diff --git a/resources/assets/stylesheets/scss/courseware.scss b/resources/assets/stylesheets/scss/courseware.scss
index b854bef5c0591446af84da8c26fa47bf6106c42e..f5caa333a450815eb1e260fe1954316584beefff 100644
--- a/resources/assets/stylesheets/scss/courseware.scss
+++ b/resources/assets/stylesheets/scss/courseware.scss
@@ -1,5831 +1,28 @@
-/* definitions */
 @use '../mixins.scss' as *;
-@import './drag-handle.scss';
-@import "courseware_gradients.scss";
 
-$companion-types: (
-    default: basic,
-    unsure: unsure,
-    special: special,
-    alert: alert,
-    sad: sad,
-    happy: happy,
-    pointing: pointing-right,
-    curious: curious
-);
-
-$element-icons: (
-    content: content2,
-    draft: category-draft,
-    task: category-task,
-    template: category-template,
-    oer: oer-campus,
-    other: category-others,
-    portfolio: category-portfolio
-);
-
-$tree-item-flag-icons: (
-    date: date,
-    write: edit,
-    cant-read: lock-locked2,
-);
-
-$tile-colors: (
-    black: #000,
-    charcoal: #3c454e,
-    royal-purple: #8656a2,
-    iguana-green: #66b570,
-    queen-blue: #536d96,
-    verdigris: #41afaa,
-    mulberry: #bf5796,
-    pumpkin: #f26e00,
-    sunglow: #ffca5c,
-    apple-green: #8bbd40,
-    studip-blue: #28497c,
-    studip-lightblue: #e7ebf1,
-    studip-red: #d60000,
-    studip-green: #008512,
-    studip-yellow: #ffbd33,
-    studip-gray: #636a71,
-);
-
-$icon-colors:(
-    icon-white: #ffffff,
-    icon-black: #000000,
-    icon-red: #cb1800,
-    icon-blue: #24437c,
-    icon-green: #00962d,
-    icon-gray: #6e6e6e,
-    icon-yellow: #ffad00
-);
-$border-colors:(
-    white: #ffffff,
-    black: #000000,
-    studip-red: #cb1800,
-    studip-blue: #24437c,
-    studip-green: #00962d,
-    studip-gray: #6e6e6e,
-    studip-yellow: #ffad00
-);
-
-$blockadder-items: (
-    before-after: block-comparison,
-    canvas: block-canvas,
-    gallery: block-gallery,
-    image-map: block-imagemap,
-    audio: audio,
-    chart: vote,
-    code: computer,
-    confirm: accept,
-    date: date,
-    dialog-cards: dialog-cards,
-    document: file-text,
-    download: download,
-    embed: code,
-    folder: folder-full,
-    headline: block-eyecatcher,
-    iframe: door-enter,
-    lti: plugin,
-    key-point: exclaim-circle,
-    link: link-extern,
-    table-of-contents: table-of-contents,
-    text: edit,
-    timeline: date-cycle,
-    typewriter: block-typewriter,
-    video: video2,
-    biography-achievements: medal,
-    biography-career: ranking,
-    biography-personal-information: own-license,
-    biography-goals: radar
-);
-
-$containeradder-items: (
-    accordion: block-accordion,
-    list: view-list,
-    tabs: block-tabs,
-);
-
-$achievement-types: (
-    certificate: file-text,
-    accreditation: vcard,
-    award: medal,
-    book: literature,
-    publication: news,
-    membership: group3,
-);
-
-$goals-types: (
-    personal: person2,
-    school: doctoral-cap,
-    academic: doctoral-cap,
-    professional: tools,
-);
-
-$media-buttons: (
-    play: play,
-    stop: stop,
-    pause: pause,
-    prev: arr_eol-left,
-    next: arr_eol-right
-);
-
-$cw-wrapper-gap: 0.5em;
-
-/* * * * * * * *
-c o n t e n t s
-* * * * * * * * */
-.cw-content-overview {
-    max-width: 1100px;
-    h2 {
-        margin: 0;
-        font-weight: 400;
-        padding: 5px 0;
-        font-size: 1.4em;
-    }
-}
-
-.cw-contents-overview-teaser {
-    max-width: 782px;
-    background-color: var(--content-color-20);
-    background-image: url("#{$image-path}/courseware-keyvisual-negative.svg");
-    background-repeat: no-repeat;
-    background-size: 196px;
-    background-position-y: 50%;
-    background-position-x: 24px;
-    padding: 24px;
-    margin-bottom: 10px;
-
-    .cw-contents-overview-teaser-content {
-        padding-left: 220px;
-
-        header{
-            font-size: 1.5em;
-            margin-bottom: 0.5em;
-        }
-    }
-}
-.responsive-display {
-    .cw-contents-overview-teaser {
-        max-width: 782px;
-        background-size: 60%;
-        background-position-y: 24px;
-        background-position-x: 50%;
-        padding: 24px;
-        margin-bottom: 10px;
-
-        .cw-contents-overview-teaser-content {
-            padding-top: 28%;
-            padding-left: 0;
-            text-align: justify;
-
-            header{
-                font-size: 1.5em;
-                margin: 1em 0 0.5em 0;
-                text-align: center;
-            }
-        }
-    }
-}
-
-.cw-loading-indicator-content {
-    margin-top: 76px;
-}
-.cw-content-loading {
-    /* Loading animation from activity feed */
-    .loading-indicator {
-        text-align: center;
-        padding: 1em 0;
-    }
-
-    .loading-indicator span {
-        background-color: var(--content-color-40);
-        border-radius: 50%;
-        height: 10px;
-        position: relative;
-        width: 10px;
-        display: inline-block;
-    }
-
-    .loading-indicator span.load-1 {
-        animation: loading-animation-1 1s linear 20;
-    }
-
-    .loading-indicator span.load-2 {
-        animation: loading-animation-2 1s linear 20;
-    }
-
-    .loading-indicator span.load-3 {
-        animation: loading-animation-3 1s linear 20;
-    }
-
-    @keyframes loading-animation-1 {
-      0%   { transform: scale(1); }
-      16%  { transform: scale(1.3); }
-      33%  { transform: scale(1); }
-      100% { transform: scale(1); }
-    }
-
-    @keyframes loading-animation-2 {
-      0%   { transform: scale(1); }
-      33%  { transform: scale(1); }
-      49%  { transform: scale(1.3); }
-      65%  { transform: scale(1); }
-      100% { transform: scale(1); }
-    }
-
-    @keyframes loading-animation-3 {
-      0%   { transform: scale(1); }
-      66%  { transform: scale(1); }
-      81%  { transform: scale(1.3); }
-      100% { transform: scale(1); }
-    }
-}
-
-.cw-content-courses {
-    h2 {
-        margin: 0;
-        font-weight: 400;
-        padding: 5px 0;
-        font-size: 1.4em;
-    }
-    ul.cw-tiles {
-        margin-bottom: 20px;
-    }
-}
-
-.cw-contents-overview-personal {
-    margin-bottom: 2em;
-}
-
-/* * * * * * * * * * *
-c o n t e n t s  e n d
-* * * * * * * * * * */
-
-/* * * * * *
-r i b b o n
-* * * * * */
-$consum_ribbon_width: calc(100% - 58px);
-#course-courseware-courseware,
-#contents-courseware-courseware,
-#contents-courseware-shared_content_courseware {
-    &.consume {
-        overflow: hidden;
-    }
-    #content-wrapper {
-        position: relative;
-    }
-}
-
-.cw-ribbon-wrapper-consume {
-    position: fixed;
-    padding: 15px;
-    background-color: var(--white);
-    width: $consum_ribbon_width;
-    height: 46px;
-    z-index: 42;
-}
-.cw-ribbon-consume-bottom {
-    position: fixed;
-    top: 75px;
-    height: 15px;
-    left: 0;
-    width: calc(100% - 1em);
-    background-color: var(--white);
-    z-index: 40;
-}
-
-.cw-ribbon-sticky-top {
-    position: fixed;
-    top: 40px;
-    height: 20px;
-    width: calc(100% - 314px);
-    background-color: var(--white);
-    z-index: 39;
-}
-.cw-ribbon-sticky-bottom {
-    position: fixed;
-    top: 110px;
-    height: 16px;
-    width: calc(100% - 314px);
-    background-color: var(--white);
-    z-index: 39;
-}
-.cw-ribbon-sticky-spacer {
-    height: 80px;
-}
-.cw-ribbon {
-    display: flex;
-    flex-wrap: wrap;
-    height: auto;
-    min-height: 30px;
-    border: solid thin var(--dark-gray-color-30);
-    margin-bottom: 15px;
-    padding: 1em;
-    justify-content: space-between;
-    background-color: var(--dark-gray-color-5);
-
-    &.cw-ribbon-sticky {
-        position: fixed;
-        top: 50px;
-        width: calc(100% - 346px);
-        z-index: 40;
-    }
-
-    &.cw-ribbon-consume {
-        width: $consum_ribbon_width;
-        position: fixed;
-        margin-bottom: 0;
-    }
-
-    .cw-ribbon-wrapper-left {
-        display: flex;
-        max-width: calc(100% - 106px);
-
-        .cw-ribbon-nav {
-            display: flex;
-            min-width: 75px;
-
-            &.single-icon {
-                min-width: 45px;
-            }
-        }
-
-        .cw-ribbon-breadcrumb {
-            font-size: 1.25em;
-            line-height: 1.5em;
-            margin-right: 1em;
-            min-width: 0;
-
-            ul {
-                display: flex;
-                list-style: none;
-                padding-left: 0;
-
-                li+li:before {
-                    padding: 0 0.25em;
-                    content: '/';
-                    background-repeat: no-repeat;
-                    background-position: center;
-                }
-
-                .cw-ribbon-breadcrumb-item {
-                    display: inline;
-                    flex-shrink: 100000;
-                    min-width: 0;
-                    overflow: hidden;
-                    text-overflow: ellipsis;
-                    white-space: nowrap;
-
-                    a {
-                        color: var(--base-color);
-                        text-decoration: none;
-                        &:hover {
-                            color: var(--active-color);
-                        }
-                    }
-
-                    img {
-                        vertical-align: text-top;
-                    }
-
-                    &.cw-ribbon-breadcrumb-item-current {
-                        flex-shrink: 1;
-                    }
-                }
-            }
-        }
-    }
-
-    .cw-ribbon-wrapper-right {
-        display: flex;
-
-        button {
-            border: none;
-            background-color: transparent;
-            cursor: pointer;
-        }
-    }
-
-    .cw-ribbon-button {
-        height: 24px;
-        width: 24px;
-        margin: 0 7px;
-        padding: 1px 2px;
-        border: none;
-        background-color: transparent;
-        background-repeat: no-repeat;
-        background-position: center;
-        background-size: 24px;
-        cursor: pointer;
-
-        &.cw-ribbon-button-menu {
-            @include background-icon(table-of-contents, clickable, 24);
-        }
-
-        &.cw-ribbon-button-prev {
-            @include background-icon(arr_1left, clickable, 24);
-            margin: 0 0.5em 0 0;
-        }
-
-        &.cw-ribbon-button-next {
-            @include background-icon(arr_1right, clickable, 24);
-            margin: 0 1em 0 0;
-        }
-
-        &.cw-ribbon-button-prev-disabled {
-            @include background-icon(arr_1left, inactive, 24);
-            margin: 0 0.5em 0 0;
-            cursor: default;
-        }
-
-        &.cw-ribbon-button-next-disabled {
-            @include background-icon(arr_1right, inactive, 24);
-            margin: 0 1em 0 0;
-            cursor: default;
-        }
-    }
-
-    .cw-ribbon-action-menu {
-        vertical-align: text-top;
-        margin: 2px 0 0 2px;
-        &.is-open {
-            z-index: 32;
-        }
-    }
-}
-
-.cw-ribbon-tools {
-    background-color: var(--white);
-    border: solid thin var(--content-color-40);
-    box-shadow: 2px 2px var(--dark-gray-color-30);
-    position: absolute;
-    right: -570px;
-    top: 15px;
-    height: 100%;
-    max-width: calc(100% - 28px);
-    display: flex;
-    flex-flow: row;
-    transition: right 0.8s;
-    z-index: 42;
-
-    &.unfold {
-        right: 0px;
-        margin-right: 15px;
-    }
-
-    &.cw-ribbon-tools-consume {
-        position: fixed;
-        &.unfold {
-            right: 15px;
-        }
-    }
-
-    &.cw-ribbon-tools-sticky {
-        position: absolute;
-        top: -1px;
-        margin-right: 0;
-    }
-
-    .cw-ribbon-tool-content {
-        height: 100%;
-        width: 540px;
-        background-color: var(--white);
-        padding: 0;
-        overflow: hidden;
-
-
-        .cw-ribbon-tool-content-nav {
-            position: sticky;
-            height: 100%;
-            top: 0;
-            background-color: var(--white);
-            margin: 0;
-            padding: 0;
-            color: var(--base-color);
-            display: flex;
-            z-index: 43;
-
-            .cw-tools-hide-button {
-                position: absolute;
-                border: none;
-                height: 36px;
-                width: 24px;
-                min-width: 24px;
-                margin-right: 1em;
-                padding: 0 4px;
-                right: 0;
-                top: 12px;
-                cursor: pointer;
-
-                @include background-icon(decline, clickable, 24);
-                background-repeat: no-repeat;
-                background-size: 24px;
-                background-position: center right;
-                background-color: var(--white);
-            }
-
-            >.cw-ribbon-tool-content-tablist {
-                width: 100%;
-                height: 100%;
-                >.cw-tabs-nav {
-                    border: none;
-                    width: calc(100% - 48px);
-
-                    >button {
-                        padding: 18px 8px 4px 8px;
-                        margin-top: 2px;
-                        max-width: unset;
-                        flex-grow: 0.5;
-                        &::after {
-                            margin-top: 16px;
-                        }
-                    }
-
-                }
-                >.cw-tabs-content {
-                    border: none;
-                    border-top: solid thin var(--content-color-40);
-                    padding: 0;
-                    height: calc(100% - 58px);
-
-                    >.cw-tab {
-                        height: calc(100% - 22px);
-                        padding: 14px 8px 8px 8px;
-                        position: relative;
-                        overflow-y: auto;
-                        overflow-x: hidden;
-                        scrollbar-width: thin;
-                        scrollbar-color: var(--base-color) var(--white);
-
-                        &.cw-ribbon-tool-blockadder-tab {
-                            height: 100%;
-                            overflow: hidden;
-                            padding: 0;
-                        }
-                    }
-                }
-            }
-        }
-
-        .cw-ribbon-tool {
-            padding: 14px 8px 6px 8px;
-            height: calc(100% - 64px);
-            overflow-y: auto;
-            overflow-x: hidden;
-            scrollbar-width: thin;
-            scrollbar-color: var(--base-color) var(--white);
-        }
-    }
-}
-
-#courseware-public-index {
-    .cw-ribbon-tools {
-        top: 127px;
-
-        &.cw-ribbon-tools-consume {
-            top: 14px;
-        }
-
-        &.cw-ribbon-tools-sticky {
-            top: 56px;
-        }
-    }
-}
-
-.cw-structural-element-consumemode {
-    .cw-ribbon-tools {
-        top: 25px;
-    }
-}
-
-.responsive-display {
-    .cw-ribbon-sticky-top,
-    .cw-ribbon-sticky-bottom,
-    .cw-ribbon-wrapper-consume,
-    .cw-ribbon-consume-bottom {
-        width: 100%;
-    }
-    .cw-ribbon {
-        &.cw-ribbon-sticky {
-            width: calc(100% - 62px);
-        }
-    }
-    .cw-ribbon-sticky-spacer {
-        height: 75px;
-    }
-}
-
-/* * * * * *
-ribbon end
-* * * * * */
-
-
-/* * * * * * * * *
- structual element
-* * * * * * * * * */
-
-.cw-structural-element {
-
-    &.cw-structural-element-consumemode {
-        position: fixed;
-        top: 0;
-        left: 0;
-        height: 100%;
-        width: 100%;
-        padding: 0;
-        background-color: var(--white);
-        z-index: 1004;
-        overflow-y: scroll;
-        overflow-x: hidden;
-        scrollbar-width: thin;
-        scrollbar-color: var(--base-color) var(--dark-gray-color-5);
-    }
-
-    .cw-welcome-screen {
-        .cw-welcome-screen-keyvisual {
-            margin: 14px 0 42px 0;
-            width: 100%;
-            height: 400px;
-            background-image: url('#{$image-path}/courseware-keyvisual.svg');
-            background-repeat: no-repeat;
-            background-position: center center;
-        }
-        header {
-            padding: 0.5em 0;
-            text-align: center;
-            font-size: 2.25em;
-        }
-        .cw-welcome-screen-actions {
-            display: flex;
-            flex-wrap: wrap;
-            justify-content: center;
-        }
-
-    }
-
-    .cw-structural-element-discussion {
-        max-width: 1606px;
-        width: 100%;
-        margin-bottom: 1em;
-    }
-
-    .cw-container-wrapper {
-        max-width: $max-content-width;
-        margin: 0;
-        padding: 0;
-        display: flex;
-        flex-wrap: wrap;
-        align-items: stretch;
-        justify-content: space-between;
-
-        &.cw-container-wrapper-consume {
-            margin: 0 auto;
-            padding: 91px 15px 15px 15px;
-        }
-
-        &.cw-container-wrapper-discuss {
-            max-width: 1606px;
-        }
-    }
-
-    .cw-structural-element-description {
-        width: 400px;
-        height: 200px;
-        overflow-y: auto;
-        resize: none;
-    }
-    .cw-structural-element-color {
-        color: var(--white);
-        &.black {
-            background-color: map-get($tile-colors, "black");
-        }
-        &.charcoal {
-            background-color: map-get($tile-colors, "charcoal");
-        }
-        &.royal-purple {
-            background-color: map-get($tile-colors, "royal-purple");
-        }
-        &.iguana-green {
-            background-color: map-get($tile-colors, "iguana-green");
-        }
-        &.queen-blue {
-            background-color: map-get($tile-colors, "queen-blue");
-        }
-        &.verdigris {
-            background-color: map-get($tile-colors, "verdigris");
-        }
-        &.mulberry {
-            background-color: map-get($tile-colors, "mulberry");
-        }
-        &.pumpkin {
-            background-color: map-get($tile-colors, "pumpkin");
-        }
-        &.sunglow {
-            background-color: map-get($tile-colors, "sunglow");
-        }
-        &.apple-green {
-            background-color: map-get($tile-colors, "apple-green");
-        }
-
-        &.studip-blue {
-            background-color: map-get($tile-colors, "studip-blue");
-        }
-        &.studip-lightblue {
-            background-color: map-get($tile-colors, "studip-lightblue");
-        }
-        &.studip-red {
-            background-color: map-get($tile-colors, "studip-red");
-        }
-        &.studip-green {
-            background-color: map-get($tile-colors, "studip-green");
-        }
-        &.studip-yellow {
-            background-color: map-get($tile-colors, "studip-yellow");
-        }
-        &.studip-gray {
-            background-color: map-get($tile-colors, "studip-gray");
-        }
-    }
-
-    .cw-structural-element-info {
-        width: 600px;
-        tr:first-child {
-            width: 12em;
-            vertical-align: top;
-        }
-    }
-}
-
-.cw-structural-element-dialog {
-    input[type=text] {
-        width: 20em;
-    }
-}
-
-.cw-structural-element-image-preview {
-    display: block;
-    max-height: 200px;
-    max-width: 400px;
-    width: auto;
-    height: auto;
-    margin: 0 auto;
-    padding-bottom: 1em;
-}
-
-.cw-structural-element-image-preview-placeholder {
-    width: 356px;
-    height: 200px;
-    margin: 0 auto;
-    background-color: var(--content-color-20);
-    background-size: 100% auto;
-    background-repeat: no-repeat;
-    background-position: center;
-    @include background-icon(courseware, clickable, 128);
-    margin-bottom: 1em;
-}
-
-.cw-element-permissions {
-    label {
-        display: block;
-        padding: 6px 0;
-    }
-    table.default {
-        > caption {
-            padding: 0;
-            font-size: 1.25em;
-        }
-        td.perm {
-            input.right, input.date {
-                cursor: pointer !important;
-            }
-        }
-    }
-    button.cw-add-persons {
-        margin-left: 4px;
-    }
-    button.cw-permission-delete {
-        width: 24px;
-        height: 24px;
-        border: none;
-        background-color: transparent;
-        @include background-icon(trash, clickable);
-        background-repeat: no-repeat;
-        cursor: pointer;
-    }
-}
-
-.cw-element-export {
-    label {
-        input {
-            vertical-align: middle;
-        }
-
-        span {
-            vertical-align: middle;
-        }
-    }
-}
-
-
-
-/* * * * * * * * * * * *
- structual element end
-* * * * * * * * * * * */
-
-/* * * * *
- container
-* * * * */
-.cw-container {
-    margin-bottom: 1em;
-
-    &.cw-container-colspan-full {
-        max-width: $max-content-width;
-        width: 100%;
-    }
-    &.cw-container-colspan-half {
-        max-width: 540px;
-        width: 100%;
-    }
-    &.cw-container-colspan-half-center {
-        width: $max-content-width;
-        .cw-container-content {
-            max-width: 540px;
-            margin: auto;
-        }
-    }
-
-    .cw-container-header {
-        background-color: var(--content-color-20);
-        padding: 4px 10px 4px 22px;
-
-        .cw-container-header-toggle {
-            display: inline-block;
-            width: calc(100% - 40px);
-        }
-
-        span {
-            color: var(--base-color);
-            font-weight: 700;
-            line-height: 2em;
-            font-size: 1.1em;
-
-            &.cw-default-container-blocker-warning {
-                font-weight: 400;
-            }
-        }
-
-        img {
-            vertical-align: text-bottom;
-        }
-
-        .cw-container-actions {
-            position: relative;
-            float: right;
-            margin-top: 4px;
-            // z-index: 31;
-            .is-open {
-                z-index: 31;
-            }
-        }
-    }
-
-    &.cw-container-active {
-        &.cw-container-colspan-half-center {
-            .cw-container-content {
-                max-width: unset;
-                .cw-block-wrapper {
-                    max-width: 540px;
-                    margin: auto;
-                }
-            }
-        }
-        .cw-container-content {
-            border: solid thin var(--content-color-40);
-        }
-    }
-
-
-    .cw-block-wrapper {
-        padding: 0;
-        margin: 0;
-        list-style: none;
-
-        &.cw-block-wrapper-active {
-            padding: 14px 10px;
-        }
-
-        .cw-block-item {
-            padding: 0;
-            margin: 0 0 1em 0;
-        }
-    }
-
-    .cw-container-list-block-list {
-        padding: 0;
-        list-style: none;
-    }
-
-    .cw-container-tabs-block-list {
-        list-style: none;
-        padding: 1em 1em 0 1em;
-    }
-
-    .cw-container-accordion-block-list {
-        list-style: none;
-        padding: 0 1em;
-    }
-}
-
-.cw-container-section-delete {
-    img {
-        cursor: pointer;
-    }
-}
-
-form.cw-container-dialog-edit-form {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 8px;
-
-    fieldset {
-        max-width: 200px;
-    }
-}
-
-.cw-container-wrapper-discuss {
-    flex-direction: column;
-
-    .cw-container-colspan-full {
-        max-width: unset;
-    }
-    .cw-container-colspan-half-center,
-    .cw-container-colspan-half {
-        max-width: 1050px;
-    }
-    .cw-container-colspan-half-center {
-        width: 100%;
-        .cw-container-content {
-            width: 1050px;
-        }
-    }
-}
-
-/* * * * * * *
- container end
-* * * * * * */
-
-/* * *
- block
-* * */
-.cw-default-block {
-    display: flex;
-    flex-flow: row;
-    .cw-default-block-invisible-info {
-        img {
-            vertical-align: text-bottom;
-        }
-    }
-
-}
-.cw-content-wrapper {
-    display: flex;
-    flex-flow: column;
-    width: 100%;
-    .cw-block-content {
-        overflow: auto;
-        position: relative;
-    }
-}
-.cw-content-wrapper-active {
-    border: solid thin var(--content-color-40);
-    .cw-block-content {
-        padding: $cw-wrapper-gap;
-    }
-}
-.cw-container-wrapper-discuss {
-    .cw-container-colspan-full {
-        .cw-content-wrapper {
-            max-width: $max-content-width;
-        }
-    }
-    .cw-container-colspan-half,
-    .cw-container-colspan-half-center {
-        .cw-content-wrapper {
-            max-width: 540px;
-        }
-    }
-}
-.cw-block-header {
-    background-color: var(--content-color-20);
-    padding: 4px 10px 4px 22px;
-
-    .cw-block-header-toggle {
-        display: inline-block;
-        width: calc(100% - 50px);
-    }
-
-    span {
-        color: var(--base-color);
-        font-weight: 700;
-        line-height: 2em;
-        font-size: 1.1em;
-
-        &.cw-default-block-invisible-info,
-        &.cw-default-block-blocker-warning {
-            font-weight: 400;
-        }
-    }
-
-    img {
-        vertical-align: text-bottom;
-    }
-
-    .cw-block-actions {
-        position: relative;
-        float: right;
-        margin-top: 4px;
-        .is-open{
-            z-index: 30;
-        }
-    }
-}
-
-.cw-discuss-wrapper,
-.cw-block-features {
-
-    header{
-        background-color: var(--content-color-20);
-        color: var(--base-color);
-        font-weight: 600;
-        padding: 0.5em;
-    }
-
-    .cw-block-features-content{
-        margin: 1em;
-    }
-}
-
-.cw-discuss-wrapper {
-    flex-shrink: 3;
-    flex-grow: 2;
-    margin-left: 10px;
-}
-
-.cw-draggable-shapes-wrapper {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    width: 100%;
-    height: 100%;
-    margin: $cw-wrapper-gap;
-
-    .cw-draggable-area {
-        width: 100%;
-        height: 100%;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        text-align: center;
-        &:hover {
-            cursor: grab;
-        }
-    }
-}
-
-@media only screen and (max-width: 1820px) {
-    .cw-structural-element .cw-container-wrapper.cw-container-wrapper-discuss {
-        max-width: $max-content-width;
-        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-full {
-            .cw-default-block {
-                flex-flow: column;
-                .cw-discuss-wrapper {
-                    margin-left: 0;
-                    margin-top: 8px;
-                }
-            }
-        }
-    }
-}
-
-@media only screen and (max-width: 1200px) {
-    .cw-structural-element .cw-container-wrapper.cw-container-wrapper-discuss {
-        max-width: $max-content-width;
-        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-half,
-        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-half-center {
-            .cw-default-block {
-                flex-flow: column;
-                .cw-discuss-wrapper {
-                    margin-left: 0;
-                    margin-top: 8px;
-                    max-width: 540px;
-                }
-            }
-        }
-    }
-}
-
-.cw-button-feature-close {
-    float: right;
-    border: none;
-    height: 24px;
-    width: 24px;
-    @include background-icon(decline, clickable);
-    background-repeat: no-repeat;
-    background-color: transparent;
-    cursor: pointer;
-}
-
-.cw-keypoint-content {
-    display: flex;
-    min-height: 52px;
-    padding:1.5em 2.5em 1.5em 2.5em;
-    border-style: solid;
-    border-width: 2px;
-    align-items: center;
-}
-.cw-keypoint-content > img {
-    flex-shrink: 0;
-}
-.cw-keypoint-red {
-    border-color: map-get($icon-colors, 'icon-red');
-}
-.cw-keypoint-blue {
-    border-color: map-get($icon-colors, 'icon-blue');
-}
-.cw-keypoint-green {
-    border-color: map-get($icon-colors, 'icon-green');
-}
-.cw-keypoint-gray {
-    border-color: map-get($icon-colors, 'icon-gray');
-}
-.cw-keypoint-yellow {
-    border-color: map-get($icon-colors, 'icon-yellow');
-}
-.cw-keypoint-sentence {
-    display: inline;
-    font-size: 1.25em;
-    padding-left: 1.5em;
-    margin-top: 10px;
-}
-.cw-keypoint-label-color {
-    width: 32px !important;
-    min-width: 32px !important;
-    height: 32px;
-    padding: 5px !important;
-
-    > .cw-keypoint-input-color {
-        visibility: hidden;
-        position: absolute;
-    }
-
-    > .cw-keypoint-input-color + div {
-        cursor: pointer;
-        border: 2px solid transparent;
-        height: 32px;
-        width: 32px;
-    }
-
-    > .cw-keypoint-input-color:checked + div { /* (RADIO CHECKED) IMAGE STYLES */
-        @include background-icon(accept, info_alt, 24);
-        background-repeat: no-repeat;
-        background-position: center;
-    }
-}
-label[for="cw-keypoint-color"] {
-    vertical-align: top;
-}
-.cw-keypoint-label-color {
-    display: inline-block !important;
-}
-.cw-keypoint-icons {
-    background-color: var(--white);
-}
-.cw-keypoint-bg-red {
-    background-color: map-get($icon-colors, 'icon-red');
-}
-.cw-keypoint-bg-blue {
-    background-color: map-get($icon-colors, 'icon-blue');
-}
-.cw-keypoint-bg-green {
-    background-color: map-get($icon-colors, 'icon-green');
-}
-.cw-keypoint-bg-gray {
-    background-color: map-get($icon-colors, 'icon-gray');
-}
-.cw-keypoint-bg-yellow {
-    background-color: map-get($icon-colors, 'icon-yellow');;
-}
-
-
-.cw-static-content-iframe {
-    width: 100%;
-}
-.cw-static-content-preview {
-    span {
-        display: block;
-    }
-    img {
-        width: 50%;
-    }
-}
-
-.cw-block-edit textarea {
-    width: -moz-available;
-    height: -moz-available;
-    min-height: 8em;
-    border: solid thin var(--content-color-40);
-    resize: none;
-}
-
-.cw-typewriter-content {
-
-    .vue-typer {
-
-        &.font-typewriter{
-            font-family: "Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace;
-        }
-        &.font-trebuchet {
-            font-family: "Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif;
-        }
-        &.font-tahoma {
-            font-family: Tahoma, Verdana, Segoe, sans-serif;
-        }
-        &.font-georgia {
-            font-family: Georgia, Times, "Times New Roman", serif;
-        }
-        &.font-narrow {
-            font-family: "Arial Narrow", Arial, "Helvetica Condensed", Helvetica, sans-serif;
-        }
-
-        &.size-tall {
-            font-size: 1.25em;
-            line-height: 1.25em;
-        }
-        &.size-grande {
-            font-size: 1.5em;
-            line-height: 1.25em;
-        }
-        &.size-huge {
-            font-size: 2em;
-            line-height: 1.25em;
-        }
-    }
-}
-
-.cw-block-actions {
-    padding-left: 14px;
-}
-.cw-button-box {
-    float: right;
-}
-
-/* * * * * *
- block end
-* * * * * */
-
-/* * * * * * * *
- sortable handle
- * * * * * * * */
-
-.cw-sortable-handle {
-    @extend .drag-handle;
-    display: inline-block;
-    height: 24px;
-    &.cw-sortable-handle-dragging {
-        cursor: grabbing;
-    }
-}
-
-.cw-block-item-sortable {
-    .cw-sortable-handle {
-        position: relative;
-        left: 4px;
-    }
-    .cw-block {
-        margin-top: -38px;
-    }
-}
-
-.cw-container-item-sortable {
-    .cw-sortable-handle {
-        position: relative;
-        left: 4px;
-    }
-    .cw-container {
-        margin-top: -38px;
-    }
-}
-
-.cw-collapsible-open {
-    .cw-container-list-sort-mode {
-        margin-top: 8px;
-    }
-}
-
-.container-ghost,
-.block-ghost {
-    opacity: 0.6;
-}
-
-
-.cw-container-wrapper-edit {
-    .cw-structural-element-list {
-        width: 100%;
-        padding: 0;
-        margin-top: 8px;
-        list-style: none;
-    }
-}
-
-.cw-block-item-selected {
-    .cw-block-header {
-        font-style: italic;
-    }
-}
-.cw-container-item-selected {
-    .cw-container-header {
-        font-style: italic;
-    }
-}
-
-/* * * * * * * * * * *
- sortable handle end
- * * * * * * * * * * */
-
-/* * * * *
- t r e e
- * * * * */
-
-.cw-tree {
-    ol {
-        list-style: none;
-        padding-left: 1.25em;
-        margin-bottom: 20px;
-
-        &.cw-tree-root-list {
-            padding-left: 0;
-            > li.cw-tree-item {
-                > .cw-tree-item-wrapper {
-                    border-bottom: solid thin var(--content-color-40);
-                    display: block;
-                    > a.cw-tree-item-link {
-                        display: block;
-                        font-size: 18px;
-                        padding-left: 26px;
-                        @include background-icon(courseware, clickable, 18);
-                        background-repeat: no-repeat;
-                        background-position: 3px 3px;
-                    }
-                }
-
-                ol {
-                    padding-left: 0;
-                    > li.cw-tree-item {
-                        margin: 28px 0 0 0;
-                        > .cw-tree-item-wrapper {
-                            display: block;
-                            border-bottom: solid thin var(--content-color-40);
-                            margin-bottom: 12px;
-                            > a.cw-tree-item-link {
-                                display: inline-block;
-                                width: calc(100% - 4px);
-                                padding-left: 4px;
-                                font-size: 16px;
-                                &.cw-tree-item-link-edit {
-                                    width: calc(100% - 20px);
-                                }
-                            }
-                        }
-                        ol {
-                            padding-left: 0.25em;
-                            &.cw-tree-draggable-list {
-                                padding-left: 1em;
-                            }
-                            > li.cw-tree-item {
-                                margin: 4px 0;
-                                > .cw-tree-item-wrapper {
-                                    border: none;
-                                    > a.cw-tree-item-link {
-                                        display: inline-block;
-                                        border-bottom: none;
-                                        font-size: 14px;
-                                        width: calc(100% - 20px);
-                                        background-repeat: no-repeat;
-                                        padding-left: 18px;
-                                        margin-left: 4px;
-                                        margin-bottom: 0;
-
-                                        &.cw-tree-item-link-edit {
-                                            width: calc(100% - 38px);
-                                        }
-
-                                        @include background-icon(bullet-dot, clickable, 18);
-                                        &:hover {
-                                            @include background-icon(bullet-dot, attention, 18);
-                                        }
-                                        &.cw-tree-item-link-current {
-                                            @include background-icon(bullet-dot, info, 18);
-                                        }
-                                    }
-                                }
-                                ol {
-                                    padding-left: 1em;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    .cw-sortable-handle {
-        vertical-align: middle;
-    }
-    .cw-tree-item-link {
-        &:hover {
-            background-color: var(--light-gray-color-20);
-            color: var(--active-color);
-        }
-        &.cw-tree-item-link-current {
-            color: var(--black);
-            font-weight: 600;
-            cursor: default;
-            &::before {
-                color: var(--black);
-            }
-        }
-        &.cw-tree-item-link-selected {
-            font-style: italic;
-            font-weight: 600;
-        }
-
-
-        @each $type, $icon in $tree-item-flag-icons {
-            .cw-tree-item-flag-#{$type} {
-                display: inline-block;
-                width: 16px;
-                height: 16px;
-                vertical-align: top;
-                @include background-icon(#{$icon}, clickable, 16);
-            }
-            &:hover .cw-tree-item-flag-#{$type} {
-                @include background-icon(#{$icon}, attention, 16);
-            }
-            &.cw-tree-item-link-current .cw-tree-item-flag-#{$type} {
-                @include background-icon(#{$icon}, info, 16);
-            }
-        }
-    }
-    .cw-tree-item-sequential {
-        display: inline-block;
-        position: absolute;
-        right: 8px;
-
-        &.cw-tree-item-sequential-complete {
-            width: 16px;
-            height: 16px;
-            vertical-align: top;
-            @include background-icon(accept, info, 16);
-        }
-        &.cw-tree-item-sequential-percentage {
-            color: var(--black);
-            font-size: 14px;
-        }
-    }
-
-    .cw-tree-item-ghost {
-        opacity: 0.6;
-    }
-}
-
-/* * * * * * *
-t r e e  e n d
-* * * * * * * */
-
-/* * * * * * * * * * * * * * *
-c o l l a p s i b l e   b o x
-* * * * * * * * * * * * * * */
-.cw-collapsible {
-
-    border: solid thin var(--content-color-40);
-    margin-bottom: -1px;
-
-    .cw-collapsible-title {
-        @include background-icon(arr_1right, clickable);
-        background-position: 6px center;
-        background-repeat: no-repeat;
-        background-color: var(--content-color-20);
-        padding: 0.5em 2em;
-        margin: 0;
-        font-weight: 600;
-        color: var(--base-color);
-        cursor: pointer;
-
-        &.cw-collapsible-open {
-            @include background-icon(arr_1down, clickable);
-        }
-
-        img {
-            vertical-align: top;
-        }
-    }
-
-    .cw-collapsible-content {
-        display: none;
-        &.cw-collapsible-content-open {
-            display: block;
-            padding: 10px;
-        }
-    }
-}
-
-form .cw-collapsible .cw-collapsible-content.cw-collapsible-content-open {
-    padding: unset;
-    label {
-        margin: 1.5ex;
-    }
-}
-
-/* * * * * * * * * * * * * * * * * *
-c o l l a p s i b l e  b o x  e n d
-* * * * * * * * * * * * * * * * * */
-
-/* * * *
-t a b s
-* * * */
-$icons: (
-    accept,
-    add,
-    add-circle,
-    admin,
-    aladdin,
-    arr_1down,
-    arr_1left,
-    arr_1right,
-    arr_1up,
-    arr_2down,
-    arr_2left,
-    arr_2right,
-    arr_2up,
-    audio,
-    audio3,
-    billboard,
-    block-canvas,
-    block-comparison,
-    block-eyecatcher,
-    block-gallery,
-    block-gallery2,
-    block-imagemap,
-    brainstorm,
-    campusnavi,
-    chat2,
-    code,
-    community2,
-    computer,
-    consultation,
-    content,
-    courseware,
-    crown,
-    date-single,
-    decline,
-    decline-circle,
-    doctoral_cap,
-    download,
-    dropbox,
-    edit,
-    exclaim,
-    exclaim-circle,
-    export,
-    favorite,
-    filter,
-    globe,
-    graph,
-    group2,
-    group3,
-    group4,
-    home2,
-    info,
-    info-circle,
-    install,
-    institute,
-    key,
-    knife,
-    learnmodule,
-    lightbulb,
-    lightbulb2,
-    link2,
-    link3,
-    link-extern,
-    link-intern,
-    literature,
-    lock-locked,
-    lock-unlocked,
-    mail2,
-    medal,
-    metro,
-    microphone,
-    module,
-    network,
-    notification,
-    notification2,
-    opencast,
-    outer-space,
-    permalink,
-    person,
-    phone,
-    picture,
-    place,
-    plugin,
-    question,
-    question-circle,
-    ranking,
-    remove,
-    remove-circle,
-    resources,
-    roles,
-    schedule2,
-    search,
-    settings,
-    span-empty,
-    span-1quarter,
-    span-2quarter,
-    span-3quarter,
-    span-full,
-    spiral,
-    sport,
-    staple,
-    star,
-    star-empty,
-    star-halffull,
-    test,
-    tools,
-    topic,
-    ufo,
-    video2,
-    visibility-visible,
-    wizard
-);
-
-.cw-tabs-nav {
-    display: flex;
-    flex-wrap: wrap;
-    list-style: none;
-    padding: 0;
-    margin: 0;
-    border: solid thin var(--content-color-40);
-    border-bottom: none;
-
-    button {
-        background-color: var(--white);
-        border: none;
-        padding: 1em 0 4px 0;
-        margin: 0 7px 0 21px;
-        color: var(--base-color);
-        cursor: pointer;
-        text-align: center;
-        flex-grow: 1;
-        max-width: max-content;
-
-        &::after {
-            display: block;
-            margin-top: 4px;
-            margin-bottom: -5px;
-            margin-left: -14px;
-            width: calc(100% + 28px);
-            content: '';
-            border-bottom: solid 3px var(--dark-gray-color-75);
-            transform: scaleX(0);
-            transition: transform var(--transition-duration) ease-in-out;
-        }
-
-        &.is-active,
-        &:hover {
-            color: var(--black);
-            &:after {
-                transform: scaleX(1);
-            }
-        }
-
-        @each $icon in $icons {
-            &.cw-tabs-nav-icon-text-#{$icon} {
-                &::before {
-                    @include background-icon($icon);
-                    background-repeat: no-repeat;
-                    background-position: left bottom;
-
-                    display: inline-block;
-                    height: 16px;
-                    width: 16px;
-                    margin-bottom: -2px;
-                    padding-left: 4px;
-                    content: '';
-                }
-
-            }
-            &.is-active.cw-tabs-nav-icon-text-#{$icon},
-            &.cw-tabs-nav-icon-text-#{$icon}:hover {
-                &::before {
-                    @include background-icon($icon, info);
-                }
-            }
-        };
-        @each $icon in $icons {
-            &.cw-tabs-nav-icon-solo-#{$icon} {
-                &::before {
-                    display: inline-block;
-                    height: 24px;
-                    width: 24px;
-                    content: '';
-
-                    @include background-icon($icon, clickable, 24);
-                    background-repeat: no-repeat;
-                    background-position: center;
-                }
-            }
-            &.is-active.cw-tabs-nav-icon-solo-#{$icon},
-            &.cw-tabs-nav-icon-solo-#{$icon}:hover {
-                &::before {
-                    @include background-icon($icon, info);
-                }
-            }
-        };
-
-    }
-
-    &:hover li {
-        &.is-active::after {
-            transform: scaleX(0);
-        }
-        &:hover::after {
-            transform: scaleX(1);
-        }
-    }
-}
-.cw-tabs-content {
-    border: solid thin var(--content-color-40);
-    padding: 4px;
-}
-.cw-block-wrapper-active {
-    .cw-tabs-content {
-        padding: 14px 0;
-    }
-}
-
-.studip-dialog-with-tab {
-    .studip-dialog-body .studip-dialog-content {
-        padding: 0 4px;
-        .cw-tab-in-dialog {
-            .cw-tabs-nav {
-                border: none;
-                border-bottom: solid thin var(--content-color-40);
-                margin-bottom: 4px;
-            }
-            .cw-tabs-content {
-                border: none;
-                min-width: 500px;
-                min-height: 400px;
-                overflow-y: auto;
-                scrollbar-width: thin;
-                scrollbar-color: var(--base-color) var(--dark-gray-color-5);
-            }
-        }
-    }
-}
-
-.cw-tabs {
-    .cw-tab {
-        display: none;
-        height: 0;
-
-        &.cw-tab-active {
-            display: block;
-            height: unset;
-            padding: 4px 8px;
-        }
-    }
-    &.cw-course-manager-tabs {
-        .cw-tab {
-            display: none;
-
-            &.cw-tab-active {
-                display: block;
-            }
-        }
-    }
-}
-
-/* * * * * * * *
-t a b s  e n d
-* * * * * * * */
-
-/* * * * * * * * * *
-b l o c k a d d e r
-* * * * * * * * * */
-
-.cw-tools-element-adder-tabs {
-    .cw-tabs-nav {
-        margin-top: 4px;
-        border: none;
-        border-bottom: solid thin var(--content-color-40);
-
-        button {
-            max-width: unset;
-            padding: 1em 1.5em 4px 1.5em;
-            margin: 0px 2em;
-        }
-    }
-    .cw-tabs-content {
-        border: none;
-        overflow-x: hidden;
-        overflow-y: auto;
-        scrollbar-width: thin;
-        scrollbar-color: var(--base-color) var(--dark-gray-color-5);
-
-        .input-group.files-search {
-            &.search {
-                border: thin solid var(--dark-gray-color-30);
-                margin-bottom: 0px;
-                input {
-                    border: none;
-                }
-            }
-
-            .input-group-append {
-                .button {
-                    border: none;
-                    border-left: thin solid var(--dark-gray-color-30);
-                    &.active {
-                        background-color: var(--base-color);
-                    }
-                }
-                .reset-search {
-                    border: none;
-                    background-color: var(--white);
-                }
-            }
-
-            .active-filter {
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                border: solid thin var(--black);
-                background-color: var(--content-color-10);
-                margin: 3px;
-                padding: 2px 3px;
-
-                .removefilter {
-                    border: none;
-                    background-color: transparent;
-                }
-            }
-        }
-
-        .cw-block-search {
-            width: inherit;
-        }
-
-        .filterpanel {
-            margin-bottom: 5px;
-            padding: 2px;
-            border: thin solid var(--dark-gray-color-30);
-            border-top: none;
-            background-color: var(--white);
-
-            .button {
-                min-width: inherit;
-                margin: 4px 2px;
-
-                &.button-active {
-                    background-color: var(--base-color);
-                    color: var(--white);
-                }
-            }
-        }
-    }
-
-    .cw-collapsible {
-        .cw-collapsible-content {
-            display: none;
-            &.cw-collapsible-content-open {
-                display: block;
-            }
-        }
-    }
-}
-
-.cw-element-adder-wrapper {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-}
-.cw-blockadder-item-list {
-    display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
-    grid-auto-rows: auto;
-    grid-gap: 4px;
-
-    .cw-blockadder-item-wrapper {
-        display: flex;
-        border: solid thin var(--content-color-40);
-        max-width: 254px;
-
-        &:hover {
-            border-color: var(--base-color);
-        }
-        .cw-blockadder-item {
-            padding: 64px 10px 4px 10px;
-            @include background-icon(unit-test, clickable, 48);
-            background-position: 10px 10px;
-            background-repeat: no-repeat;
-            cursor: pointer;
-
-            @each $item, $icon in $blockadder-items {
-                &.cw-blockadder-item-#{$item} {
-                    @include background-icon($icon, clickable, 48);
-                }
-            }
-            .cw-clipboard-item-title,
-            .cw-blockadder-item-title {
-                display: inline-block;
-                font-weight: 600;
-                margin-bottom: 2px;
-            }
-            .cw-blockadder-item-description {
-                display: inline-block;
-                margin: 0 0 4px;
-            }
-        }
-        .cw-blockadder-item-fav {
-            height: 32px;
-            padding: 8px;
-            background-color: transparent;
-            border: none;
-            cursor: pointer;
-        }
-    }
-}
-
-.cw-block-adder-area {
-    background-color: var(--white);
-    border: solid thin var(--content-color-40);
-    padding: 1em 0;
-    color: var(--base-color);
-    text-align: center;
-    width: 100%;
-    font-weight: 600;
-    cursor: pointer;
-
-    &:hover {
-        border-color: var(--base-color);
-    }
-
-    &.cw-block-adder-active {
-        border: solid thin var(--base-color);
-        background-color: var(--base-color);
-        color: var(--white);
-    }
-
-    img {
-        vertical-align: text-bottom;
-    }
-}
-.cw-block-helper-buttons {
-    display: inline-block;
-    width: 100%;
-
-    .cw-block-helper-reset {
-        float: right;
-    }
-
-    .button.cw-block-helper-reset::before {
-        content: '';
-        @include background-icon(refresh);
-        background-repeat: no-repeat;
-        float: left;
-        height: 16px;
-        width: 16px;
-        margin: 1px 5px 0 -8px;
-    }
-}
-
-.cw-block-helper-results {
-    margin-top: 5px;
-}
-
-.cw-containeradder-item {
-    margin-bottom: 4px;
-    padding: 1em 1em 1em 6em;
-    @include background-icon(unit-test, clickable, 48);
-    background-position: 12px center;
-    background-repeat: no-repeat;
-    border: solid thin var(--content-color-40);
-    cursor: pointer;
-
-    &:hover {
-        border-color: var(--base-color);
-    }
-
-    @each $item, $icon in $containeradder-items {
-        &.cw-containeradder-item-#{$item} {
-            @include background-icon($icon, clickable, 48);
-        }
-    }
-
-    .cw-containeradder-item-title {
-        font-weight: 600;
-    }
-}
-
-.cw-container-style-selector {
-    display: flex;
-    margin-bottom: 8px;
-
-    label {
-        border: solid thin var(--content-color-40);
-        padding: calc(0.5em + 32px) 1em 0.5em 1em;
-        color: var(--base-color);
-        text-align: center;
-        width: 33%;
-        background-position: center 0.5em;
-        background-repeat: no-repeat;
-        cursor: pointer;
-
-        &.full {
-            @include background-icon(column-full, clickable, 32);
-        }
-        &.half {
-            @include background-icon(column-half, clickable, 32);
-        }
-        &.half-center {
-            @include background-icon(column-half-centered, clickable, 32);
-        }
-        &:hover {
-            color: var(--active-color);
-        }
-        &:not(:first-child) {
-            border-left: solid thin transparent;
-        }
-        &.cw-container-style-selector-active {
-            background-color: var(--content-color-20);
-            border: solid thin var(--base-color);
-        }
-
-    }
-    input[type=radio] {
-        position: absolute;
-        opacity: 0;
-        width: 0;
-
-        &:focus + label {
-            outline-color: Highlight;
-            outline-color: -webkit-focus-ring-color;
-            outline-style: auto;
-            outline-width: 1px;
-        }
-    }
-}
-.cw-element-inserter-wrapper {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-}
-
-
-.cw-clipboard-item-wrapper {
-    display: flex;
-    width: calc(50% - 4px);
-    border: solid thin var(--content-color-40);
-    margin-bottom: 4px;
-
-    &:hover {
-        border-color: var(--base-color);
-    }
-
-    .cw-clipboard-item {
-        width: 207px;
-        padding: 64px 10px 4px 10px;
-        @include background-icon(unit-test, clickable, 48);
-        background-position: 10px 10px;
-        background-repeat: no-repeat;
-        cursor: pointer;
-        background-color: var(--white);
-        border: none;
-        text-align: left;
-        color: var(--base-color);
-
-        @each $item, $icon in $blockadder-items {
-            &.cw-clipboard-item-#{$item} {
-                @include background-icon($icon, clickable, 48);
-            }
-        }
-        @each $item, $icon in $containeradder-items {
-            &.cw-clipboard-item-#{$item} {
-                @include background-icon($icon, clickable, 48);
-            }
-        }
-    
-        .cw-clipboard-item-title {
-            display: inline-block;
-            font-weight: 600;
-            margin-bottom: 2px;
-        }
-
-    }
-    .cw-clipboard-item-action-menu-wrapper {
-        padding: 8px;
-    }
-}
-.action-menu.is-open,
-.action-menu-wrapper.is-open {
-    &.cw-clipboard-item-action-menu {
-        z-index: 42;
-    }
-}
-
-/* * * * * * * * * * * * *
-b l o c k a d d e r  e n d
-* * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * * *
-c o m p a n i o n  o v e r l a y
-* * * * * * * * * * * * * * * * */
-
-.cw-companion-overlay {
-    position: fixed;
-    bottom: 46px;
-    right: 0;
-    width: 360px;
-    max-width: calc(100% - 140px);
-    height: 120px;
-    z-index: 42000;
-    border: solid thin var(--content-color-40);
-    background-color: var(--white);
-    background-repeat: no-repeat;
-    background-position: 1em center;
-    background-size: 100px;
-    box-shadow: 5px 5px var(--dark-gray-color-10);
-    padding-left: 120px;
-    transform: translateX(100%);
-    transition: transform .5s ease;
-
-    @each $type, $image in $companion-types {
-        &.#{$type} {
-            background-image: url("#{$image-path}/companion/Tin_#{$image}.svg");
-        }
-    }
-
-    &.cw-companion-overlay-in {
-        transform: translateX(0);
-        right: 12px;
-    }
-
-    .cw-companion-overlay-content {
-        display: inline-block;
-        position: relative;
-        top: 25%;
-        padding: 0 1em;
-    }
-
-    .cw-compantion-overlay-close {
-        @include background-icon(decline);
-        background-color: var(--white);
-        background-repeat: no-repeat;
-
-        position: absolute;
-        top: 7px;
-        right: 7px;
-        height: 16px;
-        width: 16px;
-        border: none;
-        cursor: pointer;
-    }
-}
-
-.cw-companion-box {
-    display: flex;
-    height: 120px;
-    border: solid thin var(--content-color-40);
-    background-color: var(--white);
-    background-repeat: no-repeat;
-    background-position: 1em center;
-    background-size: 100px;
-    padding-left: 120px;
-    align-items: center;
-    margin-bottom: 1em;
-
-    @each $type, $image in $companion-types {
-        &.#{$type} {
-            background-image: url("#{$image-path}/companion/Tin_#{$image}.svg");
-        }
-    }
-
-    &.cw-companion-box-in-form {
-        margin-top: 8px;
-    }
-
-    p {
-        margin: 0 1em 10px 0;
-    }
-}
-
-.cw-companion-box-wrapper {
-        width: 100%;
-        max-width: $max-content-width;
-}
-
-/* * * * * * * * * * * * * * * * * *
-c o m p a n i o n  s m a l l  e n d
-* * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * *
-v i e w  w i d g e t
-* * * * * * * * * * */
-.cw-action-widget {
-    .cw-action-widget-show-toc {
-        @include background-icon(table-of-contents, clickable);
-    }
-    .cw-action-widget-edit{
-        @include background-icon(edit, clickable);
-    }
-    .cw-action-widget-sort{
-        @include background-icon(arr_1sort, clickable);
-    }
-    .cw-action-widget-add{
-        @include background-icon(add, clickable);
-    }
-    .cw-action-widget-info{
-        @include background-icon(info, clickable);
-    }
-    .cw-action-widget-star{
-        @include background-icon(star, clickable);
-    }
-    .cw-action-widget-trash{
-        @include background-icon(trash, clickable);
-    }
-    .cw-action-widget-oer{
-        @include background-icon(oer-campus, clickable);
-    }
-    .cw-action-widget-remove-lock{
-        @include background-icon(lock-unlocked, clickable);
-    }
-}
-.cw-export-widget {
-    .cw-export-widget-export{
-        @include background-icon(export, clickable);
-    }
-    .cw-export-widget-export-pdf{
-        @include background-icon(export, clickable);
-    }
-    .cw-export-widget-oer{
-        @include background-icon(share, clickable);
-    }
-}
-.cw-import-widget {
-    .cw-import-widget-archive{
-        @include background-icon(import, clickable);
-    }
-    .cw-import-widget-copy{
-        @include background-icon(copy, clickable);
-    }
-    .cw-import-widget-import{
-        @include background-icon(import, clickable);
-    }
-    .cw-action-widget-link {
-        @include background-icon(group, clickable);
-    }
-}
-
-/* * * * * * * * * * * * * *
-v i e w  w i d g e t  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * * * * *
-c o m m e n t s  &  f e e d b a c k
-* * * * * * * * * * * * * * * * * * */
-
-.cw-structural-element-feedback,
-.cw-structural-element-comments {
-    padding: 0 1em;
-}
-
-.cw-structural-element-feedback-items,
-.cw-structural-element-comments-items,
-.cw-block-feedback-items,
-.cw-block-comments-items {
-    min-height: 1em;
-    max-height: 225px;
-    overflow-y: auto;
-    overflow-x: hidden;
-    margin: -1em -1em 0em 0em;
-    padding: 0em  1em 0em 0em;
-    scroll-behavior: smooth;
-}
-
-.studip-dialog-content {
-    .cw-structural-element-feedback-items,
-    .cw-structural-element-comments-items,
-    .cw-block-feedback-items,
-    .cw-block-comments-items {
-        max-height: unset;
-    }
-}
-
-.cw-talk-bubble {
-    margin: 10px 20px;
-    position: relative;
-    width: 85%;
-    height: auto;
-    background-color: var(--dark-gray-color-10);
-    float: left;
-
-    .cw-talk-bubble-talktext {
-        padding: 1em;
-        text-align: left;
-        line-height: 1.5em;
-
-        .cw-talk-bubble-talktext-time {
-            color: var(--dark-gray-color-80);
-            text-align: right;
-            font-size: 0.8em;
-            margin-bottom: -0.5em;
-        }
-    }
-
-    &.cw-talk-bubble-own-post {
-        float: right;
-    }
-
-    &:after{
-        content: ' ';
-        position: absolute;
-        width: 0;
-        height: 0;
-        top: 0px;
-        bottom: auto;
-        border: 22px solid;
-        border-color: var(--dark-gray-color-10) transparent transparent transparent;
-        left: -20px;
-        right: auto;
-    }
-
-    &.cw-talk-bubble-own-post:after{
-        left: auto;
-        right: -20px;
-    }
-
-    .cw-talk-bubble-user {
-        padding: 1em 1em 0 1em;
-
-        .cw-talk-bubble-avatar{
-            display: inline-block;
-        }
-
-        span {
-            padding-left: 4px;
-            color: var(--dark-gray-color-45);
-            font-weight: 600;
-            vertical-align: top;
-        }
-    }
-}
-
-.cw-structural-element-feedback-create,
-.cw-structural-element-comment-create,
-.cw-block-feedback-create,
-.cw-block-comment-create {
-    border-top: solid thin var(--content-color-40);
-    padding-top: 1em;
-    textarea {
-        width: calc(100% - 6px);
-        resize: none;
-        border: solid thin var(--content-color-40);
-        &:active {
-            border: solid thin var(--content-color-80);
-        }
-    }
-}
-.cw-structural-element-comments-empty,
-.cw-structural-element-feedback-empty,
-.cw-block-comments-empty,
-.cw-block-feedback-empty {
-    .cw-structural-element-feedback-create,
-    .cw-structural-element-comment-create,
-    .cw-block-feedback-create,
-    .cw-block-comment-create {
-        border-top: none;
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * *
-c o m m e n t s  &  f e e d b a c k  e n d
-* * * * * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * *
-w y s i w y g
-* * * * * * */
-textarea.studip-wysiwyg {
-    width: 100%
-}
-
-/* * * * * * * * * * *
-w y s i w y g  e n d
-* * * * * * * * * * */
-
-/* * * * * * * * *
-d a s h b o a r d
-* * * * * * * * */
-
-.cw-dashboard {
-    display: flex;
-    max-width: 1112px;
-    flex-wrap: wrap;
-
-    .cw-dashboard-box {
-        margin-bottom: 1em;
-        margin-right: 1em;
-
-        &.cw-dashboard-box-full {
-            max-width: $max-content-width;
-            width: calc(100% - 16px);
-        }
-        &.cw-dashboard-box-half {
-            width: calc(50% - 16px);
-        }
-
-        &.cw-collapsible .cw-collapsible-content.cw-collapsible-content-open {
-            padding: 0;
-        }
-    }
-    .cw-dashboard-overview {
-        display: flex;
-        padding: 10px;
-        flex-wrap: wrap;
-        justify-content: center;
-
-    }
-
-    &.cw-dashboard-task-view {
-        display: unset;
-        max-width: unset;
-        flex-wrap: unset;
-
-        .cw-dashboard-tasks-wrapper,
-        .cw-dashboard-students-wrapper {
-            max-height: unset;
-        }
-    }
-}
-
-#course-courseware-dashboard {
-    .action-menu-item a {
-        cursor: pointer;
-    }
-}
-
-.responsive-display {
-    .cw-dashboard {
-        .cw-dashboard-box {
-
-            &.cw-dashboard-box-full {
-                width: 100%
-            }
-            &.cw-dashboard-box-half {
-                width: 100%
-            }
-        }
-    }
-}
-
-.cw-activities-wrapper {
-    max-width: $max-content-width;
-
-    .cw-companion-box {
-        margin: 10px;
-    }
-
-    .cw-activities {
-        list-style: none;
-        padding: 0;
-
-        .cw-activity-item {
-            border-bottom: solid thin var(--content-color-40);
-            padding: 0.5em;
-
-            &:last-child {
-                border: none;
-            }
-
-            p {
-                margin: 0 0 4px 0;
-                img {
-                    padding-right: 0.5em;
-                    vertical-align: text-bottom;
-                }
-            }
-        }
-    }
-}
-
-.cw-dashboard-box {
-    .cw-dashboard-tasks-wrapper,
-    .cw-dashboard-students-wrapper {
-        padding: 10px;
-    }
-}
-
-.cw-dashboard-tasks-wrapper,
-.cw-dashboard-students-wrapper {
-
-    table.default {
-        margin: 0;
-        thead {
-            tr {
-                th {
-                    &.feedback {
-                        min-width: 11em;
-                    }
-                    &.renewal {
-                        min-width: 14em;
-                    }
-                }
-            }
-        }
-        tbody {
-            tr {
-                td {
-                    img {
-                        vertical-align: text-bottom;
-                        &.display-feedback,
-                        &.edit {
-                            cursor: pointer;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-/* * * * * * * * * * * *
-d a s h b o a r d  e n d
-* * * * * * * * * * * */
-
-/* * * * * * * * * * * *
-    p r o g r e s s
-* * * * * * * * * * * */
-.cw-unit-progress {
-    .cw-unit-progress-breadcrumb {
-        padding: 10px 0;
-        a img {
-            vertical-align: top;
-        }
-    }
-
-    .cw-unit-progress-chapter {
-        text-align: center;
-        margin-bottom: -3.5em;
-
-        h1 {
-            border: none;
-            margin: 0;
-            padding: 0;
-        }
-
-        .cw-progress-circle {
-            font-size: 18px;
-            margin: 1em auto;
-
-            &.cw-unit-progress-current {
-                font-size: 12px;
-                top: -4.5em;
-                left: -2.5em;
-            }
-        }
-    }
-
-    .cw-unit-progress-subchapter-list {
-        border-top: solid thin var(--content-color-40);
-        padding: 0 1em 0 1em;
-
-        .cw-unit-empty-info {
-            margin-top: 10px;
-        }
-    }
-}
-
-.cw-unit-progress-item {
-    display: block;
-    border-bottom: solid thin var(--content-color-40);
-    padding: 10px 0;
-
-    &:hover{
-        background-color: hsla(217,6%,45%,.2);
-    }
-
-    &:last-child {
-        border: none;
-    }
-
-    .cw-unit-progress-item-value,
-    .cw-unit-progress-item-description {
-        display: inline-block;
-        vertical-align: top;
-    }
-
-    .cw-unit-progress-item-value {
-        width: 70px;
-        color: var(--base-color);
-        font-size: xx-large;
-
-        .cw-progress-circle {
-            font-size: 12px;
-            margin: 4px;
-        }
-    }
-    .cw-unit-progress-item-description {
-        color: var(--base-color);
-        padding: 0.5em 0 0 1em;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: nowrap;
-    }
-}
-/* * * * * * * * * * * *
- p r o g r e s s  e n d
-* * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * *
-p r o g r e s s  c i r c l e
-* * * * * * * * * * * * * * */
-
-.cw-progress-circle {
-    font-size: 14px;
-    margin: 10px;
-    position: relative;
-    padding: 0;
-    width: 5em;
-    height: 5em;
-    background-color: var(--dark-gray-color-10);
-    border-radius: 50%;
-    line-height: 5em;
-
-    &:after{
-        border: none;
-        position: absolute;
-        top: 0.35em;
-        left: 0.35em;
-        text-align: center;
-        display: block;
-        border-radius: 50%;
-        width: 4.3em;
-        height: 4.3em;
-        background-color: white;
-        content: " ";
-    }
-
-    span {
-        position: absolute;
-        line-height: 5em;
-        width: 5em;
-        text-align: center;
-        display: block;
-        color: var(--base-color);
-        z-index: 2;
-    }
-
-    .left-half-clipper {
-        border-radius: 50%;
-        width: 5em;
-        height: 5em;
-        position: absolute;
-        clip: rect(0, 5em, 5em, 2.5em);
-     }
-
-     &.over50 .left-half-clipper {
-        clip: rect(auto,auto,auto,auto);
-     }
-
-    .value-bar {
-        position: absolute;
-        clip: rect(0, 2.5em, 5em, 0);
-        width: 5em;
-        height: 5em;
-        border-radius: 50%;
-        border: 0.45em solid var(--base-color);
-        box-sizing: border-box;
-    }
-
-    &.over50 .first50-bar {
-        position: absolute;
-        clip: rect(0, 5em, 5em, 2.5em);
-        background-color: var(--base-color);
-        border-radius: 50%;
-        width: 5em;
-        height: 5em;
-    }
-
-    &:not(.over50) .first50-bar {
-        display: none;
-    }
-
-    &.p0 .value-bar { display: none; }
-
-    @for $i from 1 through 100 {
-        &.p#{$i} .value-bar {
-            transform: rotate(calc(360deg * $i / 100));
-        }
-    }
-}
-
-/* * * * * * * * * * * * * * * * * *
-p r o g r e s s  c i r c l e  e n d
-* * * * * * * * * * * * * * * * * */
-
-
-
-.cw-import-zip {
-    margin-bottom: 1em;
-
-    header {
-        font-size: 1.15;
-        font-weight: 700;
-    }
-    .progress-bar-wrapper {
-        width: 100%;
-        border: solid thin var(--content-color-40);
-
-        .progress-bar {
-            display: flex;
-            flex-direction: column;
-            justify-content: center;
-            color: white;
-            text-align: center;
-            white-space: nowrap;
-            background-color: var(--base-color);
-        }
-    }
-}
-
-/* * * * * *
-b l o c k s
-* * * * * */
-
-.cw-block-title {
-    padding: 4px;
-    background-color: var(--content-color-20);
-    color: var(--base-color);
-    font-weight: 700;
-    text-align: center;
-    border: solid thin var(--content-color-40);
-    border-bottom: none;
-}
-/* * * * * * * * *
-b l o c k s  e n d
-* * * * * * * * */
-
-/* * * * * * * * * *
-a u d i o  b l o c k
-* * * * * * * * * * */
-.cw-block-audio {
-    .cw-audio-container {
-        border: solid thin var(--content-color-40);
-        padding-top: 1em;
-    }
-    .cw-audio-controls {
-        text-align: right;
-        padding: 0 0.5em;
-    }
-    .cw-audio-range {
-        margin: 0 5px 10px 0;
-        &::-moz-focus-outer {
-            border: 0;
-        }
-        &.ui-widget-content {
-            background-color: var(--base-color);
-        }
-        .ui-widget-header {
-            background-color: var(--dark-gray-color-5);
-        }
-        .ui-slider-handle {
-            border-radius: 20px;
-            width: 1em;
-            height: 1.7em;
-            top: -0.5em;
-            background-color: var(--dark-gray-color-20);
-            border-color: var(--content-color-40);
-            cursor: pointer;
-            margin-left: -2px;
-        }
-    }
-    .cw-audio-button {
-        border: solid thin var(--content-color-40);
-        background-color: var(--white);
-        background-repeat: no-repeat;
-        background-position: center center;
-        background-size: 24px;
-        min-height: 27px;
-        line-height: 130%;
-        padding: 5px 15px 5px 30px;
-        cursor: pointer;
-        font-size: 14px;
-        box-sizing: border-box;
-        text-align: center;
-        text-decoration: none;
-        vertical-align: bottom;
-        white-space: nowrap;
-        min-width: unset;
-        margin: 5px;
-        height: 46px;
-        width: 46px;
-        display: inline-block;
-
-        &:hover {
-            background-color: var(--base-color);
-        }
-
-        @each $button, $icon in $media-buttons {
-            &.cw-audio-#{$button}button {
-                @include background-icon($icon, clickable, 24);
-                &:hover {
-                    @include background-icon($icon, info-alt, 24);
-                }
-            }
-        };
-    }
-
-
-    .cw-audio-time {
-        position: relative;
-        top: -1em;
-        color: var(--base-gray);
-    }
-
-    .cw-audio-range {
-        display: block;
-        margin: 0 auto 1.5em;
-        -webkit-appearance: none;
-        position: relative;
-        overflow: hidden;
-        height: 18px;
-        width: 100%;
-        cursor: pointer;
-        border-radius: 0;
-    }
-
-    .cw-audio-range::-webkit-slider-runnable-track {
-        background: var(--dark-gray-color-20);
-    }
-
-    .cw-audio-range::-webkit-slider-thumb {
-        -webkit-appearance: none;
-        width: 9px; /* 1 */
-        height: 18px;
-        background: var(--white);
-        box-shadow: -100vw 0 0 100vw var(--base-color);
-        border: solid thin var(--content-color-40);
-    }
-
-    .cw-audio-range::-moz-range-track {
-        height: 18px;
-        background: var(--dark-gray-color-10);
-    }
-
-    .cw-audio-range::-moz-range-thumb {
-        background: var(--white);
-        height: 18px;
-        width: 9px;
-        border: solid thin var(--content-color-40);
-        border-radius: 0 !important;
-        box-shadow: -100vw 0 0 100vw var(--base-color);
-        box-sizing: border-box;
-    }
-
-    .cw-audio-range::-ms-fill-lower {
-        background: var(--base-color);
-    }
-
-    .cw-audio-range::-ms-thumb {
-        background: var(--white);
-        border: solid thin var(--content-color-40);
-        height: 18px;
-        width: 9px;
-        box-sizing: border-box;
-    }
-
-    .cw-audio-range::-ms-ticks-after {
-        display: none;
-    }
-
-    .cw-audio-range::-ms-ticks-before {
-        display: none;
-    }
-
-    .cw-audio-range::-ms-track {
-        background: var(--dark-gray-color-20);
-        color: transparent;
-        height: 18px;
-        border: none;
-    }
-
-    .cw-audio-range::-ms-tooltip {
-        display: none;
-    }
-    .cw-audio-playlist-wrapper {
-        margin-top: -1em;
-        padding-top: 1em;
-        border: solid thin var(--content-color-40);
-        border-top: none;
-
-        &.empty {
-            border: none;
-        }
-
-        .cw-audio-playlist {
-            padding-left: 0;
-            list-style: none;
-            cursor: pointer;
-
-            &.with-recorder {
-                border-bottom: solid thin var(--content-color-40);
-            }
-
-            li {
-                margin: 0 1em;
-                &:not(:last-child) {
-                    border-bottom: solid thin var(--dark-gray-color-30);
-                }
-
-                .cw-playlist-item {
-                    display: block;
-                    @include background-icon(file-audio2, clickable, 24);
-                    background-repeat: no-repeat;
-                    background-position: 1em center;
-
-                    margin: 1em 0;
-                    padding: 1em;
-                    padding-left: 4em;
-                    color: var(--base-color);
-                    &:hover {
-                        color: var(--active-color);
-                    }
-                    &.current-item {
-                        @include background-icon(play, clickable, 24);
-                        font-weight: 700;
-                        &.is-playing {
-                            @include background-icon(pause, clickable, 24);
-                        }
-                    }
-                }
-            }
-        }
-        .cw-audio-playlist-recorder {
-            padding: 1em;
-        }
-    }
-
-
-    .cw-audio-current-track {
-        @include background-icon(file-audio2, info, 96);
-        background-position: top center;
-        background-repeat: no-repeat;
-        width: 100%;
-        min-height: 140px;
-        margin: 1em 0 2em 0;
-        p {
-            text-align: center;
-            padding-top: 106px;
-        }
-    }
-    .cw-audio-empty {
-        @include background-icon(file, info, 96);
-        border: solid thin var(--content-color-40);
-        background-position: center 1em;
-        background-repeat: no-repeat;
-        min-height: 140px;
-        padding: 1em;
-        p {
-            text-align: center;
-            padding-top: 106px;
-        }
-    }
-}
-/* * * * * * * * * * * * * *
-a u d i o  b l o c k  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * * * * * * *
-f o r  m u l t i m e d i a  b l o c k s
-* * * * * * * * * * * * * * * * * * * */
-.cw-file-empty {
-    @include background-icon(file, info, 96);
-    border: solid thin var(--content-color-40);
-    background-position: center 1em;
-    background-repeat: no-repeat;
-    min-height: 140px;
-    padding: 1em;
-    p {
-        text-align: center;
-        padding-top: 106px;
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * *
-f o r  m u l t i m e d i a  b l o c k s  e n d
-* * * * * * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * *
-v i d e o  b l o c k
-* * * * * * * * * * */
-.cw-block-video {
-    video {
-        width: 100%;
-    }
-}
-/* * * * * * * * * * * * * *
-v i d e o  b l o c k  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * * * *
-b e f o r e  a f t e r  b l o c k
-* * * * * * * * * * * * * * * * */
-.cw-block-before-after {
-    .twentytwenty-container {
-        width: 100% !important;
-        z-index: 19;
-        .twentytwenty-handle {
-            z-index: 18;
-        }
-        .twentytwenty-overlay {
-            z-index: 17;
-        }
-        img {
-            width: 100%;
-            z-index: 16;
-        }
-    }
-}
-/* * * * * * * * * * * * * * * * * * * *
-b e f o r e  a f t e r  b l o c k  e n d
-* * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * *
-c o d e  b l o c k
-* * * * * * * * */
-.cw-block-code {
-    pre {
-        margin-bottom: 0;
-    }
-
-    .hljs {
-      display: block;
-      overflow-x: auto;
-      padding: 0.5em;
-      background: var(--dark-gray-color-5);
-      color: black;
-      border: solid thin var(--content-color-40);
-    }
-
-    .hljs-comment,
-    .hljs-quote,
-    .hljs-variable {
-      color: var(--dark-green);
-    }
-
-    .hljs-keyword,
-    .hljs-selector-tag,
-    .hljs-selector-class,
-    .hljs-built_in,
-    .hljs-name,
-    .hljs-tag {
-      color: var(--base-color);
-      font-weight: 600;
-    }
-
-    .hljs-string,
-    .hljs-title,
-    .hljs-section,
-    .hljs-attribute,
-    .hljs-literal,
-    .hljs-template-tag,
-    .hljs-template-variable,
-    .hljs-type,
-    .hljs-addition {
-      color: var(--orange-80);
-      font-weight: 400;
-    }
-
-    .hljs-deletion,
-    .hljs-selector-attr,
-    .hljs-selector-pseudo,
-    .hljs-meta {
-      color: var(--petrol);
-      font-weight: 400;
-    }
-
-    .hljs-doctag {
-      color: var(--dark-gray-color-75);
-      font-weight: 400;
-    }
-
-    .hljs-attr {
-      color: var(--active-color);
-      font-weight: 400;
-    }
-
-    .hljs-symbol,
-    .hljs-bullet,
-    .hljs-link {
-      color: var(--petrol);
-      font-weight: 400;
-    }
-
-    .hljs-emphasis {
-      font-style: italic;
-      font-weight: 400;
-    }
-
-    .hljs-strong {
-      font-weight: 600;
-    }
-
-    .code-lang {
-        background: var(--dark-gray-color-5);
-        border: solid thin var(--content-color-40);
-        border-top: none;
-        padding: 5px 10px;
-        text-align: right;
-        color: var(--dark-gray-color-45);
-        font-family: monospace;
-        text-transform: full-width;
-    }
-
-}
-/* * * * * * * * * * * * *
-c o d e  b l o c k  e n d
-* * * * * * * * * * * * */
-
-/* * * * * * * * * * * * *
-c o n f i r m  b l o c k
-* * * * * * * * * * * * */
-.cw-block-confirm {
-    .cw-block-confirm-content{
-        border: solid thin var(--content-color-40);
-        padding: 1em;
-        margin: 0;
-
-        input[type=checkbox] {
-            margin-right: 2em;
-            vertical-align: bottom;
-        }
-    }
-}
-/* * * * * * * * * * * * * * * *
-c o n f i r m  b l o c k  e n d
-* * * * * * * * * * * * * * * */
-
-/* * * * * * * * * *
-d a t e  b l o c k
-* * * * * * * * * */
-
-.cw-container-colspan-half,
-.cw-container-colspan-half-center {
-    .cw-block-date {
-        .cw-block-content {
-            font-size: 9px;
-        }
-    }
-}
-
-.cw-block-date {
-
-    .cw-date-countdown,
-    .cw-date-date {
-        margin: 0 auto;
-        width: max-content;
-    }
-
-    .cw-date-countdown {
-        .cw-date-countdown-digit {
-            display: inline-block;
-            margin-right: 4px;
-
-            .cw-date-countdown-number {
-                font-size: 6em;
-                line-height: 1.25em;
-                height: 1.25em;
-                padding: 3px 0.5em;
-                background: rgba(245,245,245,1);
-                font-weight: 300;
-            }
-
-            .cw-date-countdown-label-sg,
-            .cw-date-countdown-label-pl {
-                padding: 5px;
-                font-size: 1.25em;
-                text-align: left;
-                text-transform: uppercase;
-            }
-        }
-    }
-
-    .cw-date-date {
-        .cw-date-date-space {
-            display: inline-block;
-            width: 2em;
-
-        }
-
-        .cw-date-date-digits {
-            display: inline-block;
-
-            .cw-date-date-number {
-                font-size: 5em;
-                line-height: 1.25em;
-                height: 1.25em;
-                padding: 0.25em;
-                background: rgba(245,245,245,1);
-                font-weight: 300;
-            }
-        }
-    }
-}
-
-.responsive-display {
-    .cw-block-date {
-        .cw-block-content {
-            font-size: 9px;
-
-            .cw-date-countdown-number {
-                font-size: 3.5em;
-            }
-            .cw-date-countdown-label-sg,
-            .cw-date-countdown-label-pl {
-                font-size: 1em;
-            }
-            .cw-date-date-number {
-                font-size: 3em;
-            }
-        }
-    }
-}
-
-/* * * * * * * * * * * * *
-d a t e  b l o c k  e n d
-* * * * * * * * * * * * */
-
-/* * * * * * * * * * * *
-c a n v a s  b l o c k
-* * * * * * * * * * * */
-.cw-block-canvas {
-    .cw-canvasblock-canvas {
-        max-width: 100%;
-        border: solid thin var(--content-color-40);
-    }
-
-    .cw-canvasblock-upload-message{
-        display: none;
-    }
-
-    .cw-canvasblock-original-img {
-        display: none;
-    }
-
-    .cw-canvasblock-tool-selected-text {
-        cursor: text;
-    }
-
-    h1.cw-canvasblock-description {
-        border-bottom: none;
-    }
-
-    .cw-canvasblock-toolbar {
-        border: solid thin var(--content-color-40);
-        border-bottom: none;
-
-        .cw-canvasblock-buttonset {
-            display: inline-block;
-            padding: 5px;
-            margin-right: 0.5em;
-    
-            button {
-                cursor: pointer;
-                user-select: none;
-                border: solid thin var(--content-color-40);
-                height: 32px;
-                width: 32px;
-                background-color: var(--white);
-                background-position: center;
-                background-repeat: no-repeat;
-                background-size: 24px 24px;
-        
-                &.cw-canvasblock-color {
-                    $colors: (
-                        white: #ffffff,
-                        blue: #3498db,
-                        green: #2ecc71,
-                        purple: #9b59b6,
-                        red: #e74c3c,
-                        yellow: #fed330,
-                        orange: #f39c12,
-                        grey: #95a5a6,
-                        darkgrey: #34495e,
-                        black: #000000,
-                    );
-        
-                    @each $name, $color in $colors {
-                        &.#{"" + $name} {
-                            background-color: $color;
-                        }
-                    }
-        
-                    &.selected-color {
-                        border: solid 2px var(--black);
-                    }
-                }
-        
-                &.cw-canvasblock-reset {
-                    @include background-icon(refresh, clickable, 24);
-                }
-        
-                &.cw-canvasblock-size {
-                    @include background-icon(stop, clickable);
-        
-                    &.cw-canvasblock-size-small {
-                        background-size: 8px 7px;
-                    }
-                    &.cw-canvasblock-size-normal {
-                        background-size: 16px 14px;
-                    }
-                    &.cw-canvasblock-size-large {
-                        background-size: 22px 20px;
-                    }
-                    &.cw-canvasblock-size-huge {
-                        background-size: 26px 24px;
-                    }
-                    &.selected-size {
-                        border: solid 2px var(--black);
-                    }
-                }
-        
-                &.cw-canvasblock-tool {
-                    &.cw-canvasblock-tool-pen {
-                        @include background-icon(comment, clickable);
-                    }
-        
-                    &.cw-canvasblock-tool-text {
-                        vertical-align: top;
-                        font-size: 22px;
-                        color: var(--base-color);
-                        font-weight: 600;
-                    }
-        
-                    &.selected-tool {
-                        border: solid 2px var(--black);
-                    }
-                }
-        
-                &.cw-canvasblock-undo {
-                    @include background-icon(arr_2left, clickable, 24);
-                }
-        
-                &.cw-canvasblock-download {
-                    @include background-icon(download, clickable, 24);
-                }
-                &.cw-canvasblock-store {
-                    @include background-icon(upload, clickable, 24);
-                }
-                &.cw-canvasblock-show-all {
-                    @include background-icon(group2, clickable, 24);
-                    &.selected-view {
-                        border: solid 2px var(--black);
-                    }
-                }
-                &.cw-canvasblock-show-own {
-                    @include background-icon(person, clickable, 24);
-                    &.selected-view {
-                        border: solid 2px var(--black);
-                    }
-                }
-            }
-        }
-    }
-
-    .cw-canvasblock-tool-selected-text {
-        cursor: text;
-    }
-}
-/* * * * * * * * * * * * * * *
-c a n v a s  b l o c k  e n d
-* * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * *
-d o c u m e n t  b l o c k
-* * * * * * * * * * * * */
-.cw-block-document {
-    .cw-pdf-main-container {
-        width: calc(100% - 2px);
-        border: solid thin var(--content-color-40);
-        .cw-block-title {
-            border: none;
-            border-bottom: solid thin var(--content-color-40);
-        }
-    }
-    .cw-pdf-toolbar {
-        position: relative;
-        display: flex;
-        flex-direction: row;
-        justify-content: flex-start;
-        align-items: baseline;
-        align-content: space-around;
-        background-color: var(--content-color-20);
-        padding: 4px 8px;
-
-        button {
-            height: 100%;
-            margin: 0 2px 0 0;
-            padding: 4px;
-            
-            &.active {
-                background-color: var(--base-color);
-            }
-        }
-
-        .cw-pdf-toolbar-left {
-            position: relative;
-            display: flex;
-            flex-direction: row;
-            justify-content: flex-start;
-            align-items: baseline;
-            align-content: space-between;
-            width: 33%;
-        }
-        .cw-pdf-toolbar-middle {
-            position: relative;
-            display: flex;
-            justify-content: center;
-            width: 34%;
-
-            .cw-pdf-zoom-buttons {
-                margin-right: 8px;
-
-                button {
-                    margin: 0;
-                    padding: 4px 0;
-                }
-            }
-        }
-        .cw-pdf-toolbar-right {
-            display: flex;
-            flex-direction: row;
-            justify-content: flex-end;
-            align-items: baseline;
-            align-content: space-between;
-            position: relative;
-            width: 33%;
-            margin-right: 4px;
-
-        }
-        .cw-pdf-page-nav {
-            margin: 0 4px;
-
-            button {
-                margin: 0;
-                padding: 4px 0;
-            }
-            .cw-pdf-page-num {
-                text-align: right;
-                width: 2em;
-            }
-        }
-
-        .cw-pdf-search-box {
-            position: absolute;
-            top: 33px;
-            left: 22px;
-            width: auto;
-            background-color: var(--content-color-20);
-            border-top: none;
-            padding: 6px;
-            z-index: 2;
-            line-height: normal;
-
-            .cw-pdf-search-num {
-                margin: 4px 0 0 0;
-                display: block;
-            }
-            .cw-pdf-search-navs {
-                display: inline-block;
-                button {
-                    margin: 0;
-                    padding: 0;
-                }
-            }
-        }
-    }
-    .cw-pdf-outer-container {
-        position: relative;
-        width: 100%;
-
-        .cw-pdf-content {
-            display: flex;
-            flex-direction: row;
-
-            .cw-pdf-sidebar {
-                width: 25%;
-                min-width: 270px;;
-                align-self: stretch;
-                background-color: var(--white);
-                border-right: solid 1px var(--content-color-40);
-    
-                ul.cw-pdf-toc-list, ul.cw-pdf-toc-sub-list {
-                    padding: 0;
-                    list-style: none;
-    
-                    li {
-                        padding: 0.5em 1em;
-                    }
-                }
-                ul.cw-pdf-toc-list {
-                    margin-top: 1em;
-                }
-            }
-
-            .cw-pdf-viewer-container {
-                width: 100%;
-                height: 100%;
-                overflow: hidden;
-                cursor: text;
-    
-                &.hand-cursor-grab {
-                    cursor: grab;
-                    &.grabbing {
-                        cursor: grabbing;
-                    }
-                }
-                &.has-error {
-                    display: none;
-                }
-                .page {
-                    position: relative;
-                    margin: 0 auto;
-                }
-            }
-
-        }
-
-
-        .cw-pdf-viewer-fake-container {
-            position: absolute;
-        }
-
-
-        .cw-pdf-error-page {
-            overflow: hidden;
-            width: calc(100% - 16px);
-            height: 100%;
-            padding: 8px;
-            display:table;
-        }
-    }
-}
-/* * * * * * * * * * * * * * * * * *
-d o c u m e n t  b l o c k  e n d
-* * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * * *
-e m b e d  b l o c k
-* * * * * * * * * * */
-
-.cw-block-embed {
-    .cw-block-content {
-        .cw-block-embed-iframe-wrapper {
-            overflow-y: hidden;
-            iframe{
-                height: 100% !important;
-                width: 100% !important;
-            }
-        }
-        .cw-block-embed-info {
-            margin-top: 0.5em;
-        }
-    }
-}
-
-/* * * * * * * * * * * * * *
-e m b e d  b l o c k  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * * * *
-i f r a m e  b l o c k
-* * * * * * * * * * */
-
-.cw-block-iframe {
-    .cw-block-content {
-        iframe {
-            border: solid thin var(--content-color-40);
-            width: calc(100% - 2px);
-        }
-
-        .cw-block-iframe-cc-data {
-            border: solid thin var(--content-color-40);
-            border-top: none;
-            margin-top: -6px;
-            padding-top: 10px;
-            height: 75px;
-
-            .cw-block-iframe-cc {
-                width: 120px;
-                height: 50px;
-                margin-left: 4px;
-                display: inline-block;
-                background-repeat: no-repeat;
-                &.cw-block-iframe-cc-by {
-                    background-image: url("#{$image-path}/cc/by.svg");
-                }
-                &.cw-block-iframe-cc-by-nc {
-                    background-image: url("#{$image-path}/cc/by-nc.eu.svg");
-                }
-                &.cw-block-iframe-cc-by-nc-nd {
-                    background-image: url("#{$image-path}/cc/by-nc-nd.eu.svg");
-                }
-                &.cw-block-iframe-cc-by-nc-sa {
-                    background-image: url("#{$image-path}/cc/by-nc-sa.svg");
-                }
-                &.cw-block-iframe-cc-by-nd {
-                    background-image: url("#{$image-path}/cc/by-nd.svg");
-                }
-                &.cw-block-iframe-cc-by-sa {
-                    background-image: url("#{$image-path}/cc/by-sa.svg");
-                }
-            }
-            .cw-block-iframe-cc-infos{
-                display: inline-block;
-                vertical-align: top;
-                padding-left: 1em;
-                p {
-                    margin: 0;
-                }
-            }
-        }
-
-
-
-    }
-}
-
-/* * * * * * * * * * * * * *
-i f r a m e  b l o c k  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * +
-l t i  b l o c k
-* * * * * * * * */
-.cw-block-lti {
-    .cw-block-content {
-        .cw-block-lti-content {
-            border: solid thin var(--content-color-40);
-            box-sizing: border-box;
-        }
-        .cw-block-lti-icon-tool {
-            @include background-icon(plugin, info, 24);
-            background-repeat: no-repeat;
-
-            display: block;
-            padding: 16px 16px 16px 40px;
-            background-position: 10px center;
-            overflow: hidden;
-            text-overflow: ellipsis;
-        }
-    }
-}
-/* * * * * * * * * * * *
-l t i  b l o c k  e n d
-* * * * * * * * * * * */
-
-/* * * * * * * * * * * *
-f o l d e r  b l o c k
-* * * * * * * * * * * */
-.cw-block-folder-info {
-    border: solid thin var(--content-color-40);
-    padding: 10px 10px 0 10px;
-    overflow: hidden;
-    border-bottom: none;
-}
-.cw-block-folder-list {
-    border: solid thin var(--content-color-40);
-    padding: 0;
-    list-style: none;
-
-    .cw-block-folder-file-item {
-        list-style: none;
-
-        &:not(:last-child) {
-            border-bottom: solid thin var(--content-color-40);
-        }
-        a {
-            display: block;
-        }
-        &:hover {
-            background-color: hsla(217,6%,45%,.2);
-        }
-    }
-    .cw-block-folder-download-icon {
-        @include background-icon(download, clickable, 24);
-        background-repeat: no-repeat;
-
-        float: right;
-        height: 24px;
-        width: 24px;
-        margin: 1em;
-    }
-}
-.cw-block-folder-upload {
-    border: solid thin var(--content-color-40);
-    padding: 1em 10px;
-    border-top: none;
-
-    .cw-file-input {
-        width: calc(100% - 148px);
-        vertical-align: middle;
-    }
-}
-// for folder and download block
-.cw-block-file-info {
-    @include background-icon(file, clickable, 24);
-    background-repeat: no-repeat;
-
-    display: block;
-    padding: 16px 16px 16px 40px;
-    background-position: 10px 16px;
-    width: calc(100% - 56px);
-    overflow: hidden;
-    text-overflow: ellipsis;
-
-    &.cw-block-file-icon-empty {
-        color: var(--black);
-        @include background-icon(folder-empty, info, 24);
-    }
-    &.cw-block-file-icon-none {
-        color: var(--black);
-        @include background-icon(file, info, 24);
-    }
-    &.cw-block-file-icon-audio {
-        @include background-icon(file-audio, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-audio, info, 24);
-        }
-    }
-    &.cw-block-file-icon-pic {
-        @include background-icon(file-pic, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-pic, info, 24);
-        }
-    }
-    &.cw-block-file-icon-video {
-        @include background-icon(file-video, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-video, info, 24);
-        }
-    }
-    &.cw-block-file-icon-pdf {
-        @include background-icon(file-pdf, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-pdf, info, 24);
-        }
-    }
-    &.cw-block-file-icon-word {
-        @include background-icon(file-word, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-word, info, 24);
-        }
-    }
-    &.cw-block-file-icon-spreadsheet {
-        @include background-icon(file-excel, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-excel, info, 24);
-        }
-    }
-    &.cw-block-file-icon-text {
-        @include background-icon(file-text, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-text, info, 24);
-        }
-    }
-    &.cw-block-file-icon-ppt {
-        @include background-icon(file-ppt, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-ppt, info, 24);
-        }
-    }
-    &.cw-block-file-icon-archive {
-        @include background-icon(file-archive, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file-archive, info, 24);
-        }
-    }
-    &.cw-block-file-icon-file {
-        @include background-icon(file, clickable, 24);
-        &.download-disabled {
-            @include background-icon(file, info, 24);
-        }
-    }
-}
-.cw-block-file-details {
-    margin-top: -16px;
-    padding-left: 40px;
-    padding-bottom: 16px;
-    color: var(--dark-gray-color);
-}
-.cw-block-file-owner,
-.cw-block-file-mkdate {
-    display: block;
-    width: calc(100% - 56px);
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-/* * * * * * * * * * * * * * *
-f o l d e r  b l o c k  e n d
-* * * * * * * * * * * * * * */
-
-
-/* * * * * * * * * * * * * *
-d o w n l o a d  b l o c k
-* * * * * * * * * * * * * */
-.cw-block-download {
-    .cw-block-download-content {
-        border: solid thin var(--content-color-40);
-        .cw-block-download-file-item {
-            a {
-                display: block;
-            }
-            &:hover {
-                background-color: fade-out($dark-gray-color-75, 0.8);
-            }
-            .cw-block-download-download-icon {
-                @include background-icon(download, clickable, 24);
-                background-repeat: no-repeat;
-
-                float: right;
-                height: 24px;
-                width: 24px;
-                margin: 1em;
-            }
-        }
-    }
-
-}
-
-/* * * * * * * * * * * * * * * * *
-d o w n l o a d  b l o c k  e n d
-* * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * *
-g a l l e r y  b l o c k
-* * * * * *  * * * * * * */
-
-.cw-block-gallery {
-    .cw-block-content {
-        overflow: hidden;
-    }
-}
-
-.cw-block-gallery-content {
-    position: relative;
-    margin: auto;
-}
-
-.cw-block-gallery-slides {
-    display: none;
-    img {
-        display: block;
-        max-width: 100%;
-        margin-left: auto;
-        margin-right: auto;
-    }
-}
-
-.cw-block-gallery-prev,
-.cw-block-gallery-next {
-    cursor: pointer;
-    position: absolute;
-    background-color: fade-out($white, 0.6);
-    top: 50%;
-    height: 36px;
-    width: 36px;
-    background-repeat: no-repeat;
-    background-position: center;
-    margin-top: -22px;
-    transition: 200ms ease;
-    user-select: none;
-    border: none;
-
-    &:hover {
-        background-color: var(--base-color);
-    }
-}
-
-.cw-block-gallery-prev {
-    @include background-icon(arr_1left, clickable, 24);
-    &:hover{
-        @include background-icon(arr_1left, info-alt, 24);
-    }
-}
-.cw-block-gallery-next {
-    right: 0;
-    @include background-icon(arr_1right, clickable, 24);
-    &:hover {
-        @include background-icon(arr_1right, info-alt, 24);
-    }
-}
-
-.cw-block-gallery-file-description {
-    width: -moz-available;
-    color: var(--white);
-    font-size: 15px;
-    padding: 8px 12px;
-    position: absolute;
-    bottom: 8px;
-    text-align: center;
-    p {
-        display: -webkit-inline-box;
-        background-color: fade-out($black, 0.6);
-        padding: 0 2em;
-        margin-bottom: 4px;
-        overflow: hidden;
-        -webkit-line-clamp: 3;
-        -webkit-box-orient: vertical;
-    }
-
-    &.show-on-hover {
-        display: none;
-    }
-}
-
-.cw-block-gallery-content:hover .show-on-hover {
-    display: block;
-}
-
-.cw-block-gallery-number-text {
-    color: var(--white);
-    font-size: 12px;
-    padding: 8px 12px;
-    position: absolute;
-    top: 0;
-    background-color: fade-out($black, 0.6);
-}
-
- .cw-block-gallery-fade {
-    -webkit-animation-name: fade;
-    -webkit-animation-duration: 1.5s;
-    animation-name: fade;
-    animation-duration: 1.5s;
-}
-
-@-webkit-keyframes fade {
-    from {opacity: .4}
-    to {opacity: 1}
-}
-
-@keyframes fade {
-    from {opacity: .4}
-    to {opacity: 1}
-}
-
-
-.cw-block-gallery-grid {
-    display: flex;
-    flex-direction: row;
-    flex-wrap: wrap;
-    justify-content: flex-start;
-    list-style: none;
-    padding: 0;
-    figure {
-        padding: 1px 4px;
-        margin: unset;
-        figcaption {
-            margin-bottom: 12px;
-
-            .cw-block-gallery-grid-file-name {
-                font-weight: 700;
-                margin-bottom: 4px;
-                overflow: hidden;
-                display: -webkit-box;
-                -webkit-line-clamp: 2;
-                -webkit-box-orient: vertical;
-            }
-            .cw-block-gallery-grid-file-description {
-                overflow: hidden;
-                display: -webkit-box;
-                -webkit-line-clamp: 5;
-                -webkit-box-orient: vertical;
-            }
-        }
-    }
-}
-.cw-container-wrapper-edit .cw-block-gallery-grid {
-    margin: 0;
-}
-
-/* * * * * * * * * * * * * * * * *
-g a l l e r y  b l o c k  e n d
-* * * * * * * * * * * * * * * * */
-
-
-/* * * * * * * * * * * * * * * * *
-i m a g e  m a p  b l o c k
-* * * * * * * * * * * * * * * * */
-.cw-block-image-map {
-    .cw-image-map-canvas,
-    .cw-image-map-original-img {
-      display: none;
-    }
-
-    form.default {
-        label.cw-block-image-map-dimensions > input[type=number] {
-            display: inline-block;
-        }
-    }
-}
-
-/* * * * * * * * * * * * * * * * *
-i m a g e  m a p  b l o c k  e n d
-* * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * *
-b i o g r a p h y  b l o c k
-* * * * * * * * * * * * * */
-
-.cw-block-biography {
-    .cw-block-biography-content {
-        display: flex;
-        min-height: 200px;
-        flex-direction: row;
-        padding: 2em 2em 2em 1em;
-        border: 2px solid var(--base-color);
-
-        .cw-block-biography-type {
-            margin: auto 1em auto 0;
-            padding-top: 96px;
-            min-width: 192px;
-            max-width: 192px;
-            text-align: center;
-            background-repeat: no-repeat;
-            background-position: center top;
-        }
-
-        .cw-block-biography-details {
-            h2, h3 {
-                margin-top: 0;
-            }
-        }
-
-    }
-}
-
-/* * * * * * * * * * * * * * * * * *
-b i o g r a p h y  b l o c k  e n d
-* * * * * * * * * * * * * * * * * */
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * *
-b i o g r a p h y  a c h i e v e m e n t s  b l o c k
-* * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.cw-block-biography-achievements {
-    @each $type, $icon in $achievement-types {
-        .cw-block-biography-achievements-type-#{$type} {
-            @include background-icon($icon, clickable, 96);
-        }
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-b i o g r a p h y  a c h i e v e m e n t s  b l o c k  e n d
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * ** * * * * * *
-b i o g r a p h y  g o a l s  b l o c k
-* * * * * * * * * * * * * * * * * * * */
-
-.cw-block-biography-goals {
-    @each $type, $icon in $goals-types {
-        .cw-block-biography-goals-type-#{$type} {
-            @include background-icon($icon, clickable, 96);
-        }
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * *
-b i o g r a p h y  g o a l s  b l o c k  e n d
-* * * * * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-b i o g r a p h y  p e r s o n a l  i n f o r m a t i o n  b l o c k
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.cw-block-biography-personal-information {
-    .cw-block-biography-content {
-        min-height: 140px;
-
-        .cw-block-biography-personal-information-type {
-            @include background-icon(person2, clickable, 96);
-        }
-
-        .cw-block-biography-personal-information-details {
-            display: grid;
-            max-height: 7em;
-            grid-template-columns: max-content 1fr;
-            grid-gap: 5px 10px;
-
-            .preface {
-                grid-column-start: 1;
-                grid-column-end: 3;
-            }
-        }
-    }
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-b i o g r a p h y  p e r s o n a l  i n f o r m a t i o n  b l o c k  e n d
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * * *
-l i n k  b l o c k
-* * * * * * * * * */
-
-.cw-block-link {
-    a {
-        text-decoration: none;
-    }
-    .cw-link {
-        border: solid thin var(--content-color-40);
-        color: var(--base-color);
-        height: 20px;
-        padding: 1em;
-
-        .cw-link-title {
-            margin-left: 3em;
-        }
-
-        &:hover {
-            background-color: var(--base-color);
-            border: solid thin var(--base-color);
-            color: var(--white);
-        }
-
-        &.internal {
-            @include background-icon(link-intern, clickable, 28);
-            background-position: 1em 50%;
-            background-repeat: no-repeat;
-
-            &:hover {
-                @include background-icon(link-intern, info-alt, 28);
-            }
-        }
-
-        &.external {
-            @include background-icon(link-extern, clickable, 28);
-            background-position: 1em 50%;
-            background-repeat: no-repeat;
-            &:hover {
-                @include background-icon(link-extern, info-alt, 28);
-            }
-
-            .cw-link-og-image {
-                display: inline-block;
-                max-width: 40%;
-                vertical-align: top;
-                margin-right: 2em;
-            }
-            .cw-link-og-textwrapper {
-                display: inline-block;
-                max-width: 50%;
-                p {
-                    margin: 0;
-                }
-                .cw-link-og-site {
-                    font-size: 1.25em;
-                }
-                .cw-link-og-title {
-                    font-weight: 600;
-                }
-                .cw-link-og-description {
-                    color: var(--base-color-80);
-                    text-align: justify;
-                }
-            }
-        }
-    }
-}
-
-/* * * * * * * * * * * * *
-l i n k  b l o c k  e n d
-* * * * * * * * * * * * */
-
-/*
-dialog cards block
-*/
-.cw-block-dialog-cards-content {
-    display: flex;
-    .cw-dialogcards {
-        flex-grow: 2;
-        .scene {
-            margin: 0 auto;
-            width: 440px;
-            height: 600px;
-            perspective: 880px;
-            display: none;
-            &.active {
-                display: block;
-                animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
-                transform: translate3d(0, 0, 0);
-                backface-visibility: hidden;
-                perspective: 1000px;
-            }
-        }
-
-        .card {
-            width: 100%;
-            height: 78%;
-            transition: transform 1s;
-            transform-style: preserve-3d;
-            cursor: pointer;
-            position: relative;
-            top: 11%;
-        }
-
-        .card.is-flipped {
-            transform: rotateY(180deg);
-        }
-
-        .card__face {
-            position: absolute;
-            width: 100%;
-            height: 100%;
-            color: var(--black);
-            text-align: center;
-            font-weight: bold;
-            font-size: 1.2em;
-            backface-visibility: hidden;
-            box-shadow: 0 2px 15px fade-out($black, 0.7);
-
-            img {
-                max-width: 380px;
-                max-height: 220px;
-                margin-top: 1em;
-            }
-
-            .cw-dialogcards-front-no-image {
-                @include background-icon(question, navigation, 150);
-            }
-
-            .cw-dialogcards-back-no-image {
-                @include background-icon(exclaim, navigation, 150);
-            }
-
-            .cw-dialogcards-front-no-image,
-            .cw-dialogcards-back-no-image {
-                width: 100%;
-                height: 180px;
-                margin-top: 2em;
-                background-repeat: no-repeat;
-                background-position-x: center;
-            }
-
-            p {
-                margin: 1em 3em 1em 4em;
-                padding-right: 1em;
-                overflow-y: auto;
-                max-height: 12em;
-                text-align: justify;
-            }
-        }
-
-        .card__face--front {
-            @include background-icon(arr_1right, clickable);
-            background-color: var(--white);
-            background-repeat: no-repeat;
-            background-position: 95% 95%;
-        }
-
-        .card__face--back {
-            @include background-icon(arr_1left, clickable);
-            background-color: var(--white);
-            background-repeat: no-repeat;
-            background-position: 5% 95%;
-            transform: rotateY(180deg);
-        }
-    }
-
-    .cw-dialogcards-navbutton {
-        color: transparent;
-        width: 35px;
-        height: 35px;
-        border-radius: 2px;
-        background-position: 50%;
-        background-repeat: no-repeat;
-        background-color: var(--base-color);
-        border: none;
-        display: block;
-        z-index: 4;
-        margin: auto 2px;
-        padding: 0;
-        cursor: pointer;
-
-        &.cw-dialogcards-prev {
-            @include background-icon(arr_1left, info-alt, 24);
-
-        }
-
-        &.cw-dialogcards-next {
-            @include background-icon(arr_1right, info-alt, 24);
-            right: 0;
-        }
-
-        &.cw-dialogcards-prev-disabled,
-        &.cw-dialogcards-next-disabled {
-            background-color: var(--light-gray-color-40);
-        }
-    }
-
-    @keyframes shake {
-        10%, 90% {
-            transform: translate3d(-1px, 0, 0);
-        }
-
-        20%, 80% {
-            transform: translate3d(2px, 0, 0);
-        }
-
-        30%, 50%, 70% {
-            transform: translate3d(-4px, 0, 0);
-        }
-
-        40%, 60% {
-            transform: translate3d(4px, 0, 0);
-        }
-    }
-}
-
-
-/*
-dialog cards block end
-*/
-
-/*
-headline block
-*/
-$big-icon-size: 196;
-$big-icon-size-px: $big-icon-size + px;
-$large-icon-size: 128;
-$large-icon-size-px: $large-icon-size + px;
-
-.cw-block-headline {
-    .cw-block-headline-content {
-        min-height: 600px;
-        overflow: hidden;
-        background-position: center;
-        background-size: $max-content-width;
-        background-repeat: no-repeat;
-
-        &.half {
-            min-height: 300px;
-        }
-
-        &.quarter {
-            min-height: 150px;
-        }
-
-        &.heavy {
-
-            .cw-block-headline-iconbox {
-                display: none;
-            }
-            .cw-block-headline-textbox {
-                margin: 2em;
-                h1, h2 {
-                    display: inline;
-                    border: none;
-                    padding: 0.25em 0;
-                }
-                h1 {
-                    font-size: 10em;
-                    line-height: 1.2em;
-                }
-                h2 {
-                    font-size: 2em;
-                    line-height: 1em;
-                }
-
-                &.quarter {
-                    margin: 1.5em;
-                    h1 {
-                        font-size: 5em;
-                    }
-                    h2 {
-                        font-size: 1.5em;
-                    }
-                }
-            }
-
-        }
-        &.bigicon_top {
-            .icon-layer {
-                background-repeat: no-repeat;
-                background-position: center;
-                margin-top: 8em;
-                margin-bottom: 1em;
-                background-size: $big-icon-size-px;
-                height: $big-icon-size-px;
-
-                @each $icon in $icons {
-                    &.icon-black-#{$icon} {
-                        @include background-icon($icon, info, $big-icon-size);
-                    }
-                    &.icon-white-#{$icon} {
-                        @include background-icon($icon, info-alt, $big-icon-size);
-                    }
-                    &.icon-studip-blue-#{$icon} {
-                        @include background-icon($icon, clickable, $big-icon-size);
-                    }
-                    &.icon-studip-red-#{$icon} {
-                        @include background-icon($icon, status-red, $big-icon-size);
-                    }
-                    &.icon-studip-yellow-#{$icon} {
-                        @include background-icon($icon, status-yellow, $big-icon-size);
-                    }
-                    &.icon-studip-green-#{$icon} {
-                        @include background-icon($icon, status-green, $big-icon-size);
-                    }
-                    &.icon-studip-gray-#{$icon} {
-                        @include background-icon($icon, inactive, $big-icon-size);
-                    }
-                };
-
-               &.half {
-                    height: 144px;
-                    background-size: 144px;
-                    background-position: center;
-                    margin-top: 2em;
-                    margin-bottom: 0;
-                }
-                &.quarter {
-                    height: 72px;
-                    background-size: 72px;
-                    background-position: center;
-                    margin-top: 1em;
-                    margin-bottom: 0;
-                }
-            }
-
-            .cw-block-headline-textbox {
-                width: 80%;
-                padding-bottom: 4em;
-                margin: 0 auto;
-                .cw-block-headline-title {
-                    h1 {
-                        border: none;
-                        font-size: 5em;
-                        text-align: center;
-                    }
-                }
-
-                .cw-block-headline-subtitle {
-                    h2 {
-                        border: none;
-                        font-size: 18px;
-                        text-align: center;
-                        margin-top: 10px;
-                    }
-                }
-
-                &.quarter {
-                    padding-bottom: 1em;
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 2.25em;
-                            margin: 0;
-                        }
-                    }
-                    .cw-block-headline-subtitle {
-                        h2 {
-                            font-size: 1em;
-                            margin: 0;
-                        }
-                    }
-                }
-            }
-        }
-
-        &.bigicon_before {
-            display: flex;
-            align-items: center;
-            .icon-layer {
-                min-height: $big-icon-size-px;
-                min-width: $big-icon-size-px;
-                margin:0 28px 0 28px;
-                background-repeat: no-repeat;
-                background-position: left center;
-
-                @each $icon in $icons {
-                    &.icon-black-#{$icon} {
-                        @include background-icon($icon, info, $big-icon-size);
-                    }
-                    &.icon-white-#{$icon} {
-                        @include background-icon($icon, info-alt, $big-icon-size);
-                    }
-                    &.icon-studip-blue-#{$icon} {
-                        @include background-icon($icon, clickable, $big-icon-size);
-                    }
-                    &.icon-studip-red-#{$icon} {
-                        @include background-icon($icon, status-red, $big-icon-size);
-                    }
-                    &.icon-studip-yellow-#{$icon} {
-                        @include background-icon($icon, status-yellow, $big-icon-size);
-                    }
-                    &.icon-studip-green-#{$icon} {
-                        @include background-icon($icon, status-green, $big-icon-size);
-                    }
-                    &.icon-studip-gray-#{$icon} {
-                        @include background-icon($icon, inactive, $big-icon-size);
-                    }
-                };
-
-                &.quarter {
-                    min-height: $large-icon-size-px;
-                    min-width: $large-icon-size-px;
-                    background-size: $large-icon-size-px;
-                }
-            }
-
-            .cw-block-headline-textbox {
-                margin: 2em 1em 2em 0;
-                .cw-block-headline-title {
-                    h1 {
-                        border: none;
-                        font-size: 5em;
-                        text-align: left;
-                    }
-                }
-
-                .cw-block-headline-subtitle {
-                    display: none;
-                }
-            }
-        }
-
-        &.ribbon {
-            display: flex;
-            align-items: center;
-
-            .cw-block-headline-textbox {
-                width: 100%;
-                padding: 1em 0;
-                margin: 3em 0;
-                background-color: fade-out($black, 0.5);
-                .cw-block-headline-title {
-                    h1 {
-                        border: none;
-                        font-size: 5em;
-                        text-align: center;
-                        margin-bottom: 0;
-                    }
-                }
-
-                .cw-block-headline-subtitle {
-                    h2 {
-                        border: none;
-                        font-size: 18px;
-                        text-align: center;
-                        margin-top: 10px;
-                    }
-                }
-            }
-        }
-
-        &.vertical {
-            .cw-block-headline-textbox {
-
-                .cw-block-headline-title {
-                    position: relative;
-                    top: 0;
-                    left: 5em;
-                    height: 5em;
-                    text-align: center;
-                    width: 600px;
-                    transform-origin: 0 0;
-                    transform: rotate(90deg);
-                    h1 {
-                        text-transform: uppercase;
-                        border: none;
-                        font-size: 2em;
-                        line-height: 2.5em;
-                    }
-                }
-
-                .cw-block-headline-subtitle {
-                    margin: 0 8em;
-                    padding: 2em;
-                    h2 {
-                        margin: 0;
-                        font-weight: 400;
-                    }
-                }
-            }
-            &.half {
-                .cw-block-headline-title {
-                    width: 300px;
-                }
-            }
-            &.quarter {
-                .cw-block-headline-title {
-                    width: 150px;
-                    h1 {
-                        font-size: 1em;
-                        line-height: 5em;
-                    }
-                }
-                .cw-block-headline-subtitle {
-                    margin: -2em 8em 0 8em;
-                    padding: 1em;
-                }
-            }
-        }
-
-        &.skew_text {
-            min-height: 600px;
-
-            .cw-block-headline-textbox {
-                font-size: 7em;
-                text-align: left;
-                text-transform: uppercase;
-                font-weight: 800;
-                font-family: sans-serif;
-                font-style: normal;
-                letter-spacing: -6px;
-                margin: 1.25em 0 1.5em 1em;
-                div {
-                    overflow: hidden;
-                    font-size: 1em;
-                    margin: -1px 0;
-                    white-space: nowrap;
-                    height: .8em;
-                    width: calc(100% - 1em);
-
-                    h1, h2 {
-                        font-size: 0.8em;
-                        margin: 0;
-                        white-space: nowrap;
-                        overflow: hidden;
-                        line-height: .8em;
-                        height: .8em;
-                    }
-                }
-                .cw-block-headline-title,
-                .cw-block-headline-second-subtitle {
-                    transform: skew(60deg,-15deg) scaley(.66667);
-                }
-                .cw-block-headline-subtitle {
-                    transform: skew(0deg,-15deg) scaley(1.33333);
-                }
-                .cw-block-headline-subtitle {
-                    position: relative;
-	                left: 0.48em;
-                }
-                .cw-block-headline-second-subtitle {
-                    position: relative;
-	                left: 0.92em;
-                }
-            }
-
-            &.half {
-                min-height: 300px;
-                height: 300px;
-                .cw-block-headline-textbox {
-                    font-size: 4em;
-                    margin: 1.5em 0 1.5em 1em;
-                    div {
-                        width: calc(100% - 9em);
-                    }
-                }
-            }
-            &.quarter {
-                min-height: 150px;
-                height: 150px;
-                .cw-block-headline-textbox {
-                    font-size: 2em;
-                    margin: 0.75em 0 0.75em 1em;
-                    letter-spacing: -2px;
-                    div {
-                        width: calc(100% - 18em);
-                    }
-                }
-            }
-        }
-
-        &.icon_top_lines {
-            .cw-block-headline-iconbox {
-                margin: 32px;
-                &::before,
-                &::after {
-                    width: calc(50% - 96px);
-                    height: 64px;
-                    display: inline-block;
-                    border-top: solid 4px;
-                    content: '';
-                }
-                @each $name, $hex in $border-colors {
-                    &.border-#{""+$name}::before,
-                    &.border-#{""+$name}::after {
-                        border-color: $hex;
-                    }
-                }
-                .icon-layer {
-                    background-repeat: no-repeat;
-                    background-position: center;
-                    background-size: 128px;
-                    height: 128px;
-                    width: 192px;
-                    display: inline-block;
-                    margin: auto;
-    
-                    @each $icon in $icons {
-                        &.icon-black-#{$icon} {
-                            @include background-icon($icon, info, 128);
-                        }
-                        &.icon-white-#{$icon} {
-                            @include background-icon($icon, info-alt, 128);
-                        }
-                        &.icon-studip-blue-#{$icon} {
-                            @include background-icon($icon, clickable, 128);
-                        }
-                        &.icon-studip-red-#{$icon} {
-                            @include background-icon($icon, status-red, 128);
-                        }
-                        &.icon-studip-yellow-#{$icon} {
-                            @include background-icon($icon, status-yellow, 128);
-                        }
-                        &.icon-studip-green-#{$icon} {
-                            @include background-icon($icon, status-green, 128);
-                        }
-                        &.icon-studip-gray-#{$icon} {
-                            @include background-icon($icon, inactive, 128);
-                        }
-                    };
-    
-                   &.half {
-                        height: 128px;
-                        background-size: 128px;
-                    }
-                    &.quarter {
-                        height: 64px;
-                        width: 96px;
-                        background-size: 64px;
-                    }
-                }
-                &.half {
-                    margin: 16px 32px;
-                }
-                &.quarter {
-                    margin: 8px 32px 0 32px;
-                    &::before,
-                    &::after {
-                        width: calc(50% - 48px);
-                        height: 32px;
-                    }
-                }
-            }
-            .cw-block-headline-textbox {
-                width: calc(100% - 64px);
-                min-height: 350px;
-                margin: 0 auto;
-                border-bottom: solid 4px;
-                @each $name, $hex in $border-colors {
-                    &.border-#{""+$name} {
-                        border-color: $hex;
-                    }
-                }
-                .cw-block-headline-title {
-                    h1 {
-                        border: none;
-                        font-size: 5em;
-                        text-align: center;
-                    }
-                }
-
-                .cw-block-headline-subtitle {
-                    h2 {
-                        border: none;
-                        font-size: 18px;
-                        text-align: center;
-                        margin: 22px 64px;
-                    }
-                }
-
-                &.half {
-                    min-height: 0px;
-                    margin-bottom: 32px;
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 4em;
-                        }
-                    }
-    
-                    .cw-block-headline-subtitle {
-                        h2 {
-                            font-size: 1em;
-                            margin: 1em 64px;
-                        }
-                    }
-                }
-                &.quarter {
-                    min-height: 0;
-                    margin-bottom: 0;
-                    border: none;
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 2em;
-                        }
-                    }
-    
-                    .cw-block-headline-subtitle {
-                        h2 {
-                            font-size: 1em;
-                            margin: 8px 64px;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-.cw-container-colspan-half,
-.cw-container-colspan-half-center {
-    .cw-block-headline {
-        .cw-block-headline-content {
-            min-height: 300px;
-
-            &.half {
-                min-height: 150px;
-            }
-            &.heavy {
-                h1 {
-                    font-size: 4.5em;
-                }
-                h2 {
-                    font-size: 1.25em;
-                }
-            }
-            &.bigicon_top {
-                .icon-layer {
-                    background-position: center;
-                    height: 98px;
-                    margin-top: 2em;
-                    margin-bottom: 1em;
-
-                    @each $icon in $icons {
-                        &.icon-black-#{$icon} {
-                            @include background-icon($icon, info, 98);
-                        }
-                        &.icon-white-#{$icon} {
-                            @include background-icon($icon, info-alt, 98);
-                        }
-                        &.icon-studip-blue-#{$icon} {
-                            @include background-icon($icon, clickable, 98);
-                        }
-                        &.icon-studip-red-#{$icon} {
-                            @include background-icon($icon, status-red, 98);
-                        }
-                        &.icon-studip-yellow-#{$icon} {
-                            @include background-icon($icon, status-yellow, 98);
-                        }
-                        &.icon-studip-green-#{$icon} {
-                            @include background-icon($icon, status-green, 98);
-                        }
-                        &.icon-studip-gray-#{$icon} {
-                            @include background-icon($icon, inactive, 98);
-                        }
-                    };
-
-                    &.half {
-                        background-size: 72px;
-                        height: 72px;
-                        background-position: center;
-                    }
-                }
-
-
-                .cw-block-headline-textbox {
-                    max-width: 80%;
-                    margin: 0 auto;
-                    padding-bottom: 1em;
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 2em;
-                        }
-                    }
-
-                    .cw-block-headline-subtitle {
-                        h2 {
-                            font-size: 12px;
-                        }
-                    }
-                }
-            }
-            &.bigicon_before {
-                min-height: 300px;
-                .icon-layer {
-                    min-height: 92px;
-                    min-width: 92px;
-                    background-position: 0 center;
-                    @each $icon in $icons {
-                        &.icon-black-#{$icon} {
-                            @include background-icon($icon, info, 92);
-                        }
-                        &.icon-white-#{$icon} {
-                            @include background-icon($icon, info-alt, 92);
-                        }
-                        &.icon-studip-blue-#{$icon} {
-                            @include background-icon($icon, clickable, 92);
-                        }
-                        &.icon-studip-red-#{$icon} {
-                            @include background-icon($icon, status-red, 92);
-                        }
-                        &.icon-studip-yellow-#{$icon} {
-                            @include background-icon($icon, status-yellow, 92);
-                        }
-                        &.icon-studip-green-#{$icon} {
-                            @include background-icon($icon, status-green, 92);
-                        }
-                        &.icon-studip-gray-#{$icon} {
-                            @include background-icon($icon, inactive, 92);
-                        }
-                    };
-                }
-
-                .cw-block-headline-textbox {
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 2.5em;
-                        }
-                    }
-                }
-
-                &.half {
-                    min-height: 150px;
-                }
-            }
-
-            &.ribbon {
-                min-height: 300px;
-
-                &.half {
-                    min-height: 150px;
-                }
-
-                .cw-block-headline-textbox {
-                    margin: 3em 0;
-
-                    .cw-block-headline-title {
-                        h1 {
-                            font-size: 2.5em;
-                        }
-                    }
-                    .cw-block-headline-subtitle {
-                        h2 {
-                            font-size: 12px;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-.responsive-display {
-    .cw-block-headline {
-        .cw-block-headline-content {
-            background-size: 100%;
-            &.bigicon_before {
-                .icon-layer {
-                    background-size: 144px;
-                }
-                .cw-block-headline-textbox .cw-block-headline-title h1 {
-                    font-size: 4em;
-                }
-            }
-            &.skew_text {
-                min-height: 300px;
-                .cw-block-headline-textbox {
-                    font-size: 4em;
-                    letter-spacing: -4px;
-                }
-            }
-        }
-    }
-}
-
-/*
-headline block end
-*/
-
-/*
-toc block
-*/
-.cw-block-table-of-contents {
-    .cw-block-content {
-        overflow: unset;
-    }
-}
-
-.cw-block-table-of-contents-list {
-    padding: 0;
-    list-style: none;
-    border: solid thin var(--content-color-40);
-    li {
-        &:not(:last-child) {
-            border-bottom: solid thin var(--dark-gray-color-30);
-        }
-        a {
-            display: block;
-            padding: 1em;
-        }
-        &:hover {
-            background-color: fade-out($dark-gray-color-75, 0.8);
-        }
-    }
-}
-
-.cw-block-table-of-contents-list-details {
-    padding: 0;
-    list-style: none;
-    border: solid thin var(--content-color-40);
-    li {
-        &:not(:last-child) {
-            border-bottom: solid thin var(--dark-gray-color-30);
-        }
-
-        &:hover {
-            background-color: fade-out($dark-gray-color-75, 0.8);
-        }
-        a {
-            display: block;
-            padding: 1em;
-        }
-    }
-}
-
-.cw-block-table-of-contents-title-box {
-    min-height: 3em;
-    padding-left: 1em;
-    border-left-width: 10px;
-    border-left-style: solid;
-
-    @each $name, $color in $tile-colors {
-        &.#{"" + $name} {
-            border-color: $color;
-        }
-    };
-
-    p, p:hover {
-        color: var(--black);
-    }
-}
-
-.cw-container-colspan-half {
-    .cw-block-table-of-contents-tiles.cw-tiles  {
-        .tile {
-            width: 267px;
-        }
-    }
-}
-
-/*
-toc block end
-*/
-
-/*
-text block
-*/
-.cw-block-text {
-    .cktoolbar {
-        width: 100% !important;
-        max-width: 100% !important;
-        position: relative !important;
-        top: 0 !important;
-    }
-    .cke {
-        width: 100% !important;
-    }
-    .ckplaceholder {
-        height: 0 !important;
-    }
-}
-/*
-text block end
-*/
-
-/* * * * * * * *
- t i m e l i n e
-* * * * * * * */
-// Mixins and Placeholders
-%clearfix {
-    &:after, &:before {
-        content: '';
-        display: block;
-        width: 100%;
-        clear: both;
-    }
-}
-
-// Timeline
-.cw-timeline {
-    list-style: none;
-    width: 100%;
-    margin: 30px auto;
-    position: relative;
-    padding: 0;
-    transition: all 0.4s ease;
-
-    &:before {
-        content:"";
-        width: 3px;
-        height: 100%;
-        background: var(--content-color-40);
-        left: 50%;
-        top: 0;
-        position: absolute;
-    }
-
-    &:after {
-        content: "";
-        clear: both;
-        display: table;
-        width: 100%;
-    }
-
-    .cw-timeline-item {
-        margin-bottom: 50px;
-        position: relative;
-        @extend %clearfix;
-
-        .cw-timeline-item-icon {
-            background: var(--white);
-            width: 50px;
-            height: 50px;
-            position: absolute;
-            top: 0;
-            left: 50%;
-            overflow: hidden;
-            margin-left: -25px;
-            @each $name, $color in $tile-colors {
-                &.cw-timeline-item-icon-color-#{"" + $name} {
-                    border: solid 2px $color;
-                }
-            }
-
-            border-radius: 50%;
-
-            img {
-                position: relative;
-                top: 9px;
-                left: 9px;
-
-                &.charcoal {
-                    filter: brightness(0) saturate(100%) invert(22%) sepia(29%) saturate(364%) hue-rotate(168deg) brightness(87%) contrast(79%);
-                }
-                &.royal-purple {
-                    filter: brightness(0) saturate(100%) invert(35%) sepia(43%) saturate(658%) hue-rotate(234deg) brightness(100%) contrast(87%);
-                }
-                &.iguana-green {
-                    filter: brightness(0) saturate(100%) invert(74%) sepia(9%) saturate(1885%) hue-rotate(76deg) brightness(86%) contrast(88%);
-                }
-                &.queen-blue {
-                    filter: brightness(0) saturate(100%) invert(44%) sepia(10%) saturate(2086%) hue-rotate(178deg) brightness(88%) contrast(80%);
-                }
-                &.verdigris {
-                    filter: brightness(0) saturate(100%) invert(64%) sepia(11%) saturate(4959%) hue-rotate(131deg) brightness(103%) contrast(49%);
-                }
-                &.mulberry {
-                    filter: brightness(0) saturate(100%) invert(49%) sepia(16%) saturate(1665%) hue-rotate(271deg) brightness(88%) contrast(95%);
-                }
-                &.pumpkin {
-                    filter: brightness(0) saturate(100%) invert(38%) sepia(86%) saturate(1993%) hue-rotate(13deg) brightness(104%) contrast(108%);
-                }
-                &.sunglow {
-                    filter: brightness(0) saturate(100%) invert(93%) sepia(69%) saturate(6824%) hue-rotate(313deg) brightness(102%) contrast(100%);
-                }
-                &.apple-green {
-                    filter: brightness(0) saturate(100%) invert(69%) sepia(5%) saturate(5203%) hue-rotate(42deg) brightness(100%) contrast(84%);
-                }
-                &.studip-blue {
-                    filter: brightness(0) saturate(100%) invert(26%) sepia(19%) saturate(1783%) hue-rotate(177deg) brightness(96%) contrast(93%);
-                }
-                &.studip-lightblue {
-                    filter: brightness(0) saturate(100%) invert(91%) sepia(12%) saturate(190%) hue-rotate(190deg) brightness(104%) contrast(89%);
-                }
-                &.studip-red {
-                    filter: brightness(0) saturate(100%) invert(8%) sepia(95%) saturate(6904%) hue-rotate(1deg) brightness(95%) contrast(109%);
-                }
-                &.studip-green {
-                    filter: brightness(0) saturate(100%) invert(27%) sepia(85%) saturate(1531%) hue-rotate(109deg) brightness(95%) contrast(101%);
-                }
-                &.studip-yellow {
-                    filter: brightness(0) saturate(100%) invert(94%) sepia(14%) saturate(7314%) hue-rotate(330deg) brightness(103%) contrast(101%);
-                }
-                &.studip-gray {
-                    filter: brightness(0) saturate(100%) invert(46%) sepia(1%) saturate(2621%) hue-rotate(169deg) brightness(87%) contrast(87%);
-                }
-            }
-        }
-
-        .cw-timeline-item-content {
-            width: 40%;
-            background: var(--white);
-            padding: 20px;
-            transition: all var(--transition-duration) ease;
-
-            h3 {
-                padding: 15px;
-                color: var(--white);
-                margin: -20px -20px 0 -20px;
-                font-weight: 700;
-                min-height: 1.1em;
-            }
-
-            article {
-                min-height: 2em;
-                border: solid thin var(--content-color-20);
-                border-top: none;
-                margin: 0 -20px;
-                padding: 15px;
-
-                header {
-                    font-weight: 700;
-                    font-size: 1.1em;
-                    margin: 0.5em 0;
-                }
-            }
-
-            &:before {
-                content: '';
-                position: absolute;
-                left: calc(40% + 40px);
-                top: 18px;
-                width: 0;
-                height: 0;
-                border-top: 7px solid transparent;
-                border-bottom: 7px solid transparent;
-            }
-            &.left {
-                h3 {
-                    text-align: right;
-                }
-            }
-            &.right {
-                float: right;
-
-                h3 {
-                    text-align: left;
-                }
-
-                &:before {
-                    content: '';
-                    right: calc(40% + 40px);
-                    left: inherit;
-                    border-left: 0;
-                }
-            }
-
-            @each $name, $color in $tile-colors {
-                &.cw-timeline-item-content-color-#{"" + $name} {
-                    border-color: var(--color);
-                    h3 {
-                        background-color: var(--color);
-                    }
-                    &.left {
-                        &:before {
-                            border-left: 7px solid var(--color);
-                        }
-                    }
-                    &.right {
-                        &:before {
-                            border-right: 7px solid var(--color);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-@mixin oneSidedTimeline() {
-    .cw-timeline {
-        &:before {
-            left: 25px;
-        }
-        .cw-timeline-item {
-            .cw-timeline-item-icon {
-                left: 25px;
-            }
-            .cw-timeline-item-content {
-                width: stretch;
-                margin-left: 70px;
-                &.left {
-                    float: unset;
-
-                    h3 {
-                        text-align: left;
-                    }
-
-                    &:before {
-                        content: '';
-                        right: calc(100% - 70px);
-                        left: inherit;
-                        border-left: 0;
-                    }
-                }
-                &.right {
-                    float: unset;
-                    &:before {
-                        right: calc(100% - 70px);
-                    }
-                }
-
-                @each $name, $color in $tile-colors {
-                    &.cw-timeline-item-content-color-#{"" + $name} {
-                        &.left {
-                            &:before {
-                                border-right: 7px solid $color;
-                                border-left: none;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-.cw-container-colspan-half {
-    @include oneSidedTimeline();
-}
-
-@media only screen and (max-width: 1070px) {
-    @include oneSidedTimeline();
-}
-/* * * * * * * * * * * *
- t i m e l i n e  e n d
-* * * * * * * * * * * */
-
-/*
-cw tiles
-*/
-
-.cw-tiles {
-    list-style: none;
-    display: flex;
-    flex-wrap: wrap;
-    padding-left: 0;
-    row-gap: 5px;
-    column-gap: 5px;
-}
-.cw-tiles .tile,
-.cw-tile {
-    height: 420px;
-    width: 270px;
-    margin: 0;
-    background-color: var(--base-color);
-    &:last-child {
-        margin-right: 0;
-    }
-
-    @each $name, $color in $tile-colors {
-        &.#{"" + $name} {
-            background-color: $color;
-        }
-    };
-
-    .preview-image {
-        height: 180px;
-        width: 100%;
-        background-size: 100% auto;
-        background-repeat: no-repeat;
-        background-color: var(--content-color-20);
-        background-position: center;
-        &.default-image {
-                @include background-icon(courseware, clickable, 128);
-        }
-
-        .overlay-text {
-            padding: 6px 7px;
-            margin: 4px;
-            background-color: rgba(255,255,255,0.8);
-            width: fit-content;
-            max-width: 100%;
-            height: 1.25em;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            float: right;
-            text-align: right;
-        }
-
-        .overlay-action-menu {
-            padding: 0;
-            margin: 0.25em;
-            background-color: rgba(255,255,255,0.8);
-            width: fit-content;
-            max-width: 100%;
-            overflow: hidden;
-            float: right;
-            text-align: right;
-            .action-menu {
-                margin: 5px;
-            }
-        }
-    }
-
-    .description {
-        height: 220px;
-        padding: 14px;
-        color: var(--white);
-        position: relative;
-        display: block;
-
-        header {
-            font-size: 20px;
-            line-height: 22px;
-            color: var(--white);
-            border: none;
-            width: 240px;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-            background-repeat: no-repeat;
-            background-position: 0 0;
-
-            @each $type, $icon in $element-icons {
-                &.description-icon-#{$type} {
-                    width: 212px;
-                    padding-left: 28px;
-                    @include background-icon(#{$icon}, info_alt, 22);
-                }
-            }
-        }
-
-        .progress-wrapper {
-            width: 100%;
-            padding: 1em 0;
-            border: none;
-            background: none;
-
-            progress {
-                appearance: none;
-                display: block;
-                width: 100%;
-                height: 3px;
-                margin: 0;
-                border: none;
-                background: rgba(0,0,0,0.3);
-                &::-webkit-progress-bar {
-                    background:  rgba(0,0,0,0.3);
-                }
-                &::-webkit-progress-value {
-                    background: white;
-                }
-                &::-moz-progress-bar {
-                    background: white;
-                }
-            }
-        }
-
-        .description-text-wrapper {
-            overflow: hidden;
-            height: 10em;
-            margin-top: 0.5em;
-            display: -webkit-box;
-            margin-bottom: 1em;
-            -webkit-line-clamp: 7;
-            -webkit-box-orient: vertical;
-            p {
-                text-align: left;
-            }
-        }
-
-        footer {
-            width: 242px;
-            text-align: right;
-            color: var(--white);
-            white-space: nowrap;
-            overflow: hidden;
-            text-overflow: ellipsis;
-
-            img {
-                vertical-align: text-bottom;
-            }
-        }
-    }
-
-    a[href].description {
-        transition: unset;
-    }
-
-    a.description,
-    a.description:link,
-    a.description:visited,
-    a.description:hover {
-        height: 210px;
-        color: var(--white);
-        text-decoration: unset;
-    }
-}
-/*
-cw tiles end
-*/
-
-/* courseware template preview */
-.cw-template-preview {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-    width: calc(100% - 20px);;
-    padding: 10px;
-    .cw-template-preview-container-wrapper {
-        margin-bottom: 10px;
-
-        &.cw-template-preview-container-full {
-            width: 100%
-        }
-        &.cw-template-preview-container-half {
-            width: calc(50% - 4px);
-        }
-        &.cw-template-preview-container-half-center {
-            width: 100%;
-            .cw-template-preview-container-content {
-                width: 50%;
-                margin: auto;
-            }
-        }
-
-        .cw-template-preview-container-content {
-            border: solid thin var(--content-color-40);
-        }
-
-        .cw-template-preview-container-title {
-            font-weight: 700;
-            padding: 4px 4px 4px 8px;
-            color: var(--base-color);
-            background-color: var(--content-color-20);
-        }
-
-        .cw-template-preview-blocks {
-            border: solid thin var(--content-color-40);
-            padding: 1em;
-            margin: 5px;
-            background-color: var(--white);
-
-        }
-    }
-}
-/* courseware template preview end*/
-
-/* * * * * * * * * *
- i n p u t  f i l e
-* * * * * * * * * */
- .cw-file-input {
-     width: stretch;
-     border: solid thin var(--base-color);
-     font-size: 14px;
-    cursor: pointer;
-
-    &::file-selector-button {
-        font-family: inherit;
-        border: none;
-        border-right: solid thin var(--base-color);
-        background-color: var(--white);
-        padding: 6px 15px;
-        margin-right: 10px;
-        color: var(--base-color);
-
-        &:hover {
-            background-color: var(--base-color);
-            color: var(--white);
-        }
-     }
- }
- .cw-file-input-change {
-    border: solid thin var(--base-color);
-
-    button.button {
-        padding: 0.5em 1.5em;
-        margin: 0 0 0 -1px;
-        line-height: 100%;
-        border: none;
-        border-right: solid thin var(--base-color);
-    }
-    span {
-        padding: 0.5em 1.5em 0.5em 0.5em;
-    }
- }
- /* * * * * * * * * * * * *
- i n p u t  f i l e  e n d
-* * * * * * * * * * * * * */
-
-/* * * * * * * * * * * *
-p u b l i c  l i n k s
-* * * * * * * * * * * */
-.cw-public-link-clipboard-button {
-    width: 16px;
-    height: 16px;
-    margin-left: 0.5em;
-    background-color: transparent;
-    border: none;
-    vertical-align: text-bottom;
-    @include background-icon(clipboard, clickable, 16);
-    cursor: pointer;
-
-}
-/* * * * * * * * * * * * * * *
-e n d  p u b l i c  l i n k s
-* * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * *
-a s s i s t i v e
-* * * * * * * * * * * */
-.assistive-text {
-    position: absolute;
-    margin: -1px;
-    border: 0;
-    padding: 0;
-    width: 1px;
-    height: 1px;
-    overflow: hidden;
-    clip: rect(0 0 0 0);
-  }
-/* * * * * * * * * * * * * * *
-e n d  a s s i s t i v e
-* * * * * * * * * * * * * * */
-
-/* * * * * * * * * * * * * * *
-w i z a r d  e l e m e n t s
-* * * * * * * * * * * * * * */
-.cw-element-selector-list {
-    list-style: none;
-    padding: 0;
-
-    .cw-element-selector-item {
-        display: block;
-        width: 100%;
-        border: solid thin var(--content-color-40);
-        padding: 0.5em;
-        margin-bottom: 5px;
-        background-color: var(--white);
-        color: var(--base-color);
-        text-align: left;
-        cursor: pointer;
-
-        &:hover {
-            color: var(--white);
-            background-color: var(--base-color);
-        }
-    }
-}
-form.default .courseware-structural-element-selector {
-    list-style: none;
-    padding-left: 0;
-    .courseware-structural-element-selector-item {
-        .radiobutton {
-            background: none;
-            border: none;
-            padding: 0;
-        }
-        a label {
-            cursor: pointer;
-        }
-        label {
-            display: inline-block;
-            margin-bottom: 0;
-            text-indent: 0;
-            vertical-align: middle;
-        }
-        img {
-            vertical-align: middle;
-            &.inactive {
-                opacity: 0.5;
-            }
-        }
-        ul {
-            list-style: none;
-            padding-left: 18px;
-        }
-    }
-}
-/* * * * * * * * * * * * * * * * * *
-w i z a r d  e l e m e n t s  e n d
-* * * * * * * * * * * * * * * * * */
-
-
-/* * * * * * * * * * * * * * *
-s h e l f  i t e m s
-* * * * * * * * * * * * * * */
-.cw-unit-items,
-.cw-shared-items {
-    margin-bottom: 10px;
-    h2 {
-        margin-top: 0;
-    }
-}
-/* * * * * * * * * * * * * * * * * *
-s h e l f  i t e m s  e n d
-* * * * * * * * * * * * * * * * * */
-
-/* * * * * * * * *
-r a d i o s e t
-* * * * * * * * */
-
-.cw-radioset {
-    display: flex;
-    flex-direction: row;
-    justify-content: center;
-    margin-bottom: 1em;
-    .cw-radioset-box {
-        width: 128px;
-        height: 128px;
-        text-align: center;
-        margin-right: 16px;
-        border: solid thin var(--content-color-40);
-        &.selected {
-            border-color: var(--base-color);
-            background-color: var(--content-color-20);
-        }
-        &:last-child {
-            margin-right: 0;
-        }
-        label {
-            height: 100%;
-            width: 100%;
-            margin: 0;
-            cursor: pointer;
-            .label-icon {
-                background-position: center 8px;
-                background-repeat: no-repeat;
-                height: 64px;
-                padding: 8px;
-                &.accordion {
-                    @include background-icon(block-accordion, clickable, 64);
-                }
-                &.list {
-                    @include background-icon(view-list, clickable, 64);
-                }
-                &.tabs {
-                    @include background-icon(block-tabs, clickable, 64);
-                }
-                &.full {
-                    @include background-icon(column-full, clickable, 64);
-                }
-                &.half {
-                    @include background-icon(column-half, clickable, 64);
-                }
-                &.half-center {
-                    @include background-icon(column-half-centered, clickable, 64);
-                }
-            }
-
-        }
-        input[type=radio] {
-            position: absolute;
-            opacity: 0;
-            width: 0;
-
-            &:focus + label {
-                outline-color: Highlight;
-                outline-color: -webkit-focus-ring-color;
-                outline-style: auto;
-                outline-width: 1px;
-            }
-        }
-    }
-}
-
-/* * * * * * * * * * * *
-r a d i o s e t  e n d 
-* * * * * * * * * * * */
-/* * * * * * * * * * * * * * * *
-c o m m e n t s  o v e r v i e w
-* * * * * * * * * * * * * * * */
-
-.cw-comments-overview-dialog-comments-context {
-    margin: 0 0 1.5em 0;
-}
-
-/* * * * * * * * * * * * * * * * * * * *
-c o m m e n t s  o v e r v i e w  e n d
-* * * * * * * * * * * * * * * * * * * */
-
-#course-courseware-index,
-#contents-courseware-index,
-#course-courseware-courseware,
-#contents-courseware-courseware {
-    form.default input[type=date] {
-        max-width: 9em;
-    }
-}
+@import './courseware/variables.scss';
+
+@import './courseware/a11y.scss';
+@import './courseware/blockadder.scss';
+@import './courseware/comments.scss';
+@import './courseware/content-courses.scss';
+@import './courseware/dashboard.scss';
+@import './courseware/sortable.scss';
+@import './courseware/widgets.scss';
+@import './courseware/wizards.scss';
+
+@import './courseware/shelf.scss';
+@import './courseware/structural-element.scss';
+@import './courseware/containers/default-container.scss';
+@import './courseware/blocks/default-block.scss';
+
+@import './courseware/layouts/collapsible.scss';
+@import './courseware/layouts/companion.scss';
+@import './courseware/layouts/import-zip.scss';
+@import './courseware/layouts/input-file.scss';
+@import './courseware/layouts/progress.scss';
+@import './courseware/layouts/ribbon.scss';
+@import './courseware/layouts/tabs.scss';
+@import './courseware/layouts/talk-bubble.scss';
+@import './courseware/layouts/tile.scss';
+@import './courseware/layouts/tree.scss';
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/a11y.scss b/resources/assets/stylesheets/scss/courseware/a11y.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b887e74f9000f93dab001ddf38b91180c7ffad7e
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/a11y.scss
@@ -0,0 +1,10 @@
+.assistive-text {
+    position: absolute;
+    margin: -1px;
+    border: 0;
+    padding: 0;
+    width: 1px;
+    height: 1px;
+    overflow: hidden;
+    clip: rect(0 0 0 0);
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blockadder.scss b/resources/assets/stylesheets/scss/courseware/blockadder.scss
new file mode 100644
index 0000000000000000000000000000000000000000..12a43a9b2d74e728239a8e8a029bbefed62cfd50
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blockadder.scss
@@ -0,0 +1,319 @@
+.cw-tools-element-adder-tabs {
+    .cw-tabs-nav {
+        margin-top: 4px;
+        border: none;
+        border-bottom: solid thin var(--content-color-40);
+
+        button {
+            max-width: unset;
+            padding: 1em 1.5em 4px 1.5em;
+            margin: 0px 2em;
+        }
+    }
+    .cw-tabs-content {
+        border: none;
+        overflow-x: hidden;
+        overflow-y: auto;
+        scrollbar-width: thin;
+        scrollbar-color: var(--base-color) var(--dark-gray-color-5);
+
+        .input-group.files-search {
+            &.search {
+                border: thin solid var(--dark-gray-color-30);
+                margin-bottom: 0px;
+                input {
+                    border: none;
+                }
+            }
+
+            .input-group-append {
+                .button {
+                    border: none;
+                    border-left: thin solid var(--dark-gray-color-30);
+                    &.active {
+                        background-color: var(--base-color);
+                    }
+                }
+                .reset-search {
+                    border: none;
+                    background-color: var(--white);
+                }
+            }
+
+            .active-filter {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                border: solid thin var(--black);
+                background-color: var(--content-color-10);
+                margin: 3px;
+                padding: 2px 3px;
+
+                .removefilter {
+                    border: none;
+                    background-color: transparent;
+                }
+            }
+        }
+
+        .cw-block-search {
+            width: inherit;
+        }
+
+        .filterpanel {
+            margin-bottom: 5px;
+            padding: 2px;
+            border: thin solid var(--dark-gray-color-30);
+            border-top: none;
+            background-color: var(--white);
+
+            .button {
+                min-width: inherit;
+                margin: 4px 2px;
+
+                &.button-active {
+                    background-color: var(--base-color);
+                    color: var(--white);
+                }
+            }
+        }
+    }
+
+    .cw-collapsible {
+        .cw-collapsible-content {
+            display: none;
+            &.cw-collapsible-content-open {
+                display: block;
+            }
+        }
+    }
+}
+
+.cw-element-adder-wrapper {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+}
+.cw-blockadder-item-list {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+    grid-auto-rows: auto;
+    grid-gap: 4px;
+
+    .cw-blockadder-item-wrapper {
+        display: flex;
+        border: solid thin var(--content-color-40);
+        max-width: 254px;
+
+        &:hover {
+            border-color: var(--base-color);
+        }
+        .cw-blockadder-item {
+            padding: 64px 10px 4px 10px;
+            @include background-icon(unit-test, clickable, 48);
+            background-position: 10px 10px;
+            background-repeat: no-repeat;
+            cursor: pointer;
+
+            @each $item, $icon in $blockadder-items {
+                &.cw-blockadder-item-#{$item} {
+                    @include background-icon($icon, clickable, 48);
+                }
+            }
+            .cw-clipboard-item-title,
+            .cw-blockadder-item-title {
+                display: inline-block;
+                font-weight: 600;
+                margin-bottom: 2px;
+            }
+            .cw-blockadder-item-description {
+                display: inline-block;
+                margin: 0 0 4px;
+            }
+        }
+        .cw-blockadder-item-fav {
+            height: 32px;
+            padding: 8px;
+            background-color: transparent;
+            border: none;
+            cursor: pointer;
+        }
+    }
+}
+
+.cw-block-adder-area {
+    background-color: var(--white);
+    border: solid thin var(--content-color-40);
+    padding: 1em 0;
+    color: var(--base-color);
+    text-align: center;
+    width: 100%;
+    font-weight: 600;
+    cursor: pointer;
+
+    &:hover {
+        border-color: var(--base-color);
+    }
+
+    &.cw-block-adder-active {
+        border: solid thin var(--base-color);
+        background-color: var(--base-color);
+        color: var(--white);
+    }
+
+    img {
+        vertical-align: text-bottom;
+    }
+}
+.cw-block-helper-buttons {
+    display: inline-block;
+    width: 100%;
+
+    .cw-block-helper-reset {
+        float: right;
+    }
+
+    .button.cw-block-helper-reset::before {
+        content: '';
+        @include background-icon(refresh);
+        background-repeat: no-repeat;
+        float: left;
+        height: 16px;
+        width: 16px;
+        margin: 1px 5px 0 -8px;
+    }
+}
+
+.cw-block-helper-results {
+    margin-top: 5px;
+}
+
+.cw-containeradder-item {
+    margin-bottom: 4px;
+    padding: 1em 1em 1em 6em;
+    @include background-icon(unit-test, clickable, 48);
+    background-position: 12px center;
+    background-repeat: no-repeat;
+    border: solid thin var(--content-color-40);
+    cursor: pointer;
+
+    &:hover {
+        border-color: var(--base-color);
+    }
+
+    @each $item, $icon in $containeradder-items {
+        &.cw-containeradder-item-#{$item} {
+            @include background-icon($icon, clickable, 48);
+        }
+    }
+
+    .cw-containeradder-item-title {
+        font-weight: 600;
+    }
+}
+
+.cw-container-style-selector {
+    display: flex;
+    margin-bottom: 8px;
+
+    label {
+        border: solid thin var(--content-color-40);
+        padding: calc(0.5em + 32px) 1em 0.5em 1em;
+        color: var(--base-color);
+        text-align: center;
+        width: 33%;
+        background-position: center 0.5em;
+        background-repeat: no-repeat;
+        cursor: pointer;
+
+        &.full {
+            @include background-icon(column-full, clickable, 32);
+        }
+        &.half {
+            @include background-icon(column-half, clickable, 32);
+        }
+        &.half-center {
+            @include background-icon(column-half-centered, clickable, 32);
+        }
+        &:hover {
+            color: var(--active-color);
+        }
+        &:not(:first-child) {
+            border-left: solid thin transparent;
+        }
+        &.cw-container-style-selector-active {
+            background-color: var(--content-color-20);
+            border: solid thin var(--base-color);
+        }
+
+    }
+    input[type=radio] {
+        position: absolute;
+        opacity: 0;
+        width: 0;
+
+        &:focus + label {
+            outline-color: Highlight;
+            outline-color: -webkit-focus-ring-color;
+            outline-style: auto;
+            outline-width: 1px;
+        }
+    }
+}
+.cw-element-inserter-wrapper {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+}
+
+
+.cw-clipboard-item-wrapper {
+    display: flex;
+    width: calc(50% - 4px);
+    border: solid thin var(--content-color-40);
+    margin-bottom: 4px;
+
+    &:hover {
+        border-color: var(--base-color);
+    }
+
+    .cw-clipboard-item {
+        width: 207px;
+        padding: 64px 10px 4px 10px;
+        @include background-icon(unit-test, clickable, 48);
+        background-position: 10px 10px;
+        background-repeat: no-repeat;
+        cursor: pointer;
+        background-color: var(--white);
+        border: none;
+        text-align: left;
+        color: var(--base-color);
+
+        @each $item, $icon in $blockadder-items {
+            &.cw-clipboard-item-#{$item} {
+                @include background-icon($icon, clickable, 48);
+            }
+        }
+        @each $item, $icon in $containeradder-items {
+            &.cw-clipboard-item-#{$item} {
+                @include background-icon($icon, clickable, 48);
+            }
+        }
+    
+        .cw-clipboard-item-title {
+            display: inline-block;
+            font-weight: 600;
+            margin-bottom: 2px;
+        }
+
+    }
+    .cw-clipboard-item-action-menu-wrapper {
+        padding: 8px;
+    }
+}
+.action-menu.is-open,
+.action-menu-wrapper.is-open {
+    &.cw-clipboard-item-action-menu {
+        z-index: 42;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/audio.scss b/resources/assets/stylesheets/scss/courseware/blocks/audio.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c5c530ed72607dd1cfbf161351fa01b34f246f6a
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/audio.scss
@@ -0,0 +1,231 @@
+@use '../../../mixins.scss' as *;
+
+$media-buttons: (
+    play: play,
+    stop: stop,
+    pause: pause,
+    prev: arr_eol-left,
+    next: arr_eol-right
+);
+
+.cw-block-audio {
+    .cw-audio-container {
+        border: solid thin var(--content-color-40);
+        padding-top: 1em;
+    }
+    .cw-audio-controls {
+        text-align: right;
+        padding: 0 0.5em;
+    }
+    .cw-audio-range {
+        margin: 0 5px 10px 0;
+        &::-moz-focus-outer {
+            border: 0;
+        }
+        &.ui-widget-content {
+            background-color: var(--base-color);
+        }
+        .ui-widget-header {
+            background-color: var(--dark-gray-color-5);
+        }
+        .ui-slider-handle {
+            border-radius: 20px;
+            width: 1em;
+            height: 1.7em;
+            top: -0.5em;
+            background-color: var(--dark-gray-color-20);
+            border-color: var(--content-color-40);
+            cursor: pointer;
+            margin-left: -2px;
+        }
+    }
+    .cw-audio-button {
+        border: solid thin var(--content-color-40);
+        background-color: var(--white);
+        background-repeat: no-repeat;
+        background-position: center center;
+        background-size: 24px;
+        min-height: 27px;
+        line-height: 130%;
+        padding: 5px 15px 5px 30px;
+        cursor: pointer;
+        font-size: 14px;
+        box-sizing: border-box;
+        text-align: center;
+        text-decoration: none;
+        vertical-align: bottom;
+        white-space: nowrap;
+        min-width: unset;
+        margin: 5px;
+        height: 46px;
+        width: 46px;
+        display: inline-block;
+
+        &:hover {
+            background-color: var(--base-color);
+        }
+
+        @each $button, $icon in $media-buttons {
+            &.cw-audio-#{$button}button {
+                @include background-icon($icon, clickable, 24);
+                &:hover {
+                    @include background-icon($icon, info-alt, 24);
+                }
+            }
+        }
+    }
+
+    .cw-audio-time {
+        position: relative;
+        top: -1em;
+        color: var(--base-gray);
+    }
+
+    .cw-audio-range {
+        display: block;
+        margin: 0 auto 1.5em;
+        -webkit-appearance: none;
+        position: relative;
+        overflow: hidden;
+        height: 18px;
+        width: 100%;
+        cursor: pointer;
+        border-radius: 0;
+    }
+
+    .cw-audio-range::-webkit-slider-runnable-track {
+        background: var(--dark-gray-color-20);
+    }
+
+    .cw-audio-range::-webkit-slider-thumb {
+        -webkit-appearance: none;
+        width: 9px; /* 1 */
+        height: 18px;
+        background: var(--white);
+        box-shadow: -100vw 0 0 100vw var(--base-color);
+        border: solid thin var(--content-color-40);
+    }
+
+    .cw-audio-range::-moz-range-track {
+        height: 18px;
+        background: var(--dark-gray-color-10);
+    }
+
+    .cw-audio-range::-moz-range-thumb {
+        background: var(--white);
+        height: 18px;
+        width: 9px;
+        border: solid thin var(--content-color-40);
+        border-radius: 0 !important;
+        box-shadow: -100vw 0 0 100vw var(--base-color);
+        box-sizing: border-box;
+    }
+
+    .cw-audio-range::-ms-fill-lower {
+        background: var(--base-color);
+    }
+
+    .cw-audio-range::-ms-thumb {
+        background: var(--white);
+        border: solid thin var(--content-color-40);
+        height: 18px;
+        width: 9px;
+        box-sizing: border-box;
+    }
+
+    .cw-audio-range::-ms-ticks-after {
+        display: none;
+    }
+
+    .cw-audio-range::-ms-ticks-before {
+        display: none;
+    }
+
+    .cw-audio-range::-ms-track {
+        background: var(--dark-gray-color-20);
+        color: transparent;
+        height: 18px;
+        border: none;
+    }
+
+    .cw-audio-range::-ms-tooltip {
+        display: none;
+    }
+    .cw-audio-playlist-wrapper {
+        margin-top: -1em;
+        padding-top: 1em;
+        border: solid thin var(--content-color-40);
+        border-top: none;
+
+        &.empty {
+            border: none;
+        }
+
+        .cw-audio-playlist {
+            padding-left: 0;
+            list-style: none;
+            cursor: pointer;
+
+            &.with-recorder {
+                border-bottom: solid thin var(--content-color-40);
+            }
+
+            li {
+                margin: 0 1em;
+                &:not(:last-child) {
+                    border-bottom: solid thin var(--dark-gray-color-30);
+                }
+
+                .cw-playlist-item {
+                    display: block;
+                    @include background-icon(file-audio2, clickable, 24);
+                    background-repeat: no-repeat;
+                    background-position: 1em center;
+
+                    margin: 1em 0;
+                    padding: 1em;
+                    padding-left: 4em;
+                    color: var(--base-color);
+                    &:hover {
+                        color: var(--active-color);
+                    }
+                    &.current-item {
+                        @include background-icon(play, clickable, 24);
+                        font-weight: 700;
+                        &.is-playing {
+                            @include background-icon(pause, clickable, 24);
+                        }
+                    }
+                }
+            }
+        }
+        .cw-audio-playlist-recorder {
+            padding: 1em;
+        }
+    }
+
+    .cw-audio-current-track {
+        @include background-icon(file-audio2, info, 96);
+        background-position: top center;
+        background-repeat: no-repeat;
+        width: 100%;
+        min-height: 140px;
+        margin: 1em 0 2em 0;
+        p {
+            text-align: center;
+            padding-top: 106px;
+        }
+    }
+    .cw-audio-empty {
+        @include background-icon(file, info, 96);
+        border: solid thin var(--content-color-40);
+        background-position: center 1em;
+        background-repeat: no-repeat;
+        min-height: 140px;
+        padding: 1em;
+        p {
+            text-align: center;
+            padding-top: 106px;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/biography.scss b/resources/assets/stylesheets/scss/courseware/blocks/biography.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a40239bc3f34495633ef2ae4b0a139f6105e4dad
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/biography.scss
@@ -0,0 +1,82 @@
+@use '../../../mixins.scss' as *;
+
+$achievement-types: (
+    certificate: file-text,
+    accreditation: vcard,
+    award: medal,
+    book: literature,
+    publication: news,
+    membership: group3,
+);
+
+$goals-types: (
+    personal: person2,
+    school: doctoral-cap,
+    academic: doctoral-cap,
+    professional: tools,
+);
+
+.cw-block-biography {
+    .cw-block-biography-content {
+        display: flex;
+        min-height: 200px;
+        flex-direction: row;
+        padding: 2em 2em 2em 1em;
+        border: 2px solid var(--base-color);
+
+        .cw-block-biography-type {
+            margin: auto 1em auto 0;
+            padding-top: 96px;
+            min-width: 192px;
+            max-width: 192px;
+            text-align: center;
+            background-repeat: no-repeat;
+            background-position: center top;
+        }
+
+        .cw-block-biography-details {
+            h2, h3 {
+                margin-top: 0;
+            }
+        }
+
+    }
+}
+
+.cw-block-biography-achievements {
+    @each $type, $icon in $achievement-types {
+        .cw-block-biography-achievements-type-#{$type} {
+            @include background-icon($icon, clickable, 96);
+        }
+    }
+}
+
+.cw-block-biography-goals {
+    @each $type, $icon in $goals-types {
+        .cw-block-biography-goals-type-#{$type} {
+            @include background-icon($icon, clickable, 96);
+        }
+    }
+}
+
+.cw-block-biography-personal-information {
+    .cw-block-biography-content {
+        min-height: 140px;
+
+        .cw-block-biography-personal-information-type {
+            @include background-icon(person2, clickable, 96);
+        }
+
+        .cw-block-biography-personal-information-details {
+            display: grid;
+            max-height: 7em;
+            grid-template-columns: max-content 1fr;
+            grid-gap: 5px 10px;
+
+            .preface {
+                grid-column-start: 1;
+                grid-column-end: 3;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/canvas.scss b/resources/assets/stylesheets/scss/courseware/blocks/canvas.scss
new file mode 100644
index 0000000000000000000000000000000000000000..acfd935a8403b2f930c9750a5eb204e6283e6e4e
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/canvas.scss
@@ -0,0 +1,145 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-canvas {
+    .cw-canvasblock-canvas {
+        max-width: 100%;
+        border: solid thin var(--content-color-40);
+    }
+
+    .cw-canvasblock-upload-message {
+        display: none;
+    }
+
+    .cw-canvasblock-original-img {
+        display: none;
+    }
+
+    .cw-canvasblock-tool-selected-text {
+        cursor: text;
+    }
+
+    h1.cw-canvasblock-description {
+        border-bottom: none;
+    }
+
+    .cw-canvasblock-toolbar {
+        border: solid thin var(--content-color-40);
+        border-bottom: none;
+
+        .cw-canvasblock-buttonset {
+            display: inline-block;
+            padding: 5px;
+            margin-right: 0.5em;
+
+            button {
+                cursor: pointer;
+                user-select: none;
+                border: solid thin var(--content-color-40);
+                height: 32px;
+                width: 32px;
+                background-color: var(--white);
+                background-position: center;
+                background-repeat: no-repeat;
+                background-size: 24px 24px;
+
+                &.cw-canvasblock-color {
+                    $colors: (
+                        white: var(--white),
+                        blue: #3498db,
+                        green: #2ecc71,
+                        purple: #9b59b6,
+                        red: #e74c3c,
+                        yellow: #fed330,
+                        orange: #f39c12,
+                        grey: #95a5a6,
+                        darkgrey: #34495e,
+                        black: var(--black),
+                    );
+
+                    @each $name, $color in $colors {
+                        &.#{'' + $name} {
+                            background-color: $color;
+                        }
+                    }
+
+                    &.selected-color {
+                        border: solid 2px var(--black);
+                    }
+                }
+
+                &.cw-canvasblock-reset {
+                    @include background-icon(refresh, clickable, 24);
+                }
+
+                &.cw-canvasblock-size {
+                    @include background-icon(stop, clickable);
+
+                    &.cw-canvasblock-size-small {
+                        background-size: 8px 7px;
+                    }
+                    &.cw-canvasblock-size-normal {
+                        background-size: 16px 14px;
+                    }
+                    &.cw-canvasblock-size-large {
+                        background-size: 22px 20px;
+                    }
+                    &.cw-canvasblock-size-huge {
+                        background-size: 26px 24px;
+                    }
+                    &.selected-size {
+                        border: solid 2px var(--black);
+                    }
+                }
+
+                &.cw-canvasblock-tool {
+                    &.cw-canvasblock-tool-pen {
+                        @include background-icon(comment, clickable);
+                    }
+
+                    &.cw-canvasblock-tool-text {
+                        vertical-align: top;
+                        font-size: 22px;
+                        color: var(--base-color);
+                        font-weight: 600;
+                    }
+
+                    &.selected-tool {
+                        border: solid 2px var(--black);
+                    }
+                }
+
+                &.cw-canvasblock-undo {
+                    @include background-icon(arr_2left, clickable, 24);
+                }
+
+                &.cw-canvasblock-download {
+                    @include background-icon(download, clickable, 24);
+                }
+
+                &.cw-canvasblock-store {
+                    @include background-icon(upload, clickable, 24);
+                }
+
+                &.cw-canvasblock-show-all {
+                    @include background-icon(group2, clickable, 24);
+
+                    &.selected-view {
+                        border: solid 2px var(--black);
+                    }
+                }
+
+                &.cw-canvasblock-show-own {
+                    @include background-icon(person, clickable, 24);
+
+                    &.selected-view {
+                        border: solid 2px var(--black);
+                    }
+                }
+            }
+        }
+    }
+
+    .cw-canvasblock-tool-selected-text {
+        cursor: text;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/code.scss b/resources/assets/stylesheets/scss/courseware/blocks/code.scss
new file mode 100644
index 0000000000000000000000000000000000000000..ac401cf45411d0dc75093505ac17e7959214cb74
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/code.scss
@@ -0,0 +1,88 @@
+.cw-block-code {
+    pre {
+        margin-bottom: 0;
+    }
+
+    .hljs {
+        display: block;
+        overflow-x: auto;
+        padding: 0.5em;
+        background: var(--dark-gray-color-5);
+        color: black;
+        border: solid thin var(--content-color-40);
+    }
+
+    .hljs-comment,
+    .hljs-quote,
+    .hljs-variable {
+        color: var(--dark-green);
+    }
+
+    .hljs-keyword,
+    .hljs-selector-tag,
+    .hljs-selector-class,
+    .hljs-built_in,
+    .hljs-name,
+    .hljs-tag {
+        color: var(--base-color);
+        font-weight: 600;
+    }
+
+    .hljs-string,
+    .hljs-title,
+    .hljs-section,
+    .hljs-attribute,
+    .hljs-literal,
+    .hljs-template-tag,
+    .hljs-template-variable,
+    .hljs-type,
+    .hljs-addition {
+        color: var(--orange-80);
+        font-weight: 400;
+    }
+
+    .hljs-deletion,
+    .hljs-selector-attr,
+    .hljs-selector-pseudo,
+    .hljs-meta {
+        color: var(--petrol);
+        font-weight: 400;
+    }
+
+    .hljs-doctag {
+        color: var(--dark-gray-color-75);
+        font-weight: 400;
+    }
+
+    .hljs-attr {
+        color: var(--active-color);
+        font-weight: 400;
+    }
+
+    .hljs-symbol,
+    .hljs-bullet,
+    .hljs-link {
+        color: var(--petrol);
+        font-weight: 400;
+    }
+
+    .hljs-emphasis {
+        font-style: italic;
+        font-weight: 400;
+    }
+
+    .hljs-strong {
+        font-weight: 600;
+    }
+
+    .code-lang {
+        background: var(--dark-gray-color-5);
+        border: solid thin var(--content-color-40);
+        border-top: none;
+        padding: 5px 10px;
+        text-align: right;
+        color: var(--dark-gray-color-45);
+        font-family: monospace;
+        text-transform: full-width;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/confirm.scss b/resources/assets/stylesheets/scss/courseware/blocks/confirm.scss
new file mode 100644
index 0000000000000000000000000000000000000000..0c236fc7fdbe328e3bce55c896a933025a93442c
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/confirm.scss
@@ -0,0 +1,12 @@
+.cw-block-confirm {
+    .cw-block-confirm-content {
+        border: solid thin var(--content-color-40);
+        padding: 1em;
+        margin: 0;
+
+        input[type='checkbox'] {
+            margin-right: 2em;
+            vertical-align: bottom;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/date.scss b/resources/assets/stylesheets/scss/courseware/blocks/date.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f2cde08896ef9a1f6ec9f1d7691e267986d76e45
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/date.scss
@@ -0,0 +1,79 @@
+.cw-container-colspan-half,
+.cw-container-colspan-half-center {
+    .cw-block-date {
+        .cw-block-content {
+            font-size: 9px;
+        }
+    }
+}
+
+.cw-block-date {
+    .cw-date-countdown,
+    .cw-date-date {
+        margin: 0 auto;
+        width: max-content;
+    }
+
+    .cw-date-countdown {
+        .cw-date-countdown-digit {
+            display: inline-block;
+            margin-right: 4px;
+
+            .cw-date-countdown-number {
+                font-size: 6em;
+                line-height: 1.25em;
+                height: 1.25em;
+                padding: 3px 0.5em;
+                background: rgba(245, 245, 245, 1);
+                font-weight: 300;
+            }
+
+            .cw-date-countdown-label-sg,
+            .cw-date-countdown-label-pl {
+                padding: 5px;
+                font-size: 1.25em;
+                text-align: left;
+                text-transform: uppercase;
+            }
+        }
+    }
+
+    .cw-date-date {
+        .cw-date-date-space {
+            display: inline-block;
+            width: 2em;
+        }
+
+        .cw-date-date-digits {
+            display: inline-block;
+
+            .cw-date-date-number {
+                font-size: 5em;
+                line-height: 1.25em;
+                height: 1.25em;
+                padding: 0.25em;
+                background: rgba(245, 245, 245, 1);
+                font-weight: 300;
+            }
+        }
+    }
+}
+
+.responsive-display {
+    .cw-block-date {
+        .cw-block-content {
+            font-size: 9px;
+
+            .cw-date-countdown-number {
+                font-size: 3.5em;
+            }
+            .cw-date-countdown-label-sg,
+            .cw-date-countdown-label-pl {
+                font-size: 1em;
+            }
+            .cw-date-date-number {
+                font-size: 3em;
+            }
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/default-block.scss b/resources/assets/stylesheets/scss/courseware/blocks/default-block.scss
new file mode 100644
index 0000000000000000000000000000000000000000..24c57511cfd6b86bbab9226f09b43e2e21f3bd80
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/default-block.scss
@@ -0,0 +1,134 @@
+.cw-default-block {
+    display: flex;
+    flex-flow: row;
+    .cw-default-block-invisible-info {
+        img {
+            vertical-align: text-bottom;
+        }
+    }
+
+}
+
+.cw-block-header {
+    background-color: var(--content-color-20);
+    padding: 4px 10px 4px 22px;
+
+    .cw-block-header-toggle {
+        display: inline-block;
+        width: calc(100% - 50px);
+    }
+
+    span {
+        color: var(--base-color);
+        font-weight: 700;
+        line-height: 2em;
+        font-size: 1.1em;
+
+        &.cw-default-block-invisible-info,
+        &.cw-default-block-blocker-warning {
+            font-weight: 400;
+        }
+    }
+
+    img {
+        vertical-align: text-bottom;
+    }
+
+    .cw-block-actions {
+        position: relative;
+        float: right;
+        margin-top: 4px;
+        .is-open{
+            z-index: 30;
+        }
+    }
+}
+
+.cw-discuss-wrapper,
+.cw-block-features {
+    header{
+        background-color: var(--content-color-20);
+        color: var(--base-color);
+        font-weight: 600;
+        padding: 0.5em;
+    }
+
+    .cw-block-features-content{
+        margin: 1em;
+    }
+}
+
+.cw-discuss-wrapper {
+    flex-shrink: 3;
+    flex-grow: 2;
+    margin-left: 10px;
+}
+
+.cw-block-edit textarea {
+    width: -moz-available;
+    height: -moz-available;
+    min-height: 8em;
+    border: solid thin var(--content-color-40);
+    resize: none;
+}
+
+.cw-block-actions {
+    padding-left: 14px;
+}
+.cw-button-box {
+    float: right;
+}
+
+.cw-content-wrapper {
+    display: flex;
+    flex-flow: column;
+    width: 100%;
+    .cw-block-content {
+        overflow: auto;
+        position: relative;
+    }
+}
+.cw-content-wrapper-active {
+    border: solid thin var(--content-color-40);
+    .cw-block-content {
+        padding: $cw-wrapper-gap;
+    }
+}
+
+
+.cw-container-wrapper-discuss {
+    .cw-container-colspan-full {
+        .cw-content-wrapper {
+            max-width: $max-content-width;
+        }
+    }
+    .cw-container-colspan-half,
+    .cw-container-colspan-half-center {
+        .cw-content-wrapper {
+            max-width: 540px;
+        }
+    }
+}
+
+.cw-block-title {
+    padding: 4px;
+    background-color: var(--content-color-20);
+    color: var(--base-color);
+    font-weight: 700;
+    text-align: center;
+    border: solid thin var(--content-color-40);
+    border-bottom: none;
+}
+
+.cw-file-empty {
+    @include background-icon(file, info, 96);
+    border: solid thin var(--content-color-40);
+    background-position: center 1em;
+    background-repeat: no-repeat;
+    min-height: 140px;
+    padding: 1em;
+    p {
+        text-align: center;
+        padding-top: 106px;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/dialog-cards.scss b/resources/assets/stylesheets/scss/courseware/blocks/dialog-cards.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e8ba46720e0fb485fc56130f8d2242747be1e0c0
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/dialog-cards.scss
@@ -0,0 +1,150 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-dialog-cards-content {
+    display: flex;
+
+    .cw-dialogcards {
+        flex-grow: 2;
+
+        .scene {
+            margin: 0 auto;
+            width: 440px;
+            height: 600px;
+            perspective: 880px;
+            display: none;
+
+            &.active {
+                display: block;
+                animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
+                transform: translate3d(0, 0, 0);
+                backface-visibility: hidden;
+                perspective: 1000px;
+            }
+        }
+
+        .card {
+            width: 100%;
+            height: 78%;
+            transition: transform 1s;
+            transform-style: preserve-3d;
+            cursor: pointer;
+            position: relative;
+            top: 11%;
+        }
+
+        .card.is-flipped {
+            transform: rotateY(180deg);
+        }
+
+        .card__face {
+            position: absolute;
+            width: 100%;
+            height: 100%;
+            color: var(--black);
+            text-align: center;
+            font-weight: bold;
+            font-size: 1.2em;
+            backface-visibility: hidden;
+            box-shadow: 0 2px 15px fade-out($black, 0.7);
+
+            img {
+                max-width: 380px;
+                max-height: 220px;
+                margin-top: 1em;
+            }
+
+            .cw-dialogcards-front-no-image {
+                @include background-icon(question, navigation, 150);
+            }
+
+            .cw-dialogcards-back-no-image {
+                @include background-icon(exclaim, navigation, 150);
+            }
+
+            .cw-dialogcards-front-no-image,
+            .cw-dialogcards-back-no-image {
+                width: 100%;
+                height: 180px;
+                margin-top: 2em;
+                background-repeat: no-repeat;
+                background-position-x: center;
+            }
+
+            p {
+                margin: 1em 3em 1em 4em;
+                padding-right: 1em;
+                overflow-y: auto;
+                max-height: 12em;
+                text-align: justify;
+            }
+        }
+
+        .card__face--front {
+            @include background-icon(arr_1right, clickable);
+            background-color: var(--white);
+            background-repeat: no-repeat;
+            background-position: 95% 95%;
+        }
+
+        .card__face--back {
+            @include background-icon(arr_1left, clickable);
+            background-color: var(--white);
+            background-repeat: no-repeat;
+            background-position: 5% 95%;
+            transform: rotateY(180deg);
+        }
+    }
+
+    .cw-dialogcards-navbutton {
+        color: transparent;
+        width: 35px;
+        height: 35px;
+        border-radius: 2px;
+        background-position: 50%;
+        background-repeat: no-repeat;
+        background-color: var(--base-color);
+        border: none;
+        display: block;
+        z-index: 4;
+        margin: auto 2px;
+        padding: 0;
+        cursor: pointer;
+
+        &.cw-dialogcards-prev {
+            @include background-icon(arr_1left, info-alt, 24);
+        }
+
+        &.cw-dialogcards-next {
+            @include background-icon(arr_1right, info-alt, 24);
+            right: 0;
+        }
+
+        &.cw-dialogcards-prev-disabled,
+        &.cw-dialogcards-next-disabled {
+            background-color: var(--light-gray-color-40);
+        }
+    }
+
+    @keyframes shake {
+        10%,
+        90% {
+            transform: translate3d(-1px, 0, 0);
+        }
+
+        20%,
+        80% {
+            transform: translate3d(2px, 0, 0);
+        }
+
+        30%,
+        50%,
+        70% {
+            transform: translate3d(-4px, 0, 0);
+        }
+
+        40%,
+        60% {
+            transform: translate3d(4px, 0, 0);
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/document.scss b/resources/assets/stylesheets/scss/courseware/blocks/document.scss
new file mode 100644
index 0000000000000000000000000000000000000000..fb230b2d52a4f22a9508196aa8daa00b38e4483f
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/document.scss
@@ -0,0 +1,176 @@
+.cw-block-document {
+    .cw-pdf-main-container {
+        width: calc(100% - 2px);
+        border: solid thin var(--content-color-40);
+
+        .cw-block-title {
+            border: none;
+            border-bottom: solid thin var(--content-color-40);
+        }
+    }
+    .cw-pdf-toolbar {
+        position: relative;
+        display: flex;
+        flex-direction: row;
+        justify-content: flex-start;
+        align-items: baseline;
+        align-content: space-around;
+        background-color: var(--content-color-20);
+        padding: 4px 8px;
+
+        button {
+            height: 100%;
+            margin: 0 2px 0 0;
+            padding: 4px;
+
+            &.active {
+                background-color: var(--base-color);
+            }
+        }
+
+        .cw-pdf-toolbar-left {
+            position: relative;
+            display: flex;
+            flex-direction: row;
+            justify-content: flex-start;
+            align-items: baseline;
+            align-content: space-between;
+            width: 33%;
+        }
+
+        .cw-pdf-toolbar-middle {
+            position: relative;
+            display: flex;
+            justify-content: center;
+            width: 34%;
+
+            .cw-pdf-zoom-buttons {
+                margin-right: 8px;
+
+                button {
+                    margin: 0;
+                    padding: 4px 0;
+                }
+            }
+        }
+
+        .cw-pdf-toolbar-right {
+            display: flex;
+            flex-direction: row;
+            justify-content: flex-end;
+            align-items: baseline;
+            align-content: space-between;
+            position: relative;
+            width: 33%;
+            margin-right: 4px;
+        }
+
+        .cw-pdf-page-nav {
+            margin: 0 4px;
+
+            button {
+                margin: 0;
+                padding: 4px 0;
+            }
+
+            .cw-pdf-page-num {
+                text-align: right;
+                width: 2em;
+            }
+        }
+
+        .cw-pdf-search-box {
+            position: absolute;
+            top: 33px;
+            left: 22px;
+            width: auto;
+            background-color: var(--content-color-20);
+            border-top: none;
+            padding: 6px;
+            z-index: 2;
+            line-height: normal;
+
+            .cw-pdf-search-num {
+                margin: 4px 0 0 0;
+                display: block;
+            }
+
+            .cw-pdf-search-navs {
+                display: inline-block;
+
+                button {
+                    margin: 0;
+                    padding: 0;
+                }
+            }
+        }
+    }
+
+    .cw-pdf-outer-container {
+        position: relative;
+        width: 100%;
+
+        .cw-pdf-content {
+            display: flex;
+            flex-direction: row;
+
+            .cw-pdf-sidebar {
+                width: 25%;
+                min-width: 270px;
+                align-self: stretch;
+                background-color: var(--white);
+                border-right: solid 1px var(--content-color-40);
+
+                ul.cw-pdf-toc-list,
+                ul.cw-pdf-toc-sub-list {
+                    padding: 0;
+                    list-style: none;
+
+                    li {
+                        padding: 0.5em 1em;
+                    }
+                }
+
+                ul.cw-pdf-toc-list {
+                    margin-top: 1em;
+                }
+            }
+
+            .cw-pdf-viewer-container {
+                width: 100%;
+                height: 100%;
+                overflow: hidden;
+                cursor: text;
+
+                &.hand-cursor-grab {
+                    cursor: grab;
+
+                    &.grabbing {
+                        cursor: grabbing;
+                    }
+                }
+
+                &.has-error {
+                    display: none;
+                }
+
+                .page {
+                    position: relative;
+                    margin: 0 auto;
+                }
+            }
+        }
+
+        .cw-pdf-viewer-fake-container {
+            position: absolute;
+        }
+
+        .cw-pdf-error-page {
+            overflow: hidden;
+            width: calc(100% - 16px);
+            height: 100%;
+            padding: 8px;
+            display: table;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/embed.scss b/resources/assets/stylesheets/scss/courseware/blocks/embed.scss
new file mode 100644
index 0000000000000000000000000000000000000000..094afca083a0a77a989e289c0a889eef835b2e6e
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/embed.scss
@@ -0,0 +1,15 @@
+.cw-block-embed {
+    .cw-block-content {
+        .cw-block-embed-iframe-wrapper {
+            overflow-y: hidden;
+
+            iframe {
+                height: 100% !important;
+                width: 100% !important;
+            }
+        }
+        .cw-block-embed-info {
+            margin-top: 0.5em;
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/files.scss b/resources/assets/stylesheets/scss/courseware/blocks/files.scss
new file mode 100644
index 0000000000000000000000000000000000000000..7bc97270f540988d9cf6df1bf15a03e446ac14b3
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/files.scss
@@ -0,0 +1,192 @@
+@use '../../../mixins.scss' as *;
+
+// folder block
+.cw-block-folder-info {
+    border: solid thin var(--content-color-40);
+    padding: 10px 10px 0 10px;
+    overflow: hidden;
+    border-bottom: none;
+}
+
+.cw-block-folder-list {
+    border: solid thin var(--content-color-40);
+    padding: 0;
+    list-style: none;
+
+    .cw-block-folder-file-item {
+        list-style: none;
+
+        &:not(:last-child) {
+            border-bottom: solid thin var(--content-color-40);
+        }
+
+        a {
+            display: block;
+        }
+
+        &:hover {
+            background-color: hsla(217, 6%, 45%, 0.2);
+        }
+    }
+
+    .cw-block-folder-download-icon {
+        @include background-icon(download, clickable, 24);
+        background-repeat: no-repeat;
+        float: right;
+        height: 24px;
+        width: 24px;
+        margin: 1em;
+    }
+}
+
+.cw-block-folder-upload {
+    border: solid thin var(--content-color-40);
+    padding: 1em 10px;
+    border-top: none;
+
+    .cw-file-input {
+        width: calc(100% - 148px);
+        vertical-align: middle;
+    }
+}
+
+// for folder and download block
+.cw-block-file-info {
+    @include background-icon(file, clickable, 24);
+    background-repeat: no-repeat;
+    display: block;
+    padding: 16px 16px 16px 40px;
+    background-position: 10px 16px;
+    width: calc(100% - 56px);
+    overflow: hidden;
+    text-overflow: ellipsis;
+
+    &.cw-block-file-icon-empty {
+        color: var(--black);
+        @include background-icon(folder-empty, info, 24);
+    }
+
+    &.cw-block-file-icon-none {
+        color: var(--black);
+        @include background-icon(file, info, 24);
+    }
+
+    &.cw-block-file-icon-audio {
+        @include background-icon(file-audio, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-audio, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-pic {
+        @include background-icon(file-pic, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-pic, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-video {
+        @include background-icon(file-video, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-video, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-pdf {
+        @include background-icon(file-pdf, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-pdf, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-word {
+        @include background-icon(file-word, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-word, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-spreadsheet {
+        @include background-icon(file-excel, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-excel, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-text {
+        @include background-icon(file-text, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-text, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-ppt {
+        @include background-icon(file-ppt, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-ppt, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-archive {
+        @include background-icon(file-archive, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file-archive, info, 24);
+        }
+    }
+
+    &.cw-block-file-icon-file {
+        @include background-icon(file, clickable, 24);
+
+        &.download-disabled {
+            @include background-icon(file, info, 24);
+        }
+    }
+}
+.cw-block-file-details {
+    margin-top: -16px;
+    padding-left: 40px;
+    padding-bottom: 16px;
+    color: var(--dark-gray-color);
+}
+.cw-block-file-owner,
+.cw-block-file-mkdate {
+    display: block;
+    width: calc(100% - 56px);
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+// download block
+.cw-block-download {
+    .cw-block-download-content {
+        border: solid thin var(--content-color-40);
+
+        .cw-block-download-file-item {
+            a {
+                display: block;
+            }
+
+            &:hover {
+                background-color: fade-out($dark-gray-color-75, 0.8);
+            }
+
+            .cw-block-download-download-icon {
+                @include background-icon(download, clickable, 24);
+                background-repeat: no-repeat;
+                float: right;
+                height: 24px;
+                width: 24px;
+                margin: 1em;
+            }
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/gallery.scss b/resources/assets/stylesheets/scss/courseware/blocks/gallery.scss
new file mode 100644
index 0000000000000000000000000000000000000000..9e1cfb468d41c49dab937dd9fdcf9220c0c08e6d
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/gallery.scss
@@ -0,0 +1,160 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-gallery {
+    .cw-block-content {
+        overflow: hidden;
+    }
+}
+
+.cw-block-gallery-content {
+    position: relative;
+    margin: auto;
+}
+
+.cw-block-gallery-slides {
+    display: none;
+
+    img {
+        display: block;
+        max-width: 100%;
+        margin-left: auto;
+        margin-right: auto;
+    }
+}
+
+.cw-block-gallery-prev,
+.cw-block-gallery-next {
+    cursor: pointer;
+    position: absolute;
+    background-color: fade-out($white, 0.6);
+    top: 50%;
+    height: 36px;
+    width: 36px;
+    background-repeat: no-repeat;
+    background-position: center;
+    margin-top: -22px;
+    transition: 200ms ease;
+    user-select: none;
+    border: none;
+
+    &:hover {
+        background-color: var(--base-color);
+    }
+}
+
+.cw-block-gallery-prev {
+    @include background-icon(arr_1left, clickable, 24);
+
+    &:hover {
+        @include background-icon(arr_1left, info-alt, 24);
+    }
+}
+
+.cw-block-gallery-next {
+    right: 0;
+    @include background-icon(arr_1right, clickable, 24);
+
+    &:hover {
+        @include background-icon(arr_1right, info-alt, 24);
+    }
+}
+
+.cw-block-gallery-file-description {
+    width: -moz-available;
+    color: var(--white);
+    font-size: 15px;
+    padding: 8px 12px;
+    position: absolute;
+    bottom: 8px;
+    text-align: center;
+
+    p {
+        display: -webkit-inline-box;
+        background-color: fade-out($black, 0.6);
+        padding: 0 2em;
+        margin-bottom: 4px;
+        overflow: hidden;
+        -webkit-line-clamp: 3;
+        -webkit-box-orient: vertical;
+    }
+
+    &.show-on-hover {
+        display: none;
+    }
+}
+
+.cw-block-gallery-content:hover .show-on-hover {
+    display: block;
+}
+
+.cw-block-gallery-number-text {
+    color: var(--white);
+    font-size: 12px;
+    padding: 8px 12px;
+    position: absolute;
+    top: 0;
+    background-color: fade-out($black, 0.6);
+}
+
+.cw-block-gallery-fade {
+    -webkit-animation-name: fade;
+    -webkit-animation-duration: 1.5s;
+    animation-name: fade;
+    animation-duration: 1.5s;
+}
+
+@-webkit-keyframes fade {
+    from {
+        opacity: 0.4;
+    }
+    to {
+        opacity: 1;
+    }
+}
+
+@keyframes fade {
+    from {
+        opacity: 0.4;
+    }
+    to {
+        opacity: 1;
+    }
+}
+
+.cw-block-gallery-grid {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    list-style: none;
+    padding: 0;
+
+    figure {
+        padding: 1px 4px;
+        margin: unset;
+
+        figcaption {
+            margin-bottom: 12px;
+
+            .cw-block-gallery-grid-file-name {
+                font-weight: 700;
+                margin-bottom: 4px;
+                overflow: hidden;
+                display: -webkit-box;
+                -webkit-line-clamp: 2;
+                -webkit-box-orient: vertical;
+            }
+
+            .cw-block-gallery-grid-file-description {
+                overflow: hidden;
+                display: -webkit-box;
+                -webkit-line-clamp: 5;
+                -webkit-box-orient: vertical;
+            }
+        }
+    }
+}
+
+.cw-container-wrapper-edit .cw-block-gallery-grid {
+    margin: 0;
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/headline.scss b/resources/assets/stylesheets/scss/courseware/blocks/headline.scss
new file mode 100644
index 0000000000000000000000000000000000000000..36463276e77237f969af54c5f99e3c69455c7c00
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/headline.scss
@@ -0,0 +1,651 @@
+@use '../../../mixins.scss' as *;
+@import '../gradients.scss';
+@import '../variables.scss';
+
+$big-icon-size: 196;
+$big-icon-size-px: $big-icon-size + px;
+$large-icon-size: 128;
+$large-icon-size-px: $large-icon-size + px;
+
+.cw-block-headline {
+    .cw-block-headline-content {
+        min-height: 600px;
+        overflow: hidden;
+        background-position: center;
+        background-size: $max-content-width;
+        background-repeat: no-repeat;
+
+        &.half {
+            min-height: 300px;
+        }
+
+        &.quarter {
+            min-height: 150px;
+        }
+
+        &.heavy {
+            .cw-block-headline-iconbox {
+                display: none;
+            }
+            .cw-block-headline-textbox {
+                margin: 2em;
+                h1,
+                h2 {
+                    display: inline;
+                    border: none;
+                    padding: 0.25em 0;
+                }
+                h1 {
+                    font-size: 10em;
+                    line-height: 1.2em;
+                }
+                h2 {
+                    font-size: 2em;
+                    line-height: 1em;
+                }
+
+                &.quarter {
+                    margin: 1.5em;
+                    h1 {
+                        font-size: 5em;
+                    }
+                    h2 {
+                        font-size: 1.5em;
+                    }
+                }
+            }
+        }
+        &.bigicon_top {
+            .icon-layer {
+                background-repeat: no-repeat;
+                background-position: center;
+                margin-top: 8em;
+                margin-bottom: 1em;
+                background-size: $big-icon-size-px;
+                height: $big-icon-size-px;
+
+                @each $icon in $icons {
+                    &.icon-black-#{$icon} {
+                        @include background-icon($icon, info, $big-icon-size);
+                    }
+                    &.icon-white-#{$icon} {
+                        @include background-icon($icon, info-alt, $big-icon-size);
+                    }
+                    &.icon-studip-blue-#{$icon} {
+                        @include background-icon($icon, clickable, $big-icon-size);
+                    }
+                    &.icon-studip-red-#{$icon} {
+                        @include background-icon($icon, status-red, $big-icon-size);
+                    }
+                    &.icon-studip-yellow-#{$icon} {
+                        @include background-icon($icon, status-yellow, $big-icon-size);
+                    }
+                    &.icon-studip-green-#{$icon} {
+                        @include background-icon($icon, status-green, $big-icon-size);
+                    }
+                    &.icon-studip-gray-#{$icon} {
+                        @include background-icon($icon, inactive, $big-icon-size);
+                    }
+                }
+
+                &.half {
+                    height: 144px;
+                    background-size: 144px;
+                    background-position: center;
+                    margin-top: 2em;
+                    margin-bottom: 0;
+                }
+                &.quarter {
+                    height: 72px;
+                    background-size: 72px;
+                    background-position: center;
+                    margin-top: 1em;
+                    margin-bottom: 0;
+                }
+            }
+
+            .cw-block-headline-textbox {
+                width: 80%;
+                padding-bottom: 4em;
+                margin: 0 auto;
+                .cw-block-headline-title {
+                    h1 {
+                        border: none;
+                        font-size: 5em;
+                        text-align: center;
+                    }
+                }
+
+                .cw-block-headline-subtitle {
+                    h2 {
+                        border: none;
+                        font-size: 18px;
+                        text-align: center;
+                        margin-top: 10px;
+                    }
+                }
+
+                &.quarter {
+                    padding-bottom: 1em;
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 2.25em;
+                            margin: 0;
+                        }
+                    }
+                    .cw-block-headline-subtitle {
+                        h2 {
+                            font-size: 1em;
+                            margin: 0;
+                        }
+                    }
+                }
+            }
+        }
+
+        &.bigicon_before {
+            display: flex;
+            align-items: center;
+            .icon-layer {
+                min-height: $big-icon-size-px;
+                min-width: $big-icon-size-px;
+                margin: 0 28px 0 28px;
+                background-repeat: no-repeat;
+                background-position: left center;
+
+                @each $icon in $icons {
+                    &.icon-black-#{$icon} {
+                        @include background-icon($icon, info, $big-icon-size);
+                    }
+                    &.icon-white-#{$icon} {
+                        @include background-icon($icon, info-alt, $big-icon-size);
+                    }
+                    &.icon-studip-blue-#{$icon} {
+                        @include background-icon($icon, clickable, $big-icon-size);
+                    }
+                    &.icon-studip-red-#{$icon} {
+                        @include background-icon($icon, status-red, $big-icon-size);
+                    }
+                    &.icon-studip-yellow-#{$icon} {
+                        @include background-icon($icon, status-yellow, $big-icon-size);
+                    }
+                    &.icon-studip-green-#{$icon} {
+                        @include background-icon($icon, status-green, $big-icon-size);
+                    }
+                    &.icon-studip-gray-#{$icon} {
+                        @include background-icon($icon, inactive, $big-icon-size);
+                    }
+                }
+
+                &.quarter {
+                    min-height: $large-icon-size-px;
+                    min-width: $large-icon-size-px;
+                    background-size: $large-icon-size-px;
+                }
+            }
+
+            .cw-block-headline-textbox {
+                margin: 2em 1em 2em 0;
+                .cw-block-headline-title {
+                    h1 {
+                        border: none;
+                        font-size: 5em;
+                        text-align: left;
+                    }
+                }
+
+                .cw-block-headline-subtitle {
+                    display: none;
+                }
+            }
+        }
+
+        &.ribbon {
+            display: flex;
+            align-items: center;
+
+            .cw-block-headline-textbox {
+                width: 100%;
+                padding: 1em 0;
+                margin: 3em 0;
+                background-color: fade-out($black, 0.5);
+                .cw-block-headline-title {
+                    h1 {
+                        border: none;
+                        font-size: 5em;
+                        text-align: center;
+                        margin-bottom: 0;
+                    }
+                }
+
+                .cw-block-headline-subtitle {
+                    h2 {
+                        border: none;
+                        font-size: 18px;
+                        text-align: center;
+                        margin-top: 10px;
+                    }
+                }
+            }
+        }
+
+        &.vertical {
+            .cw-block-headline-textbox {
+                .cw-block-headline-title {
+                    position: relative;
+                    top: 0;
+                    left: 5em;
+                    height: 5em;
+                    text-align: center;
+                    width: 600px;
+                    transform-origin: 0 0;
+                    transform: rotate(90deg);
+                    h1 {
+                        text-transform: uppercase;
+                        border: none;
+                        font-size: 2em;
+                        line-height: 2.5em;
+                    }
+                }
+
+                .cw-block-headline-subtitle {
+                    margin: 0 8em;
+                    padding: 2em;
+                    h2 {
+                        margin: 0;
+                        font-weight: 400;
+                    }
+                }
+            }
+            &.half {
+                .cw-block-headline-title {
+                    width: 300px;
+                }
+            }
+            &.quarter {
+                .cw-block-headline-title {
+                    width: 150px;
+                    h1 {
+                        font-size: 1em;
+                        line-height: 5em;
+                    }
+                }
+                .cw-block-headline-subtitle {
+                    margin: -2em 8em 0 8em;
+                    padding: 1em;
+                }
+            }
+        }
+
+        &.skew_text {
+            min-height: 600px;
+
+            .cw-block-headline-textbox {
+                font-size: 7em;
+                text-align: left;
+                text-transform: uppercase;
+                font-weight: 800;
+                font-family: sans-serif;
+                font-style: normal;
+                letter-spacing: -6px;
+                margin: 1.25em 0 1.5em 1em;
+                div {
+                    overflow: hidden;
+                    font-size: 1em;
+                    margin: -1px 0;
+                    white-space: nowrap;
+                    height: 0.8em;
+                    width: calc(100% - 1em);
+
+                    h1,
+                    h2 {
+                        font-size: 0.8em;
+                        margin: 0;
+                        white-space: nowrap;
+                        overflow: hidden;
+                        line-height: 0.8em;
+                        height: 0.8em;
+                    }
+                }
+                .cw-block-headline-title,
+                .cw-block-headline-second-subtitle {
+                    transform: skew(60deg, -15deg) scaley(0.66667);
+                }
+                .cw-block-headline-subtitle {
+                    transform: skew(0deg, -15deg) scaley(1.33333);
+                }
+                .cw-block-headline-subtitle {
+                    position: relative;
+                    left: 0.48em;
+                }
+                .cw-block-headline-second-subtitle {
+                    position: relative;
+                    left: 0.92em;
+                }
+            }
+
+            &.half {
+                min-height: 300px;
+                height: 300px;
+                .cw-block-headline-textbox {
+                    font-size: 4em;
+                    margin: 1.5em 0 1.5em 1em;
+                    div {
+                        width: calc(100% - 9em);
+                    }
+                }
+            }
+            &.quarter {
+                min-height: 150px;
+                height: 150px;
+                .cw-block-headline-textbox {
+                    font-size: 2em;
+                    margin: 0.75em 0 0.75em 1em;
+                    letter-spacing: -2px;
+                    div {
+                        width: calc(100% - 18em);
+                    }
+                }
+            }
+        }
+
+        &.icon_top_lines {
+            .cw-block-headline-iconbox {
+                margin: 32px;
+                &::before,
+                &::after {
+                    width: calc(50% - 96px);
+                    height: 64px;
+                    display: inline-block;
+                    border-top: solid 4px;
+                    content: '';
+                }
+                @each $name, $hex in $border-colors {
+                    &.border-#{'' + $name}::before,
+                    &.border-#{'' + $name}::after {
+                        border-color: $hex;
+                    }
+                }
+                .icon-layer {
+                    background-repeat: no-repeat;
+                    background-position: center;
+                    background-size: 128px;
+                    height: 128px;
+                    width: 192px;
+                    display: inline-block;
+                    margin: auto;
+
+                    @each $icon in $icons {
+                        &.icon-black-#{$icon} {
+                            @include background-icon($icon, info, 128);
+                        }
+                        &.icon-white-#{$icon} {
+                            @include background-icon($icon, info-alt, 128);
+                        }
+                        &.icon-studip-blue-#{$icon} {
+                            @include background-icon($icon, clickable, 128);
+                        }
+                        &.icon-studip-red-#{$icon} {
+                            @include background-icon($icon, status-red, 128);
+                        }
+                        &.icon-studip-yellow-#{$icon} {
+                            @include background-icon($icon, status-yellow, 128);
+                        }
+                        &.icon-studip-green-#{$icon} {
+                            @include background-icon($icon, status-green, 128);
+                        }
+                        &.icon-studip-gray-#{$icon} {
+                            @include background-icon($icon, inactive, 128);
+                        }
+                    }
+
+                    &.half {
+                        height: 128px;
+                        background-size: 128px;
+                    }
+                    &.quarter {
+                        height: 64px;
+                        width: 96px;
+                        background-size: 64px;
+                    }
+                }
+                &.half {
+                    margin: 16px 32px;
+                }
+                &.quarter {
+                    margin: 8px 32px 0 32px;
+                    &::before,
+                    &::after {
+                        width: calc(50% - 48px);
+                        height: 32px;
+                    }
+                }
+            }
+            .cw-block-headline-textbox {
+                width: calc(100% - 64px);
+                min-height: 350px;
+                margin: 0 auto;
+                border-bottom: solid 4px;
+                @each $name, $hex in $border-colors {
+                    &.border-#{'' + $name} {
+                        border-color: $hex;
+                    }
+                }
+                .cw-block-headline-title {
+                    h1 {
+                        border: none;
+                        font-size: 5em;
+                        text-align: center;
+                    }
+                }
+
+                .cw-block-headline-subtitle {
+                    h2 {
+                        border: none;
+                        font-size: 18px;
+                        text-align: center;
+                        margin: 22px 64px;
+                    }
+                }
+
+                &.half {
+                    min-height: 0px;
+                    margin-bottom: 32px;
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 4em;
+                        }
+                    }
+
+                    .cw-block-headline-subtitle {
+                        h2 {
+                            font-size: 1em;
+                            margin: 1em 64px;
+                        }
+                    }
+                }
+                &.quarter {
+                    min-height: 0;
+                    margin-bottom: 0;
+                    border: none;
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 2em;
+                        }
+                    }
+
+                    .cw-block-headline-subtitle {
+                        h2 {
+                            font-size: 1em;
+                            margin: 8px 64px;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+.cw-container-colspan-half,
+.cw-container-colspan-half-center {
+    .cw-block-headline {
+        .cw-block-headline-content {
+            min-height: 300px;
+
+            &.half {
+                min-height: 150px;
+            }
+            &.heavy {
+                h1 {
+                    font-size: 4.5em;
+                }
+                h2 {
+                    font-size: 1.25em;
+                }
+            }
+            &.bigicon_top {
+                .icon-layer {
+                    background-position: center;
+                    height: 98px;
+                    margin-top: 2em;
+                    margin-bottom: 1em;
+
+                    @each $icon in $icons {
+                        &.icon-black-#{$icon} {
+                            @include background-icon($icon, info, 98);
+                        }
+                        &.icon-white-#{$icon} {
+                            @include background-icon($icon, info-alt, 98);
+                        }
+                        &.icon-studip-blue-#{$icon} {
+                            @include background-icon($icon, clickable, 98);
+                        }
+                        &.icon-studip-red-#{$icon} {
+                            @include background-icon($icon, status-red, 98);
+                        }
+                        &.icon-studip-yellow-#{$icon} {
+                            @include background-icon($icon, status-yellow, 98);
+                        }
+                        &.icon-studip-green-#{$icon} {
+                            @include background-icon($icon, status-green, 98);
+                        }
+                        &.icon-studip-gray-#{$icon} {
+                            @include background-icon($icon, inactive, 98);
+                        }
+                    }
+
+                    &.half {
+                        background-size: 72px;
+                        height: 72px;
+                        background-position: center;
+                    }
+                }
+
+                .cw-block-headline-textbox {
+                    max-width: 80%;
+                    margin: 0 auto;
+                    padding-bottom: 1em;
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 2em;
+                        }
+                    }
+
+                    .cw-block-headline-subtitle {
+                        h2 {
+                            font-size: 12px;
+                        }
+                    }
+                }
+            }
+            &.bigicon_before {
+                min-height: 300px;
+                .icon-layer {
+                    min-height: 92px;
+                    min-width: 92px;
+                    background-position: 0 center;
+                    @each $icon in $icons {
+                        &.icon-black-#{$icon} {
+                            @include background-icon($icon, info, 92);
+                        }
+                        &.icon-white-#{$icon} {
+                            @include background-icon($icon, info-alt, 92);
+                        }
+                        &.icon-studip-blue-#{$icon} {
+                            @include background-icon($icon, clickable, 92);
+                        }
+                        &.icon-studip-red-#{$icon} {
+                            @include background-icon($icon, status-red, 92);
+                        }
+                        &.icon-studip-yellow-#{$icon} {
+                            @include background-icon($icon, status-yellow, 92);
+                        }
+                        &.icon-studip-green-#{$icon} {
+                            @include background-icon($icon, status-green, 92);
+                        }
+                        &.icon-studip-gray-#{$icon} {
+                            @include background-icon($icon, inactive, 92);
+                        }
+                    }
+                }
+
+                .cw-block-headline-textbox {
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 2.5em;
+                        }
+                    }
+                }
+
+                &.half {
+                    min-height: 150px;
+                }
+            }
+
+            &.ribbon {
+                min-height: 300px;
+
+                &.half {
+                    min-height: 150px;
+                }
+
+                .cw-block-headline-textbox {
+                    margin: 3em 0;
+
+                    .cw-block-headline-title {
+                        h1 {
+                            font-size: 2.5em;
+                        }
+                    }
+                    .cw-block-headline-subtitle {
+                        h2 {
+                            font-size: 12px;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+.responsive-display {
+    .cw-block-headline {
+        .cw-block-headline-content {
+            background-size: 100%;
+            &.bigicon_before {
+                .icon-layer {
+                    background-size: 144px;
+                }
+                .cw-block-headline-textbox .cw-block-headline-title h1 {
+                    font-size: 4em;
+                }
+            }
+            &.skew_text {
+                min-height: 300px;
+                .cw-block-headline-textbox {
+                    font-size: 4em;
+                    letter-spacing: -4px;
+                }
+            }
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/iframe.scss b/resources/assets/stylesheets/scss/courseware/blocks/iframe.scss
new file mode 100644
index 0000000000000000000000000000000000000000..6bba2abdb3c67e1810b48bf0efc0c8fb02f77726
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/iframe.scss
@@ -0,0 +1,54 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-iframe {
+    .cw-block-content {
+        iframe {
+            border: solid thin var(--content-color-40);
+            width: calc(100% - 2px);
+        }
+
+        .cw-block-iframe-cc-data {
+            border: solid thin var(--content-color-40);
+            border-top: none;
+            margin-top: -6px;
+            padding-top: 10px;
+            height: 75px;
+
+            .cw-block-iframe-cc {
+                width: 120px;
+                height: 50px;
+                margin-left: 4px;
+                display: inline-block;
+                background-repeat: no-repeat;
+
+                &.cw-block-iframe-cc-by {
+                    background-image: url('#{$image-path}/cc/by.svg');
+                }
+                &.cw-block-iframe-cc-by-nc {
+                    background-image: url('#{$image-path}/cc/by-nc.eu.svg');
+                }
+                &.cw-block-iframe-cc-by-nc-nd {
+                    background-image: url('#{$image-path}/cc/by-nc-nd.eu.svg');
+                }
+                &.cw-block-iframe-cc-by-nc-sa {
+                    background-image: url('#{$image-path}/cc/by-nc-sa.svg');
+                }
+                &.cw-block-iframe-cc-by-nd {
+                    background-image: url('#{$image-path}/cc/by-nd.svg');
+                }
+                &.cw-block-iframe-cc-by-sa {
+                    background-image: url('#{$image-path}/cc/by-sa.svg');
+                }
+            }
+
+            .cw-block-iframe-cc-infos {
+                display: inline-block;
+                vertical-align: top;
+                padding-left: 1em;
+                p {
+                    margin: 0;
+                }
+            }
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/image-map.scss b/resources/assets/stylesheets/scss/courseware/blocks/image-map.scss
new file mode 100644
index 0000000000000000000000000000000000000000..398ce99f43b6e303bc30c891997fa8c6025accbc
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/image-map.scss
@@ -0,0 +1,35 @@
+@import '../variables.scss';
+
+.cw-block-image-map {
+    .cw-image-map-canvas,
+    .cw-image-map-original-img {
+        display: none;
+    }
+
+    form.default {
+        label.cw-block-image-map-dimensions > input[type='number'] {
+            display: inline-block;
+        }
+    }
+}
+
+.cw-draggable-shapes-wrapper {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    width: 100%;
+    height: 100%;
+    margin: $cw-wrapper-gap;
+
+    .cw-draggable-area {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        text-align: center;
+        &:hover {
+            cursor: grab;
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/keypoint.scss b/resources/assets/stylesheets/scss/courseware/blocks/keypoint.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1cf7b867d129c4bdb4ad1ef26e52df84a2030f90
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/keypoint.scss
@@ -0,0 +1,100 @@
+@use '../../../mixins.scss' as *;
+@import '../variables.scss';
+
+.cw-keypoint-content {
+    display: flex;
+    min-height: 52px;
+    padding: 1.5em 2.5em 1.5em 2.5em;
+    border-style: solid;
+    border-width: 2px;
+    align-items: center;
+}
+
+.cw-keypoint-content > img {
+    flex-shrink: 0;
+}
+
+.cw-keypoint-red {
+    border-color: map-get($icon-colors, 'icon-red');
+}
+
+.cw-keypoint-blue {
+    border-color: map-get($icon-colors, 'icon-blue');
+}
+
+.cw-keypoint-green {
+    border-color: map-get($icon-colors, 'icon-green');
+}
+
+.cw-keypoint-gray {
+    border-color: map-get($icon-colors, 'icon-gray');
+}
+
+.cw-keypoint-yellow {
+    border-color: map-get($icon-colors, 'icon-yellow');
+}
+
+.cw-keypoint-sentence {
+    display: inline;
+    font-size: 1.25em;
+    padding-left: 1.5em;
+    margin-top: 10px;
+}
+
+.cw-keypoint-label-color {
+    width: 32px !important;
+    min-width: 32px !important;
+    height: 32px;
+    padding: 5px !important;
+
+    > .cw-keypoint-input-color {
+        visibility: hidden;
+        position: absolute;
+    }
+
+    > .cw-keypoint-input-color + div {
+        cursor: pointer;
+        border: 2px solid transparent;
+        height: 32px;
+        width: 32px;
+    }
+
+    > .cw-keypoint-input-color:checked + div {
+        /* (RADIO CHECKED) IMAGE STYLES */
+        @include background-icon(accept, info_alt, 24);
+        background-repeat: no-repeat;
+        background-position: center;
+    }
+}
+
+label[for='cw-keypoint-color'] {
+    vertical-align: top;
+}
+
+.cw-keypoint-label-color {
+    display: inline-block !important;
+}
+
+.cw-keypoint-icons {
+    background-color: var(--white);
+}
+
+.cw-keypoint-bg-red {
+    background-color: map-get($icon-colors, 'icon-red');
+}
+
+.cw-keypoint-bg-blue {
+    background-color: map-get($icon-colors, 'icon-blue');
+}
+
+.cw-keypoint-bg-green {
+    background-color: map-get($icon-colors, 'icon-green');
+}
+
+.cw-keypoint-bg-gray {
+    background-color: map-get($icon-colors, 'icon-gray');
+}
+
+.cw-keypoint-bg-yellow {
+    background-color: map-get($icon-colors, 'icon-yellow');
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/link.scss b/resources/assets/stylesheets/scss/courseware/blocks/link.scss
new file mode 100644
index 0000000000000000000000000000000000000000..eeeab6bb85c42cea967883d7f9a2d7ef639b9721
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/link.scss
@@ -0,0 +1,73 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-link {
+    a {
+        text-decoration: none;
+    }
+
+    .cw-link {
+        border: solid thin var(--content-color-40);
+        color: var(--base-color);
+        height: 20px;
+        padding: 1em;
+
+        .cw-link-title {
+            margin-left: 3em;
+        }
+
+        &:hover {
+            background-color: var(--base-color);
+            border: solid thin var(--base-color);
+            color: var(--white);
+        }
+
+        &.internal {
+            @include background-icon(link-intern, clickable, 28);
+            background-position: 1em 50%;
+            background-repeat: no-repeat;
+
+            &:hover {
+                @include background-icon(link-intern, info-alt, 28);
+            }
+        }
+
+        &.external {
+            @include background-icon(link-extern, clickable, 28);
+            background-position: 1em 50%;
+            background-repeat: no-repeat;
+
+            &:hover {
+                @include background-icon(link-extern, info-alt, 28);
+            }
+
+            .cw-link-og-image {
+                display: inline-block;
+                max-width: 40%;
+                vertical-align: top;
+                margin-right: 2em;
+            }
+
+            .cw-link-og-textwrapper {
+                display: inline-block;
+                max-width: 50%;
+
+                p {
+                    margin: 0;
+                }
+
+                .cw-link-og-site {
+                    font-size: 1.25em;
+                }
+
+                .cw-link-og-title {
+                    font-weight: 600;
+                }
+
+                .cw-link-og-description {
+                    color: var(--base-color-80);
+                    text-align: justify;
+                }
+            }
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/lti.scss b/resources/assets/stylesheets/scss/courseware/blocks/lti.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c3d7af1144bd4c3e683c6bb6170eff4c301f0aa0
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/lti.scss
@@ -0,0 +1,20 @@
+@use '../../../mixins.scss' as *;
+
+.cw-block-lti {
+    .cw-block-content {
+        .cw-block-lti-content {
+            border: solid thin var(--content-color-40);
+            box-sizing: border-box;
+        }
+
+        .cw-block-lti-icon-tool {
+            @include background-icon(plugin, info, 24);
+            background-repeat: no-repeat;
+            display: block;
+            padding: 16px 16px 16px 40px;
+            background-position: 10px center;
+            overflow: hidden;
+            text-overflow: ellipsis;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/table-of-contents.scss b/resources/assets/stylesheets/scss/courseware/blocks/table-of-contents.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f1c1d225b8478bb7de25996097a5641f31cca395
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/table-of-contents.scss
@@ -0,0 +1,71 @@
+@use '../../../mixins.scss' as *;
+@import '../variables.scss';
+
+.cw-block-table-of-contents {
+    .cw-block-content {
+        overflow: unset;
+    }
+}
+
+.cw-block-table-of-contents-list {
+    padding: 0;
+    list-style: none;
+    border: solid thin var(--content-color-40);
+    li {
+        &:not(:last-child) {
+            border-bottom: solid thin var(--dark-gray-color-30);
+        }
+        a {
+            display: block;
+            padding: 1em;
+        }
+        &:hover {
+            background-color: fade-out($dark-gray-color-75, 0.8);
+        }
+    }
+}
+
+.cw-block-table-of-contents-list-details {
+    padding: 0;
+    list-style: none;
+    border: solid thin var(--content-color-40);
+    li {
+        &:not(:last-child) {
+            border-bottom: solid thin var(--dark-gray-color-30);
+        }
+
+        &:hover {
+            background-color: fade-out($dark-gray-color-75, 0.8);
+        }
+        a {
+            display: block;
+            padding: 1em;
+        }
+    }
+}
+
+.cw-block-table-of-contents-title-box {
+    min-height: 3em;
+    padding-left: 1em;
+    border-left-width: 10px;
+    border-left-style: solid;
+
+    @each $name, $color in $tile-colors {
+        &.#{'' + $name} {
+            border-color: $color;
+        }
+    }
+
+    p,
+    p:hover {
+        color: var(--black);
+    }
+}
+
+.cw-container-colspan-half {
+    .cw-block-table-of-contents-tiles.cw-tiles {
+        .tile {
+            width: 267px;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/text.scss b/resources/assets/stylesheets/scss/courseware/blocks/text.scss
new file mode 100644
index 0000000000000000000000000000000000000000..6bb182429a0ffa2c7d94ae0d71f4053cc4051e71
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/text.scss
@@ -0,0 +1,16 @@
+.cw-block-text {
+    .cktoolbar {
+        width: 100% !important;
+        max-width: 100% !important;
+        position: relative !important;
+        top: 0 !important;
+    }
+
+    .cke {
+        width: 100% !important;
+    }
+
+    .ckplaceholder {
+        height: 0 !important;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/timeline.scss b/resources/assets/stylesheets/scss/courseware/blocks/timeline.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e727313845b489603614a63c871ace856d894d04
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/timeline.scss
@@ -0,0 +1,244 @@
+@import '../variables.scss';
+
+%clearfix {
+    &:after, &:before {
+        content: '';
+        display: block;
+        width: 100%;
+        clear: both;
+    }
+}
+
+.cw-timeline {
+    list-style: none;
+    width: 100%;
+    margin: 30px auto;
+    position: relative;
+    padding: 0;
+    transition: all 0.4s ease;
+
+    &:before {
+        content:"";
+        width: 3px;
+        height: 100%;
+        background: var(--content-color-40);
+        left: 50%;
+        top: 0;
+        position: absolute;
+    }
+
+    &:after {
+        content: "";
+        clear: both;
+        display: table;
+        width: 100%;
+    }
+
+    .cw-timeline-item {
+        margin-bottom: 50px;
+        position: relative;
+        @extend %clearfix;
+
+        .cw-timeline-item-icon {
+            background: var(--white);
+            width: 50px;
+            height: 50px;
+            position: absolute;
+            top: 0;
+            left: 50%;
+            overflow: hidden;
+            margin-left: -25px;
+            @each $name, $color in $tile-colors {
+                &.cw-timeline-item-icon-color-#{"" + $name} {
+                    border: solid 2px $color;
+                }
+            }
+
+            border-radius: 50%;
+
+            img {
+                position: relative;
+                top: 9px;
+                left: 9px;
+
+                &.charcoal {
+                    filter: brightness(0) saturate(100%) invert(22%) sepia(29%) saturate(364%) hue-rotate(168deg) brightness(87%) contrast(79%);
+                }
+                &.royal-purple {
+                    filter: brightness(0) saturate(100%) invert(35%) sepia(43%) saturate(658%) hue-rotate(234deg) brightness(100%) contrast(87%);
+                }
+                &.iguana-green {
+                    filter: brightness(0) saturate(100%) invert(74%) sepia(9%) saturate(1885%) hue-rotate(76deg) brightness(86%) contrast(88%);
+                }
+                &.queen-blue {
+                    filter: brightness(0) saturate(100%) invert(44%) sepia(10%) saturate(2086%) hue-rotate(178deg) brightness(88%) contrast(80%);
+                }
+                &.verdigris {
+                    filter: brightness(0) saturate(100%) invert(64%) sepia(11%) saturate(4959%) hue-rotate(131deg) brightness(103%) contrast(49%);
+                }
+                &.mulberry {
+                    filter: brightness(0) saturate(100%) invert(49%) sepia(16%) saturate(1665%) hue-rotate(271deg) brightness(88%) contrast(95%);
+                }
+                &.pumpkin {
+                    filter: brightness(0) saturate(100%) invert(38%) sepia(86%) saturate(1993%) hue-rotate(13deg) brightness(104%) contrast(108%);
+                }
+                &.sunglow {
+                    filter: brightness(0) saturate(100%) invert(93%) sepia(69%) saturate(6824%) hue-rotate(313deg) brightness(102%) contrast(100%);
+                }
+                &.apple-green {
+                    filter: brightness(0) saturate(100%) invert(69%) sepia(5%) saturate(5203%) hue-rotate(42deg) brightness(100%) contrast(84%);
+                }
+                &.studip-blue {
+                    filter: brightness(0) saturate(100%) invert(26%) sepia(19%) saturate(1783%) hue-rotate(177deg) brightness(96%) contrast(93%);
+                }
+                &.studip-lightblue {
+                    filter: brightness(0) saturate(100%) invert(91%) sepia(12%) saturate(190%) hue-rotate(190deg) brightness(104%) contrast(89%);
+                }
+                &.studip-red {
+                    filter: brightness(0) saturate(100%) invert(8%) sepia(95%) saturate(6904%) hue-rotate(1deg) brightness(95%) contrast(109%);
+                }
+                &.studip-green {
+                    filter: brightness(0) saturate(100%) invert(27%) sepia(85%) saturate(1531%) hue-rotate(109deg) brightness(95%) contrast(101%);
+                }
+                &.studip-yellow {
+                    filter: brightness(0) saturate(100%) invert(94%) sepia(14%) saturate(7314%) hue-rotate(330deg) brightness(103%) contrast(101%);
+                }
+                &.studip-gray {
+                    filter: brightness(0) saturate(100%) invert(46%) sepia(1%) saturate(2621%) hue-rotate(169deg) brightness(87%) contrast(87%);
+                }
+            }
+        }
+
+        .cw-timeline-item-content {
+            width: 40%;
+            background: var(--white);
+            padding: 20px;
+            transition: all var(--transition-duration) ease;
+
+            h3 {
+                padding: 15px;
+                color: var(--white);
+                margin: -20px -20px 0 -20px;
+                font-weight: 700;
+                min-height: 1.1em;
+            }
+
+            article {
+                min-height: 2em;
+                border: solid thin var(--content-color-20);
+                border-top: none;
+                margin: 0 -20px;
+                padding: 15px;
+
+                header {
+                    font-weight: 700;
+                    font-size: 1.1em;
+                    margin: 0.5em 0;
+                }
+            }
+
+            &:before {
+                content: '';
+                position: absolute;
+                left: calc(40% + 40px);
+                top: 18px;
+                width: 0;
+                height: 0;
+                border-top: 7px solid transparent;
+                border-bottom: 7px solid transparent;
+            }
+            &.left {
+                h3 {
+                    text-align: right;
+                }
+            }
+            &.right {
+                float: right;
+
+                h3 {
+                    text-align: left;
+                }
+
+                &:before {
+                    content: '';
+                    right: calc(40% + 40px);
+                    left: inherit;
+                    border-left: 0;
+                }
+            }
+
+            @each $name, $color in $tile-colors {
+                &.cw-timeline-item-content-color-#{"" + $name} {
+                    border-color: $color;
+                    h3 {
+                        background-color: $color;
+                    }
+                    &.left {
+                        &:before {
+                            border-left: 7px solid $color;
+                        }
+                    }
+                    &.right {
+                        &:before {
+                            border-right: 7px solid $color;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+@mixin oneSidedTimeline() {
+    .cw-timeline {
+        &:before {
+            left: 25px;
+        }
+        .cw-timeline-item {
+            .cw-timeline-item-icon {
+                left: 25px;
+            }
+            .cw-timeline-item-content {
+                width: stretch;
+                margin-left: 70px;
+                &.left {
+                    float: unset;
+
+                    h3 {
+                        text-align: left;
+                    }
+
+                    &:before {
+                        content: '';
+                        right: calc(100% - 70px);
+                        left: inherit;
+                        border-left: 0;
+                    }
+                }
+                &.right {
+                    float: unset;
+                    &:before {
+                        right: calc(100% - 70px);
+                    }
+                }
+
+                @each $name, $color in $tile-colors {
+                    &.cw-timeline-item-content-color-#{"" + $name} {
+                        &.left {
+                            &:before {
+                                border-right: 7px solid $color;
+                                border-left: none;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+.cw-container-colspan-half {
+    @include oneSidedTimeline();
+}
+
+@media only screen and (max-width: 1070px) {
+    @include oneSidedTimeline();
+}
diff --git a/resources/assets/stylesheets/scss/courseware/blocks/typewriter.scss b/resources/assets/stylesheets/scss/courseware/blocks/typewriter.scss
new file mode 100644
index 0000000000000000000000000000000000000000..89a12df24d960a19ccac95953d46905746753b3e
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/blocks/typewriter.scss
@@ -0,0 +1,38 @@
+.cw-typewriter-content {
+    .vue-typer {
+        &.font-typewriter {
+            font-family: 'Lucida Sans Typewriter', 'Lucida Console', Monaco, 'Bitstream Vera Sans Mono', monospace;
+        }
+
+        &.font-trebuchet {
+            font-family: 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', sans-serif;
+        }
+
+        &.font-tahoma {
+            font-family: Tahoma, Verdana, Segoe, sans-serif;
+        }
+
+        &.font-georgia {
+            font-family: Georgia, Times, 'Times New Roman', serif;
+        }
+
+        &.font-narrow {
+            font-family: 'Arial Narrow', Arial, 'Helvetica Condensed', Helvetica, sans-serif;
+        }
+
+        &.size-tall {
+            font-size: 1.25em;
+            line-height: 1.25em;
+        }
+
+        &.size-grande {
+            font-size: 1.5em;
+            line-height: 1.25em;
+        }
+
+        &.size-huge {
+            font-size: 2em;
+            line-height: 1.25em;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/comments.scss b/resources/assets/stylesheets/scss/courseware/comments.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f953e86d2ad43854fe1d9cec7e8dc3e9515d816f
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/comments.scss
@@ -0,0 +1,57 @@
+.cw-structural-element-feedback,
+.cw-structural-element-comments {
+    padding: 0 1em;
+}
+
+.cw-structural-element-feedback-items,
+.cw-structural-element-comments-items,
+.cw-block-feedback-items,
+.cw-block-comments-items {
+    min-height: 1em;
+    max-height: 225px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    margin: -1em -1em 0em 0em;
+    padding: 0em 1em 0em 0em;
+    scroll-behavior: smooth;
+}
+
+.studip-dialog-content {
+    .cw-structural-element-feedback-items,
+    .cw-structural-element-comments-items,
+    .cw-block-feedback-items,
+    .cw-block-comments-items {
+        max-height: unset;
+    }
+}
+
+.cw-structural-element-feedback-create,
+.cw-structural-element-comment-create,
+.cw-block-feedback-create,
+.cw-block-comment-create {
+    border-top: solid thin var(--content-color-40);
+    padding-top: 1em;
+    textarea {
+        width: calc(100% - 6px);
+        resize: none;
+        border: solid thin var(--content-color-40);
+        &:active {
+            border: solid thin var(--content-color-80);
+        }
+    }
+}
+.cw-structural-element-comments-empty,
+.cw-structural-element-feedback-empty,
+.cw-block-comments-empty,
+.cw-block-feedback-empty {
+    .cw-structural-element-feedback-create,
+    .cw-structural-element-comment-create,
+    .cw-block-feedback-create,
+    .cw-block-comment-create {
+        border-top: none;
+    }
+}
+
+.cw-comments-overview-dialog-comments-context {
+    margin: 0 0 1.5em 0;
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/containers/accordion.scss b/resources/assets/stylesheets/scss/courseware/containers/accordion.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/resources/assets/stylesheets/scss/courseware/containers/default-container.scss b/resources/assets/stylesheets/scss/courseware/containers/default-container.scss
new file mode 100644
index 0000000000000000000000000000000000000000..489a1fa0ea59c1c39f8e799657f962f5908126e3
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/containers/default-container.scss
@@ -0,0 +1,202 @@
+.cw-container {
+    margin-bottom: 1em;
+
+    &.cw-container-colspan-full {
+        max-width: $max-content-width;
+        width: 100%;
+    }
+    &.cw-container-colspan-half {
+        max-width: 540px;
+        width: 100%;
+    }
+    &.cw-container-colspan-half-center {
+        width: $max-content-width;
+        .cw-container-content {
+            max-width: 540px;
+            margin: auto;
+        }
+    }
+
+    .cw-container-header {
+        background-color: var(--content-color-20);
+        padding: 4px 10px 4px 22px;
+
+        .cw-container-header-toggle {
+            display: inline-block;
+            width: calc(100% - 40px);
+        }
+
+        span {
+            color: var(--base-color);
+            font-weight: 700;
+            line-height: 2em;
+            font-size: 1.1em;
+
+            &.cw-default-container-blocker-warning {
+                font-weight: 400;
+            }
+        }
+
+        img {
+            vertical-align: text-bottom;
+        }
+
+        .cw-container-actions {
+            position: relative;
+            float: right;
+            margin-top: 4px;
+            // z-index: 31;
+            .is-open {
+                z-index: 31;
+            }
+        }
+    }
+
+    &.cw-container-active {
+        &.cw-container-colspan-half-center {
+            .cw-container-content {
+                max-width: unset;
+                .cw-block-wrapper {
+                    max-width: 540px;
+                    margin: auto;
+                }
+            }
+        }
+        .cw-container-content {
+            border: solid thin var(--content-color-40);
+        }
+    }
+
+
+    .cw-block-wrapper {
+        padding: 0;
+        margin: 0;
+        list-style: none;
+
+        &.cw-block-wrapper-active {
+            padding: 14px 10px;
+
+            .cw-tabs-content {
+                padding: 14px 0;
+            }
+        }
+
+        .cw-block-item {
+            padding: 0;
+            margin: 0 0 1em 0;
+        }
+    }
+
+    .cw-container-list-block-list {
+        padding: 0;
+        list-style: none;
+    }
+
+    .cw-container-tabs-block-list {
+        list-style: none;
+        padding: 1em 1em 0 1em;
+    }
+
+    .cw-container-accordion-block-list {
+        list-style: none;
+        padding: 0 1em;
+    }
+}
+
+.cw-container-section-delete {
+    img {
+        cursor: pointer;
+    }
+}
+
+form.cw-container-dialog-edit-form {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+
+    fieldset {
+        max-width: 200px;
+    }
+}
+
+.cw-container-wrapper-discuss {
+    flex-direction: column;
+
+    .cw-container-colspan-full {
+        max-width: unset;
+    }
+    .cw-container-colspan-half-center,
+    .cw-container-colspan-half {
+        max-width: 1050px;
+    }
+    .cw-container-colspan-half-center {
+        width: 100%;
+        .cw-container-content {
+            width: 1050px;
+        }
+    }
+}
+
+.cw-radioset {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    margin-bottom: 1em;
+    .cw-radioset-box {
+        width: 128px;
+        height: 128px;
+        text-align: center;
+        margin-right: 16px;
+        border: solid thin var(--content-color-40);
+        &.selected {
+            border-color: var(--base-color);
+            background-color: var(--content-color-20);
+        }
+        &:last-child {
+            margin-right: 0;
+        }
+        label {
+            height: 100%;
+            width: 100%;
+            margin: 0;
+            cursor: pointer;
+            .label-icon {
+                background-position: center 8px;
+                background-repeat: no-repeat;
+                height: 64px;
+                padding: 8px;
+                &.accordion {
+                    @include background-icon(block-accordion, clickable, 64);
+                }
+                &.list {
+                    @include background-icon(view-list, clickable, 64);
+                }
+                &.tabs {
+                    @include background-icon(block-tabs, clickable, 64);
+                }
+                &.full {
+                    @include background-icon(column-full, clickable, 64);
+                }
+                &.half {
+                    @include background-icon(column-half, clickable, 64);
+                }
+                &.half-center {
+                    @include background-icon(column-half-centered, clickable, 64);
+                }
+            }
+
+        }
+        input[type=radio] {
+            position: absolute;
+            opacity: 0;
+            width: 0;
+
+            &:focus + label {
+                outline-color: Highlight;
+                outline-color: -webkit-focus-ring-color;
+                outline-style: auto;
+                outline-width: 1px;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/containers/list.scss b/resources/assets/stylesheets/scss/courseware/containers/list.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/resources/assets/stylesheets/scss/courseware/containers/tabs.scss b/resources/assets/stylesheets/scss/courseware/containers/tabs.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/resources/assets/stylesheets/scss/courseware/content-courses.scss b/resources/assets/stylesheets/scss/courseware/content-courses.scss
new file mode 100644
index 0000000000000000000000000000000000000000..16d712cf05c972b7fac16c447990eab8b4a0c499
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/content-courses.scss
@@ -0,0 +1,12 @@
+.cw-content-courses {
+    h2 {
+        margin: 0;
+        font-weight: 400;
+        padding: 5px 0;
+        font-size: 1.4em;
+    }
+
+    ul.cw-tiles {
+        margin-bottom: 20px;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/dashboard.scss b/resources/assets/stylesheets/scss/courseware/dashboard.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a3e9dd395000dda1f6fc33a655b94a8db1c80c81
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/dashboard.scss
@@ -0,0 +1,131 @@
+
+.cw-dashboard {
+    display: flex;
+    max-width: 1112px;
+    flex-wrap: wrap;
+
+    .cw-dashboard-box {
+        margin-bottom: 1em;
+        margin-right: 1em;
+
+        &.cw-dashboard-box-full {
+            max-width: $max-content-width;
+            width: calc(100% - 16px);
+        }
+        &.cw-dashboard-box-half {
+            width: calc(50% - 16px);
+        }
+
+        &.cw-collapsible .cw-collapsible-content.cw-collapsible-content-open {
+            padding: 0;
+        }
+    }
+    .cw-dashboard-overview {
+        display: flex;
+        padding: 10px;
+        flex-wrap: wrap;
+        justify-content: center;
+
+    }
+
+    &.cw-dashboard-task-view {
+        display: unset;
+        max-width: unset;
+        flex-wrap: unset;
+
+        .cw-dashboard-tasks-wrapper,
+        .cw-dashboard-students-wrapper {
+            max-height: unset;
+        }
+    }
+}
+
+#course-courseware-dashboard {
+    .action-menu-item a {
+        cursor: pointer;
+    }
+}
+
+.responsive-display {
+    .cw-dashboard {
+        .cw-dashboard-box {
+
+            &.cw-dashboard-box-full {
+                width: 100%
+            }
+            &.cw-dashboard-box-half {
+                width: 100%
+            }
+        }
+    }
+}
+
+.cw-activities-wrapper {
+    max-width: $max-content-width;
+
+    .cw-companion-box {
+        margin: 10px;
+    }
+
+    .cw-activities {
+        list-style: none;
+        padding: 0;
+
+        .cw-activity-item {
+            border-bottom: solid thin var(--content-color-40);
+            padding: 0.5em;
+
+            &:last-child {
+                border: none;
+            }
+
+            p {
+                margin: 0 0 4px 0;
+                img {
+                    padding-right: 0.5em;
+                    vertical-align: text-bottom;
+                }
+            }
+        }
+    }
+}
+
+.cw-dashboard-box {
+    .cw-dashboard-tasks-wrapper,
+    .cw-dashboard-students-wrapper {
+        padding: 10px;
+    }
+}
+
+.cw-dashboard-tasks-wrapper,
+.cw-dashboard-students-wrapper {
+
+    table.default {
+        margin: 0;
+        thead {
+            tr {
+                th {
+                    &.feedback {
+                        min-width: 11em;
+                    }
+                    &.renewal {
+                        min-width: 14em;
+                    }
+                }
+            }
+        }
+        tbody {
+            tr {
+                td {
+                    img {
+                        vertical-align: text-bottom;
+                        &.display-feedback,
+                        &.edit {
+                            cursor: pointer;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware_gradients.scss b/resources/assets/stylesheets/scss/courseware/gradients.scss
similarity index 100%
rename from resources/assets/stylesheets/scss/courseware_gradients.scss
rename to resources/assets/stylesheets/scss/courseware/gradients.scss
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/collapsible.scss b/resources/assets/stylesheets/scss/courseware/layouts/collapsible.scss
new file mode 100644
index 0000000000000000000000000000000000000000..79dc2eedc0d6b99e7512efb48e1b678dfb0d7464
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/collapsible.scss
@@ -0,0 +1,46 @@
+@use '../../../mixins.scss' as *;
+
+.cw-collapsible {
+    border: solid thin var(--content-color-40);
+    margin-bottom: -1px;
+
+    .cw-collapsible-title {
+        @include background-icon(arr_1right, clickable);
+        background-position: 6px center;
+        background-repeat: no-repeat;
+        background-color: var(--content-color-20);
+        padding: 0.5em 2em;
+        margin: 0;
+        font-weight: 600;
+        color: var(--base-color);
+        cursor: pointer;
+
+        &.cw-collapsible-open {
+            @include background-icon(arr_1down, clickable);
+
+            .cw-container-list-sort-mode {
+                margin-top: 8px;
+            }
+        }
+
+        img {
+            vertical-align: top;
+        }
+    }
+
+    .cw-collapsible-content {
+        display: none;
+        &.cw-collapsible-content-open {
+            display: block;
+            padding: 10px;
+        }
+    }
+}
+
+form .cw-collapsible .cw-collapsible-content.cw-collapsible-content-open {
+    padding: unset;
+
+    label {
+        margin: 1.5ex;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/companion.scss b/resources/assets/stylesheets/scss/courseware/layouts/companion.scss
new file mode 100644
index 0000000000000000000000000000000000000000..cf48c8f2ec6823e15852e3684b6b3d4830523b6a
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/companion.scss
@@ -0,0 +1,90 @@
+@use '../../../mixins.scss' as *;
+
+$companion-types: (
+    default: basic,
+    unsure: unsure,
+    special: special,
+    alert: alert,
+    sad: sad,
+    happy: happy,
+    pointing: pointing-right,
+    curious: curious
+);
+
+.cw-companion-overlay {
+    position: fixed;
+    bottom: 46px;
+    right: 0;
+    width: 360px;
+    max-width: calc(100% - 140px);
+    height: 120px;
+    z-index: 42000;
+    border: solid thin var(--content-color-40);
+    background-color: var(--white);
+    background-repeat: no-repeat;
+    background-position: 1em center;
+    background-size: 100px;
+    box-shadow: 5px 5px var(--dark-gray-color-10);
+    padding-left: 120px;
+    transform: translateX(100%);
+    transition: transform .5s ease;
+
+    @each $type, $image in $companion-types {
+        &.#{$type} {
+            background-image: url("#{$image-path}/companion/Tin_#{$image}.svg");
+        }
+    }
+
+    &.cw-companion-overlay-in {
+        transform: translateX(0);
+        right: 12px;
+    }
+
+    .cw-companion-overlay-content {
+        display: inline-block;
+        position: relative;
+        top: 25%;
+        padding: 0 1em;
+    }
+
+    .cw-compantion-overlay-close {
+        @include background-icon(decline);
+        background-color: var(--white);
+        background-repeat: no-repeat;
+
+        position: absolute;
+        top: 7px;
+        right: 7px;
+        height: 16px;
+        width: 16px;
+        border: none;
+        cursor: pointer;
+    }
+}
+
+.cw-companion-box {
+    display: flex;
+    height: 120px;
+    border: solid thin var(--content-color-40);
+    background-color: var(--white);
+    background-repeat: no-repeat;
+    background-position: 1em center;
+    background-size: 100px;
+    padding-left: 120px;
+    align-items: center;
+    margin-bottom: 1em;
+
+    @each $type, $image in $companion-types {
+        &.#{$type} {
+            background-image: url("#{$image-path}/companion/Tin_#{$image}.svg");
+        }
+    }
+
+    &.cw-companion-box-in-form {
+        margin-top: 8px;
+    }
+
+    p {
+        margin: 0 1em 10px 0;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/import-zip.scss b/resources/assets/stylesheets/scss/courseware/layouts/import-zip.scss
new file mode 100644
index 0000000000000000000000000000000000000000..5ffd9a2d319d203a4a5ff310f76c6c777dce22b1
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/import-zip.scss
@@ -0,0 +1,22 @@
+.cw-import-zip {
+    margin-bottom: 1em;
+
+    header {
+        font-size: 1.15;
+        font-weight: 700;
+    }
+    .progress-bar-wrapper {
+        width: 100%;
+        border: solid thin var(--content-color-40);
+
+        .progress-bar {
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            color: white;
+            text-align: center;
+            white-space: nowrap;
+            background-color: var(--base-color);
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/input-file.scss b/resources/assets/stylesheets/scss/courseware/layouts/input-file.scss
new file mode 100644
index 0000000000000000000000000000000000000000..91590699f65f9f7c76fa4a6174c860bd6c367d80
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/input-file.scss
@@ -0,0 +1,36 @@
+.cw-file-input {
+    width: stretch;
+    border: solid thin var(--base-color);
+    font-size: 14px;
+    cursor: pointer;
+
+    &::file-selector-button {
+        font-family: inherit;
+        border: none;
+        border-right: solid thin var(--base-color);
+        background-color: var(--white);
+        padding: 6px 15px;
+        margin-right: 10px;
+        color: var(--base-color);
+
+        &:hover {
+            background-color: var(--base-color);
+            color: var(--white);
+        }
+    }
+}
+.cw-file-input-change {
+    border: solid thin var(--base-color);
+
+    button.button {
+        padding: 0.5em 1.5em;
+        margin: 0 0 0 -1px;
+        line-height: 100%;
+        border: none;
+        border-right: solid thin var(--base-color);
+    }
+
+    span {
+        padding: 0.5em 1.5em 0.5em 0.5em;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/progress.scss b/resources/assets/stylesheets/scss/courseware/layouts/progress.scss
new file mode 100644
index 0000000000000000000000000000000000000000..822294f77d830f5a452df7eba461518d6614c742
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/progress.scss
@@ -0,0 +1,160 @@
+.cw-unit-progress {
+    .cw-unit-progress-breadcrumb {
+        padding: 10px 0;
+
+        a img {
+            vertical-align: top;
+        }
+    }
+
+    .cw-unit-progress-chapter {
+        text-align: center;
+        margin-bottom: -3.5em;
+
+        h1 {
+            border: none;
+            margin: 0;
+            padding: 0;
+        }
+
+        .cw-progress-circle {
+            font-size: 18px;
+            margin: 1em auto;
+
+            &.cw-unit-progress-current {
+                font-size: 12px;
+                top: -4.5em;
+                left: -2.5em;
+            }
+        }
+    }
+
+    .cw-unit-progress-subchapter-list {
+        border-top: solid thin var(--content-color-40);
+        padding: 0 1em 0 1em;
+
+        .cw-unit-empty-info {
+            margin-top: 10px;
+        }
+    }
+}
+
+.cw-unit-progress-item {
+    display: block;
+    border-bottom: solid thin var(--content-color-40);
+    padding: 10px 0;
+
+    &:hover {
+        background-color: hsla(217, 6%, 45%, 0.2);
+    }
+
+    &:last-child {
+        border: none;
+    }
+
+    .cw-unit-progress-item-value,
+    .cw-unit-progress-item-description {
+        display: inline-block;
+        vertical-align: top;
+    }
+
+    .cw-unit-progress-item-value {
+        width: 70px;
+        color: var(--base-color);
+        font-size: xx-large;
+
+        .cw-progress-circle {
+            font-size: 12px;
+            margin: 4px;
+        }
+    }
+
+    .cw-unit-progress-item-description {
+        color: var(--base-color);
+        padding: 0.5em 0 0 1em;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+    }
+}
+
+.cw-progress-circle {
+    font-size: 14px;
+    margin: 10px;
+    position: relative;
+    padding: 0;
+    width: 5em;
+    height: 5em;
+    background-color: var(--dark-gray-color-10);
+    border-radius: 50%;
+    line-height: 5em;
+
+    &:after {
+        border: none;
+        position: absolute;
+        top: 0.35em;
+        left: 0.35em;
+        text-align: center;
+        display: block;
+        border-radius: 50%;
+        width: 4.3em;
+        height: 4.3em;
+        background-color: white;
+        content: ' ';
+    }
+
+    span {
+        position: absolute;
+        line-height: 5em;
+        width: 5em;
+        text-align: center;
+        display: block;
+        color: var(--base-color);
+        z-index: 2;
+    }
+
+    .left-half-clipper {
+        border-radius: 50%;
+        width: 5em;
+        height: 5em;
+        position: absolute;
+        clip: rect(0, 5em, 5em, 2.5em);
+    }
+
+    &.over50 .left-half-clipper {
+        clip: rect(auto, auto, auto, auto);
+    }
+
+    .value-bar {
+        position: absolute;
+        clip: rect(0, 2.5em, 5em, 0);
+        width: 5em;
+        height: 5em;
+        border-radius: 50%;
+        border: 0.45em solid var(--base-color);
+        box-sizing: border-box;
+    }
+
+    &.over50 .first50-bar {
+        position: absolute;
+        clip: rect(0, 5em, 5em, 2.5em);
+        background-color: var(--base-color);
+        border-radius: 50%;
+        width: 5em;
+        height: 5em;
+    }
+
+    &:not(.over50) .first50-bar {
+        display: none;
+    }
+
+    &.p0 .value-bar {
+        display: none;
+    }
+
+    @for $i from 1 through 100 {
+        &.p#{$i} .value-bar {
+            transform: rotate(calc(360deg * $i / 100));
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/ribbon.scss b/resources/assets/stylesheets/scss/courseware/layouts/ribbon.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b39687ff6ebbd846024f57b699fe28ece364bcf7
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/ribbon.scss
@@ -0,0 +1,359 @@
+@use '../../../mixins.scss' as *;
+
+$consum_ribbon_width: calc(100% - 58px);
+#course-courseware-courseware,
+#contents-courseware-courseware,
+#contents-courseware-shared_content_courseware {
+    &.consume {
+        overflow: hidden;
+    }
+
+    #content-wrapper {
+        position: relative;
+    }
+}
+
+.cw-ribbon-wrapper-consume {
+    position: fixed;
+    padding: 15px;
+    background-color: var(--white);
+    width: $consum_ribbon_width;
+    height: 46px;
+    z-index: 42;
+}
+
+.cw-ribbon-consume-bottom {
+    position: fixed;
+    top: 75px;
+    height: 15px;
+    left: 0;
+    width: calc(100% - 1em);
+    background-color: var(--white);
+    z-index: 40;
+}
+
+.cw-ribbon-sticky-top {
+    position: fixed;
+    top: 40px;
+    height: 20px;
+    width: calc(100% - 314px);
+    background-color: var(--white);
+    z-index: 39;
+}
+
+.cw-ribbon-sticky-bottom {
+    position: fixed;
+    top: 110px;
+    height: 16px;
+    width: calc(100% - 314px);
+    background-color: var(--white);
+    z-index: 39;
+}
+
+.cw-ribbon-sticky-spacer {
+    height: 80px;
+}
+
+.cw-ribbon {
+    display: flex;
+    flex-wrap: wrap;
+    height: auto;
+    min-height: 30px;
+    border: solid thin var(--dark-gray-color-30);
+    margin-bottom: 15px;
+    padding: 1em;
+    justify-content: space-between;
+    background-color: var(--dark-gray-color-5);
+
+    &.cw-ribbon-sticky {
+        position: fixed;
+        top: 50px;
+        width: calc(100% - 346px);
+        z-index: 40;
+    }
+
+    &.cw-ribbon-consume {
+        width: $consum_ribbon_width;
+        position: fixed;
+        margin-bottom: 0;
+    }
+
+    .cw-ribbon-wrapper-left {
+        display: flex;
+        max-width: calc(100% - 106px);
+
+        .cw-ribbon-nav {
+            display: flex;
+            min-width: 75px;
+
+            &.single-icon {
+                min-width: 45px;
+            }
+        }
+
+        .cw-ribbon-breadcrumb {
+            font-size: 1.25em;
+            line-height: 1.5em;
+            margin-right: 1em;
+            min-width: 0;
+
+            ul {
+                display: flex;
+                list-style: none;
+                padding-left: 0;
+
+                li + li:before {
+                    padding: 0 0.25em;
+                    content: '/';
+                    background-repeat: no-repeat;
+                    background-position: center;
+                }
+
+                .cw-ribbon-breadcrumb-item {
+                    display: inline;
+                    flex-shrink: 100000;
+                    min-width: 0;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+
+                    a {
+                        color: var(--base-color);
+                        text-decoration: none;
+                        &:hover {
+                            color: var(--active-color);
+                        }
+                    }
+
+                    img {
+                        vertical-align: text-top;
+                    }
+
+                    &.cw-ribbon-breadcrumb-item-current {
+                        flex-shrink: 1;
+                    }
+                }
+            }
+        }
+    }
+
+    .cw-ribbon-wrapper-right {
+        display: flex;
+
+        button {
+            border: none;
+            background-color: transparent;
+            cursor: pointer;
+        }
+    }
+
+    .cw-ribbon-button {
+        height: 24px;
+        width: 24px;
+        margin: 0 7px;
+        padding: 1px 2px;
+        border: none;
+        background-color: transparent;
+        background-repeat: no-repeat;
+        background-position: center;
+        background-size: 24px;
+        cursor: pointer;
+
+        &.cw-ribbon-button-menu {
+            @include background-icon(table-of-contents, clickable, 24);
+        }
+
+        &.cw-ribbon-button-prev {
+            @include background-icon(arr_1left, clickable, 24);
+            margin: 0 0.5em 0 0;
+        }
+
+        &.cw-ribbon-button-next {
+            @include background-icon(arr_1right, clickable, 24);
+            margin: 0 1em 0 0;
+        }
+
+        &.cw-ribbon-button-prev-disabled {
+            @include background-icon(arr_1left, inactive, 24);
+            margin: 0 0.5em 0 0;
+            cursor: default;
+        }
+
+        &.cw-ribbon-button-next-disabled {
+            @include background-icon(arr_1right, inactive, 24);
+            margin: 0 1em 0 0;
+            cursor: default;
+        }
+    }
+
+    .cw-ribbon-action-menu {
+        vertical-align: text-top;
+        margin: 2px 0 0 2px;
+        &.is-open {
+            z-index: 32;
+        }
+    }
+}
+
+.cw-ribbon-tools {
+    background-color: var(--white);
+    border: solid thin var(--content-color-40);
+    box-shadow: 2px 2px var(--dark-gray-color-30);
+    position: absolute;
+    right: -570px;
+    top: 15px;
+    height: 100%;
+    max-width: calc(100% - 28px);
+    display: flex;
+    flex-flow: row;
+    transition: right 0.8s;
+    z-index: 42;
+
+    &.unfold {
+        right: 0px;
+        margin-right: 15px;
+    }
+
+    &.cw-ribbon-tools-consume {
+        position: fixed;
+
+        &.unfold {
+            right: 15px;
+        }
+    }
+
+    &.cw-ribbon-tools-sticky {
+        position: absolute;
+        top: -1px;
+        margin-right: 0;
+    }
+
+    .cw-ribbon-tool-content {
+        height: 100%;
+        width: 540px;
+        background-color: var(--white);
+        padding: 0;
+        overflow: hidden;
+
+        .cw-ribbon-tool-content-nav {
+            position: sticky;
+            height: 100%;
+            top: 0;
+            background-color: var(--white);
+            margin: 0;
+            padding: 0;
+            color: var(--base-color);
+            display: flex;
+            z-index: 43;
+
+            .cw-tools-hide-button {
+                position: absolute;
+                border: none;
+                height: 36px;
+                width: 24px;
+                min-width: 24px;
+                margin-right: 1em;
+                padding: 0 4px;
+                right: 0;
+                top: 12px;
+                cursor: pointer;
+                @include background-icon(decline, clickable, 24);
+                background-repeat: no-repeat;
+                background-size: 24px;
+                background-position: center right;
+                background-color: var(--white);
+            }
+
+            > .cw-ribbon-tool-content-tablist {
+                width: 100%;
+                height: 100%;
+
+                > .cw-tabs-nav {
+                    border: none;
+                    width: calc(100% - 48px);
+
+                    > button {
+                        padding: 18px 8px 4px 8px;
+                        margin-top: 2px;
+                        max-width: unset;
+                        flex-grow: 0.5;
+                        &::after {
+                            margin-top: 16px;
+                        }
+                    }
+                }
+
+                > .cw-tabs-content {
+                    border: none;
+                    border-top: solid thin var(--content-color-40);
+                    padding: 0;
+                    height: calc(100% - 58px);
+
+                    > .cw-tab {
+                        height: calc(100% - 22px);
+                        padding: 14px 8px 8px 8px;
+                        position: relative;
+                        overflow-y: auto;
+                        overflow-x: hidden;
+                        scrollbar-width: thin;
+                        scrollbar-color: var(--base-color) var(--white);
+
+                        &.cw-ribbon-tool-blockadder-tab {
+                            height: 100%;
+                            overflow: hidden;
+                            padding: 0;
+                        }
+                    }
+                }
+            }
+        }
+
+        .cw-ribbon-tool {
+            padding: 14px 8px 6px 8px;
+            height: calc(100% - 64px);
+            overflow-y: auto;
+            overflow-x: hidden;
+            scrollbar-width: thin;
+            scrollbar-color: var(--base-color) var(--white);
+        }
+    }
+}
+
+#courseware-public-index {
+    .cw-ribbon-tools {
+        top: 127px;
+
+        &.cw-ribbon-tools-consume {
+            top: 14px;
+        }
+
+        &.cw-ribbon-tools-sticky {
+            top: 56px;
+        }
+    }
+}
+
+.cw-structural-element-consumemode {
+    .cw-ribbon-tools {
+        top: 25px;
+    }
+}
+
+.responsive-display {
+    .cw-ribbon-sticky-top,
+    .cw-ribbon-sticky-bottom,
+    .cw-ribbon-wrapper-consume,
+    .cw-ribbon-consume-bottom {
+        width: 100%;
+    }
+
+    .cw-ribbon {
+        &.cw-ribbon-sticky {
+            width: calc(100% - 62px);
+        }
+    }
+
+    .cw-ribbon-sticky-spacer {
+        height: 75px;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/tabs.scss b/resources/assets/stylesheets/scss/courseware/layouts/tabs.scss
new file mode 100644
index 0000000000000000000000000000000000000000..aa12b5e929f46ba6804e1f8dea71e1a1af7bc56a
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/tabs.scss
@@ -0,0 +1,114 @@
+@use '../../../mixins.scss' as *;
+@import '../variables.scss';
+
+.cw-tabs-nav {
+    display: flex;
+    flex-wrap: wrap;
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    border: solid thin var(--content-color-40);
+    border-bottom: none;
+
+    button {
+        background-color: var(--white);
+        border: none;
+        padding: 1em 0 4px 0;
+        margin: 0 7px 0 21px;
+        color: var(--base-color);
+        cursor: pointer;
+        text-align: center;
+        flex-grow: 1;
+        max-width: max-content;
+
+        &::after {
+            display: block;
+            margin-top: 4px;
+            margin-bottom: -5px;
+            margin-left: -14px;
+            width: calc(100% + 28px);
+            content: '';
+            border-bottom: solid 3px var(--dark-gray-color-75);
+            transform: scaleX(0);
+            transition: transform var(--transition-duration) ease-in-out;
+        }
+
+        &.is-active,
+        &:hover {
+            color: var(--black);
+            &:after {
+                transform: scaleX(1);
+            }
+        }
+
+        @each $icon in $icons {
+            &.cw-tabs-nav-icon-text-#{$icon} {
+                &::before {
+                    @include background-icon($icon);
+                    background-repeat: no-repeat;
+                    background-position: left bottom;
+
+                    display: inline-block;
+                    height: 16px;
+                    width: 16px;
+                    margin-bottom: -2px;
+                    padding-left: 4px;
+                    content: '';
+                }
+            }
+            &.is-active.cw-tabs-nav-icon-text-#{$icon},
+            &.cw-tabs-nav-icon-text-#{$icon}:hover {
+                &::before {
+                    @include background-icon($icon, info);
+                }
+            }
+        }
+        @each $icon in $icons {
+            &.cw-tabs-nav-icon-solo-#{$icon} {
+                &::before {
+                    display: inline-block;
+                    height: 24px;
+                    width: 24px;
+                    content: '';
+
+                    @include background-icon($icon, clickable, 24);
+                    background-repeat: no-repeat;
+                    background-position: center;
+                }
+            }
+            &.is-active.cw-tabs-nav-icon-solo-#{$icon},
+            &.cw-tabs-nav-icon-solo-#{$icon}:hover {
+                &::before {
+                    @include background-icon($icon, info);
+                }
+            }
+        }
+    }
+
+    &:hover li {
+        &.is-active::after {
+            transform: scaleX(0);
+        }
+        &:hover::after {
+            transform: scaleX(1);
+        }
+    }
+}
+
+.cw-tabs-content {
+    border: solid thin var(--content-color-40);
+    padding: 4px;
+}
+
+.cw-tabs {
+    .cw-tab {
+        display: none;
+        height: 0;
+
+        &.cw-tab-active {
+            display: block;
+            height: unset;
+            padding: 4px 8px;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/talk-bubble.scss b/resources/assets/stylesheets/scss/courseware/layouts/talk-bubble.scss
new file mode 100644
index 0000000000000000000000000000000000000000..06062b692eeb0b087c082dcad2a29bb6ef5da68b
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/talk-bubble.scss
@@ -0,0 +1,58 @@
+.cw-talk-bubble {
+    margin: 10px 20px;
+    position: relative;
+    width: 85%;
+    height: auto;
+    background-color: var(--dark-gray-color-10);
+    float: left;
+
+    .cw-talk-bubble-talktext {
+        padding: 1em;
+        text-align: left;
+        line-height: 1.5em;
+
+        .cw-talk-bubble-talktext-time {
+            color: var(--dark-gray-color-80);
+            text-align: right;
+            font-size: 0.8em;
+            margin-bottom: -0.5em;
+        }
+    }
+
+    &.cw-talk-bubble-own-post {
+        float: right;
+    }
+
+    &:after {
+        content: ' ';
+        position: absolute;
+        width: 0;
+        height: 0;
+        top: 0px;
+        bottom: auto;
+        border: 22px solid;
+        border-color: var(--dark-gray-color-10) transparent transparent transparent;
+        left: -20px;
+        right: auto;
+    }
+
+    &.cw-talk-bubble-own-post:after {
+        left: auto;
+        right: -20px;
+    }
+
+    .cw-talk-bubble-user {
+        padding: 1em 1em 0 1em;
+
+        .cw-talk-bubble-avatar {
+            display: inline-block;
+        }
+
+        span {
+            padding-left: 4px;
+            color: var(--dark-gray-color-45);
+            font-weight: 600;
+            vertical-align: top;
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/tile.scss b/resources/assets/stylesheets/scss/courseware/layouts/tile.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f4c795f3ec8212a039bb8e7f981061320f4d5347
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/tile.scss
@@ -0,0 +1,157 @@
+.cw-tiles {
+    list-style: none;
+    display: flex;
+    flex-wrap: wrap;
+    padding-left: 0;
+    row-gap: 5px;
+    column-gap: 5px;
+}
+.cw-tiles .tile,
+.cw-tile {
+    height: 420px;
+    width: 270px;
+    margin: 0;
+    background-color: var(--base-color);
+    &:last-child {
+        margin-right: 0;
+    }
+
+    @each $name, $color in $tile-colors {
+        &.#{'' + $name} {
+            background-color: $color;
+        }
+    }
+
+    .preview-image {
+        height: 180px;
+        width: 100%;
+        background-size: 100% auto;
+        background-repeat: no-repeat;
+        background-color: var(--content-color-20);
+        background-position: center;
+        &.default-image {
+            @include background-icon(courseware, clickable, 128);
+        }
+
+        .overlay-text {
+            padding: 6px 7px;
+            margin: 4px;
+            background-color: rgba(255, 255, 255, 0.8);
+            width: fit-content;
+            max-width: 100%;
+            height: 1.25em;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            float: right;
+            text-align: right;
+        }
+
+        .overlay-action-menu {
+            padding: 0;
+            margin: 0.25em;
+            background-color: rgba(255, 255, 255, 0.8);
+            width: fit-content;
+            max-width: 100%;
+            overflow: hidden;
+            float: right;
+            text-align: right;
+            .action-menu {
+                margin: 5px;
+            }
+        }
+    }
+
+    .description {
+        height: 220px;
+        padding: 14px;
+        color: var(--white);
+        position: relative;
+        display: block;
+
+        header {
+            font-size: 20px;
+            line-height: 22px;
+            color: var(--white);
+            border: none;
+            width: 240px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            background-repeat: no-repeat;
+            background-position: 0 0;
+
+            @each $type, $icon in $element-icons {
+                &.description-icon-#{$type} {
+                    width: 212px;
+                    padding-left: 28px;
+                    @include background-icon(#{$icon}, info_alt, 22);
+                }
+            }
+        }
+
+        .progress-wrapper {
+            width: 100%;
+            padding: 1em 0;
+            border: none;
+            background: none;
+
+            progress {
+                appearance: none;
+                display: block;
+                width: 100%;
+                height: 3px;
+                margin: 0;
+                border: none;
+                background: rgba(0, 0, 0, 0.3);
+                &::-webkit-progress-bar {
+                    background: rgba(0, 0, 0, 0.3);
+                }
+                &::-webkit-progress-value {
+                    background: white;
+                }
+                &::-moz-progress-bar {
+                    background: white;
+                }
+            }
+        }
+
+        .description-text-wrapper {
+            overflow: hidden;
+            height: 10em;
+            margin-top: 0.5em;
+            display: -webkit-box;
+            margin-bottom: 1em;
+            -webkit-line-clamp: 7;
+            -webkit-box-orient: vertical;
+            p {
+                text-align: left;
+            }
+        }
+
+        footer {
+            width: 242px;
+            text-align: right;
+            color: var(--white);
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+
+            img {
+                vertical-align: text-bottom;
+            }
+        }
+    }
+
+    a[href].description {
+        transition: unset;
+    }
+
+    a.description,
+    a.description:link,
+    a.description:visited,
+    a.description:hover {
+        height: 210px;
+        color: var(--white);
+        text-decoration: unset;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/layouts/tree.scss b/resources/assets/stylesheets/scss/courseware/layouts/tree.scss
new file mode 100644
index 0000000000000000000000000000000000000000..5f976a22a2a0ae5cda5fdcc60cc82c21c121ea7b
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/layouts/tree.scss
@@ -0,0 +1,163 @@
+.cw-tree {
+    ol {
+        list-style: none;
+        padding-left: 1.25em;
+        margin-bottom: 20px;
+
+        &.cw-tree-root-list {
+            padding-left: 0;
+
+            > li.cw-tree-item {
+                > .cw-tree-item-wrapper {
+                    border-bottom: solid thin var(--content-color-40);
+                    display: block;
+
+                    > a.cw-tree-item-link {
+                        display: block;
+                        font-size: 18px;
+                        padding-left: 26px;
+                        @include background-icon(courseware, clickable, 18);
+                        background-repeat: no-repeat;
+                        background-position: 3px 3px;
+                    }
+                }
+
+                ol {
+                    padding-left: 0;
+
+                    > li.cw-tree-item {
+                        margin: 28px 0 0 0;
+
+                        > .cw-tree-item-wrapper {
+                            display: block;
+                            border-bottom: solid thin var(--content-color-40);
+                            margin-bottom: 12px;
+
+                            > a.cw-tree-item-link {
+                                display: inline-block;
+                                width: calc(100% - 4px);
+                                padding-left: 4px;
+                                font-size: 16px;
+
+                                &.cw-tree-item-link-edit {
+                                    width: calc(100% - 20px);
+                                }
+                            }
+                        }
+
+                        ol {
+                            padding-left: 0.25em;
+
+                            &.cw-tree-draggable-list {
+                                padding-left: 1em;
+                            }
+
+                            > li.cw-tree-item {
+                                margin: 4px 0;
+
+                                > .cw-tree-item-wrapper {
+                                    border: none;
+
+                                    > a.cw-tree-item-link {
+                                        display: inline-block;
+                                        border-bottom: none;
+                                        font-size: 14px;
+                                        width: calc(100% - 20px);
+                                        background-repeat: no-repeat;
+                                        padding-left: 18px;
+                                        margin-left: 4px;
+                                        margin-bottom: 0;
+
+                                        &.cw-tree-item-link-edit {
+                                            width: calc(100% - 38px);
+                                        }
+
+                                        @include background-icon(bullet-dot, clickable, 18);
+
+                                        &:hover {
+                                            @include background-icon(bullet-dot, attention, 18);
+                                        }
+
+                                        &.cw-tree-item-link-current {
+                                            @include background-icon(bullet-dot, info, 18);
+                                        }
+                                    }
+                                }
+
+                                ol {
+                                    padding-left: 1em;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    .cw-sortable-handle {
+        vertical-align: middle;
+    }
+
+    .cw-tree-item-link {
+        &:hover {
+            background-color: var(--light-gray-color-20);
+            color: var(--active-color);
+        }
+
+        &.cw-tree-item-link-current {
+            color: var(--black);
+            font-weight: 600;
+            cursor: default;
+
+            &::before {
+                color: var(--black);
+            }
+        }
+
+        &.cw-tree-item-link-selected {
+            font-style: italic;
+            font-weight: 600;
+        }
+
+        @each $type, $icon in $tree-item-flag-icons {
+            .cw-tree-item-flag-#{$type} {
+                display: inline-block;
+                width: 16px;
+                height: 16px;
+                vertical-align: top;
+                @include background-icon(#{$icon}, clickable, 16);
+            }
+
+            &:hover .cw-tree-item-flag-#{$type} {
+                @include background-icon(#{$icon}, attention, 16);
+            }
+
+            &.cw-tree-item-link-current .cw-tree-item-flag-#{$type} {
+                @include background-icon(#{$icon}, info, 16);
+            }
+        }
+    }
+
+    .cw-tree-item-sequential {
+        display: inline-block;
+        position: absolute;
+        right: 8px;
+
+        &.cw-tree-item-sequential-complete {
+            width: 16px;
+            height: 16px;
+            vertical-align: top;
+            @include background-icon(accept, info, 16);
+        }
+
+        &.cw-tree-item-sequential-percentage {
+            color: var(--black);
+            font-size: 14px;
+        }
+    }
+
+    .cw-tree-item-ghost {
+        opacity: 0.6;
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/shelf.scss b/resources/assets/stylesheets/scss/courseware/shelf.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a7b3eabdf5f8c5fa86758459b08f9e7af2505a67
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/shelf.scss
@@ -0,0 +1,53 @@
+@use '../../mixins.scss' as *;
+
+.cw-contents-overview-teaser {
+    max-width: 782px;
+    background-color: var(--content-color-20);
+    background-image: url('#{$image-path}/courseware-keyvisual-negative.svg');
+    background-repeat: no-repeat;
+    background-size: 196px;
+    background-position-y: 50%;
+    background-position-x: 24px;
+    padding: 24px;
+    margin-bottom: 10px;
+
+    .cw-contents-overview-teaser-content {
+        padding-left: 220px;
+
+        header {
+            font-size: 1.5em;
+            margin-bottom: 0.5em;
+        }
+    }
+}
+
+.responsive-display {
+    .cw-contents-overview-teaser {
+        max-width: 782px;
+        background-size: 60%;
+        background-position-y: 24px;
+        background-position-x: 50%;
+        padding: 24px;
+        margin-bottom: 10px;
+
+        .cw-contents-overview-teaser-content {
+            padding-top: 28%;
+            padding-left: 0;
+            text-align: justify;
+
+            header {
+                font-size: 1.5em;
+                margin: 1em 0 0.5em 0;
+                text-align: center;
+            }
+        }
+    }
+}
+
+.cw-unit-items,
+.cw-shared-items {
+    margin-bottom: 10px;
+    h2 {
+        margin-top: 0;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/sortable.scss b/resources/assets/stylesheets/scss/courseware/sortable.scss
new file mode 100644
index 0000000000000000000000000000000000000000..107b3a8056ab3ab0ec016802349724c81d9332d4
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/sortable.scss
@@ -0,0 +1,57 @@
+@import '../drag-handle.scss';
+
+.cw-sortable-handle {
+    @extend .drag-handle;
+    display: inline-block;
+    height: 24px;
+    &.cw-sortable-handle-dragging {
+        cursor: grabbing;
+    }
+}
+
+.cw-block-item-sortable {
+    .cw-sortable-handle {
+        position: relative;
+        left: 4px;
+    }
+    .cw-block {
+        margin-top: -38px;
+    }
+}
+
+.cw-container-item-sortable {
+    .cw-sortable-handle {
+        position: relative;
+        left: 4px;
+    }
+    .cw-container {
+        margin-top: -38px;
+    }
+}
+
+.container-ghost,
+.block-ghost {
+    opacity: 0.6;
+}
+
+
+.cw-container-wrapper-edit {
+    .cw-structural-element-list {
+        width: 100%;
+        padding: 0;
+        margin-top: 8px;
+        list-style: none;
+    }
+}
+
+.cw-block-item-selected {
+    .cw-block-header {
+        font-style: italic;
+    }
+}
+
+.cw-container-item-selected {
+    .cw-container-header {
+        font-style: italic;
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/structural-element.scss b/resources/assets/stylesheets/scss/courseware/structural-element.scss
new file mode 100644
index 0000000000000000000000000000000000000000..917684d110de034098a26b4ec093b3b5cd1e4878
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/structural-element.scss
@@ -0,0 +1,273 @@
+@use '../../mixins.scss' as *;
+@import './variables.scss';
+
+#course-courseware-index,
+#contents-courseware-index,
+#course-courseware-courseware,
+#contents-courseware-courseware {
+    form.default input[type=date] {
+        max-width: 9em;
+    }
+}
+
+.cw-structural-element {
+    &.cw-structural-element-consumemode {
+        position: fixed;
+        top: 0;
+        left: 0;
+        height: 100%;
+        width: 100%;
+        padding: 0;
+        background-color: var(--white);
+        z-index: 1004;
+        overflow-y: scroll;
+        overflow-x: hidden;
+        scrollbar-width: thin;
+        scrollbar-color: var(--base-color) var(--dark-gray-color-5);
+    }
+
+    .cw-welcome-screen {
+        .cw-welcome-screen-keyvisual {
+            margin: 14px 0 42px 0;
+            width: 100%;
+            height: 400px;
+            background-image: url('#{$image-path}/courseware-keyvisual.svg');
+            background-repeat: no-repeat;
+            background-position: center center;
+        }
+
+        header {
+            padding: 0.5em 0;
+            text-align: center;
+            font-size: 2.25em;
+        }
+
+        .cw-welcome-screen-actions {
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+    }
+
+    .cw-structural-element-discussion {
+        max-width: 1606px;
+        width: 100%;
+        margin-bottom: 1em;
+    }
+
+    .cw-container-wrapper {
+        max-width: $max-content-width;
+        margin: 0;
+        padding: 0;
+        display: flex;
+        flex-wrap: wrap;
+        align-items: stretch;
+        justify-content: space-between;
+
+        &.cw-container-wrapper-consume {
+            margin: 0 auto;
+            padding: 91px 15px 15px 15px;
+        }
+
+        &.cw-container-wrapper-discuss {
+            max-width: 1606px;
+        }
+    }
+
+    .cw-structural-element-description {
+        width: 400px;
+        height: 200px;
+        overflow-y: auto;
+        resize: none;
+    }
+
+    .cw-structural-element-color {
+        color: var(--white);
+        &.black {
+            background-color: map-get($tile-colors, 'black');
+        }
+        &.charcoal {
+            background-color: map-get($tile-colors, 'charcoal');
+        }
+        &.royal-purple {
+            background-color: map-get($tile-colors, 'royal-purple');
+        }
+        &.iguana-green {
+            background-color: map-get($tile-colors, 'iguana-green');
+        }
+        &.queen-blue {
+            background-color: map-get($tile-colors, 'queen-blue');
+        }
+        &.verdigris {
+            background-color: map-get($tile-colors, 'verdigris');
+        }
+        &.mulberry {
+            background-color: map-get($tile-colors, 'mulberry');
+        }
+        &.pumpkin {
+            background-color: map-get($tile-colors, 'pumpkin');
+        }
+        &.sunglow {
+            background-color: map-get($tile-colors, 'sunglow');
+        }
+        &.apple-green {
+            background-color: map-get($tile-colors, 'apple-green');
+        }
+
+        &.studip-blue {
+            background-color: map-get($tile-colors, 'studip-blue');
+        }
+        &.studip-lightblue {
+            background-color: map-get($tile-colors, 'studip-lightblue');
+        }
+        &.studip-red {
+            background-color: map-get($tile-colors, 'studip-red');
+        }
+        &.studip-green {
+            background-color: map-get($tile-colors, 'studip-green');
+        }
+        &.studip-yellow {
+            background-color: map-get($tile-colors, 'studip-yellow');
+        }
+        &.studip-gray {
+            background-color: map-get($tile-colors, 'studip-gray');
+        }
+    }
+
+    .cw-structural-element-info {
+        width: 600px;
+        tr:first-child {
+            width: 12em;
+            vertical-align: top;
+        }
+    }
+
+    .cw-companion-box-wrapper {
+        width: 100%;
+        max-width: $max-content-width;
+    }
+}
+
+.cw-structural-element-dialog {
+    input[type='text'] {
+        width: 20em;
+    }
+}
+
+.cw-structural-element-image-preview {
+    display: block;
+    max-height: 200px;
+    max-width: 400px;
+    width: auto;
+    height: auto;
+    margin: 0 auto;
+    padding-bottom: 1em;
+}
+
+.cw-structural-element-image-preview-placeholder {
+    width: 356px;
+    height: 200px;
+    margin: 0 auto;
+    background-color: var(--content-color-20);
+    background-size: 100% auto;
+    background-repeat: no-repeat;
+    background-position: center;
+    @include background-icon(courseware, clickable, 128);
+    margin-bottom: 1em;
+}
+
+.cw-element-permissions {
+    label {
+        display: block;
+        padding: 6px 0;
+    }
+    table.default {
+        > caption {
+            padding: 0;
+            font-size: 1.25em;
+        }
+        td.perm {
+            input.right,
+            input.date {
+                cursor: pointer !important;
+            }
+        }
+    }
+    button.cw-add-persons {
+        margin-left: 4px;
+    }
+    button.cw-permission-delete {
+        width: 24px;
+        height: 24px;
+        border: none;
+        background-color: transparent;
+        @include background-icon(trash, clickable);
+        background-repeat: no-repeat;
+        cursor: pointer;
+    }
+}
+
+.cw-element-export {
+    label {
+        input {
+            vertical-align: middle;
+        }
+
+        span {
+            vertical-align: middle;
+        }
+    }
+}
+
+.studip-dialog-with-tab {
+    .studip-dialog-body .studip-dialog-content {
+        padding: 0 4px;
+        .cw-tab-in-dialog {
+            .cw-tabs-nav {
+                border: none;
+                border-bottom: solid thin var(--content-color-40);
+                margin-bottom: 4px;
+            }
+            .cw-tabs-content {
+                border: none;
+                min-width: 500px;
+                min-height: 400px;
+                overflow-y: auto;
+                scrollbar-width: thin;
+                scrollbar-color: var(--base-color) var(--dark-gray-color-5);
+            }
+        }
+    }
+}
+
+@media only screen and (max-width: 1820px) {
+    .cw-structural-element .cw-container-wrapper.cw-container-wrapper-discuss {
+        max-width: $max-content-width;
+        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-full {
+            .cw-default-block {
+                flex-flow: column;
+                .cw-discuss-wrapper {
+                    margin-left: 0;
+                    margin-top: 8px;
+                }
+            }
+        }
+    }
+}
+
+@media only screen and (max-width: 1200px) {
+    .cw-structural-element .cw-container-wrapper.cw-container-wrapper-discuss {
+        max-width: $max-content-width;
+        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-half,
+        .cw-container.cw-container-list.cw-container-item.cw-container-colspan-half-center {
+            .cw-default-block {
+                flex-flow: column;
+                .cw-discuss-wrapper {
+                    margin-left: 0;
+                    margin-top: 8px;
+                    max-width: 540px;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/variables.scss b/resources/assets/stylesheets/scss/courseware/variables.scss
new file mode 100644
index 0000000000000000000000000000000000000000..af97f927b570ca9e37050bfb0bcc8584fbda6996
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/variables.scss
@@ -0,0 +1,205 @@
+$element-icons: (
+    content: content2,
+    draft: category-draft,
+    task: category-task,
+    template: category-template,
+    oer: oer-campus,
+    other: category-others,
+    portfolio: category-portfolio
+);
+
+$tree-item-flag-icons: (
+    date: date,
+    write: edit,
+    cant-read: lock-locked2,
+);
+
+$tile-colors: (
+    black: #000,
+    charcoal: #3c454e,
+    royal-purple: #8656a2,
+    iguana-green: #66b570,
+    queen-blue: #536d96,
+    verdigris: #41afaa,
+    mulberry: #bf5796,
+    pumpkin: #f26e00,
+    sunglow: #ffca5c,
+    apple-green: #8bbd40,
+    studip-blue: #28497c,
+    studip-lightblue: #e7ebf1,
+    studip-red: #d60000,
+    studip-green: #008512,
+    studip-yellow: #ffbd33,
+    studip-gray: #636a71,
+);
+
+$icon-colors:(
+    icon-white: #ffffff,
+    icon-black: #000000,
+    icon-red: #cb1800,
+    icon-blue: #24437c,
+    icon-green: #00962d,
+    icon-gray: #6e6e6e,
+    icon-yellow: #ffad00
+);
+$border-colors:(
+    white: #ffffff,
+    black: #000000,
+    studip-red: #cb1800,
+    studip-blue: #24437c,
+    studip-green: #00962d,
+    studip-gray: #6e6e6e,
+    studip-yellow: #ffad00
+);
+
+$blockadder-items: (
+    before-after: block-comparison,
+    canvas: block-canvas,
+    gallery: block-gallery,
+    image-map: block-imagemap,
+    audio: audio,
+    chart: vote,
+    code: computer,
+    confirm: accept,
+    date: date,
+    dialog-cards: dialog-cards,
+    document: file-text,
+    download: download,
+    embed: code,
+    folder: folder-full,
+    headline: block-eyecatcher,
+    iframe: door-enter,
+    lti: plugin,
+    key-point: exclaim-circle,
+    link: link-extern,
+    table-of-contents: table-of-contents,
+    text: edit,
+    timeline: date-cycle,
+    typewriter: block-typewriter,
+    video: video2,
+    biography-achievements: medal,
+    biography-career: ranking,
+    biography-personal-information: own-license,
+    biography-goals: radar
+);
+
+$containeradder-items: (
+    accordion: block-accordion,
+    list: view-list,
+    tabs: block-tabs,
+);
+
+$cw-wrapper-gap: 0.5em;
+
+$icons: (
+    accept,
+    add,
+    add-circle,
+    admin,
+    aladdin,
+    arr_1down,
+    arr_1left,
+    arr_1right,
+    arr_1up,
+    arr_2down,
+    arr_2left,
+    arr_2right,
+    arr_2up,
+    audio,
+    audio3,
+    billboard,
+    block-canvas,
+    block-comparison,
+    block-eyecatcher,
+    block-gallery,
+    block-gallery2,
+    block-imagemap,
+    brainstorm,
+    campusnavi,
+    chat2,
+    code,
+    community2,
+    computer,
+    consultation,
+    content,
+    courseware,
+    crown,
+    date-single,
+    decline,
+    decline-circle,
+    doctoral_cap,
+    download,
+    dropbox,
+    edit,
+    exclaim,
+    exclaim-circle,
+    export,
+    favorite,
+    filter,
+    globe,
+    graph,
+    group2,
+    group3,
+    group4,
+    home2,
+    info,
+    info-circle,
+    install,
+    institute,
+    key,
+    knife,
+    learnmodule,
+    lightbulb,
+    lightbulb2,
+    link2,
+    link3,
+    link-extern,
+    link-intern,
+    literature,
+    lock-locked,
+    lock-unlocked,
+    mail2,
+    medal,
+    metro,
+    microphone,
+    module,
+    network,
+    notification,
+    notification2,
+    opencast,
+    outer-space,
+    permalink,
+    person,
+    phone,
+    picture,
+    place,
+    plugin,
+    question,
+    question-circle,
+    ranking,
+    remove,
+    remove-circle,
+    resources,
+    roles,
+    schedule2,
+    search,
+    settings,
+    span-empty,
+    span-1quarter,
+    span-2quarter,
+    span-3quarter,
+    span-full,
+    spiral,
+    sport,
+    staple,
+    star,
+    star-empty,
+    star-halffull,
+    test,
+    tools,
+    topic,
+    ufo,
+    video2,
+    visibility-visible,
+    wizard
+);
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/courseware/widgets.scss b/resources/assets/stylesheets/scss/courseware/widgets.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d5db20ca4b57030b57f5498a8906a03dc3b35614
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/widgets.scss
@@ -0,0 +1,56 @@
+.cw-action-widget {
+    .cw-action-widget-show-toc {
+        @include background-icon(table-of-contents, clickable);
+    }
+    .cw-action-widget-edit {
+        @include background-icon(edit, clickable);
+    }
+    .cw-action-widget-sort {
+        @include background-icon(arr_1sort, clickable);
+    }
+    .cw-action-widget-add {
+        @include background-icon(add, clickable);
+    }
+    .cw-action-widget-info {
+        @include background-icon(info, clickable);
+    }
+    .cw-action-widget-star {
+        @include background-icon(star, clickable);
+    }
+    .cw-action-widget-trash {
+        @include background-icon(trash, clickable);
+    }
+    .cw-action-widget-oer {
+        @include background-icon(oer-campus, clickable);
+    }
+    .cw-action-widget-remove-lock {
+        @include background-icon(lock-unlocked, clickable);
+    }
+}
+
+.cw-export-widget {
+    .cw-export-widget-export {
+        @include background-icon(export, clickable);
+    }
+    .cw-export-widget-export-pdf {
+        @include background-icon(export, clickable);
+    }
+    .cw-export-widget-oer {
+        @include background-icon(share, clickable);
+    }
+}
+
+.cw-import-widget {
+    .cw-import-widget-archive {
+        @include background-icon(import, clickable);
+    }
+    .cw-import-widget-copy {
+        @include background-icon(copy, clickable);
+    }
+    .cw-import-widget-import {
+        @include background-icon(import, clickable);
+    }
+    .cw-action-widget-link {
+        @include background-icon(group, clickable);
+    }
+}
diff --git a/resources/assets/stylesheets/scss/courseware/wizards.scss b/resources/assets/stylesheets/scss/courseware/wizards.scss
new file mode 100644
index 0000000000000000000000000000000000000000..953f5104dbf5b32c86ff12a95630b74b59ba9aef
--- /dev/null
+++ b/resources/assets/stylesheets/scss/courseware/wizards.scss
@@ -0,0 +1,57 @@
+.cw-element-selector-list {
+    list-style: none;
+    padding: 0;
+
+    .cw-element-selector-item {
+        display: block;
+        width: 100%;
+        border: solid thin var(--content-color-40);
+        padding: 0.5em;
+        margin-bottom: 5px;
+        background-color: var(--white);
+        color: var(--base-color);
+        text-align: left;
+        cursor: pointer;
+
+        &:hover {
+            color: var(--white);
+            background-color: var(--base-color);
+        }
+    }
+}
+
+form.default .courseware-structural-element-selector {
+    list-style: none;
+    padding-left: 0;
+
+    .courseware-structural-element-selector-item {
+        .radiobutton {
+            background: none;
+            border: none;
+            padding: 0;
+        }
+
+        a label {
+            cursor: pointer;
+        }
+
+        label {
+            display: inline-block;
+            margin-bottom: 0;
+            text-indent: 0;
+            vertical-align: middle;
+        }
+
+        img {
+            vertical-align: middle;
+            &.inactive {
+                opacity: 0.5;
+            }
+        }
+
+        ul {
+            list-style: none;
+            padding-left: 18px;
+        }
+    }
+}
diff --git a/resources/assets/stylesheets/scss/progress_indicator.scss b/resources/assets/stylesheets/scss/progress_indicator.scss
index 55358f4c2028ebc1f0a770f8fa782361bc26a16c..1bf0d1a34d0982335da35ce1bb64bd177be7e98c 100644
--- a/resources/assets/stylesheets/scss/progress_indicator.scss
+++ b/resources/assets/stylesheets/scss/progress_indicator.scss
@@ -3,6 +3,10 @@
     display: flex;
     flex-direction: column;
 
+    &.loading-indicator-content {
+        margin-top: 76px;
+    }
+
     .progress-indicator {
         width: 100%;
         background-image: url("#{$image-path}/loading-indicator.svg");
diff --git a/resources/vue/components/blubber/Panel.vue b/resources/vue/components/blubber/Panel.vue
index 12f15a263b69f4314caff9f2eb69db1ad3f3fbd3..f70d1f637a2fd7cf565828b51f6709b551a24cb7 100644
--- a/resources/vue/components/blubber/Panel.vue
+++ b/resources/vue/components/blubber/Panel.vue
@@ -1,6 +1,6 @@
 <template>
     <StudipProgressIndicator
-        class="cw-loading-indicator-content"
+        class="loading-indicator-content"
         :description="$gettext('Lade Kommentare...')"
         v-if="!doneFetching"
     />
diff --git a/resources/vue/components/courseware/ActivitiesApp.vue b/resources/vue/components/courseware/ActivitiesApp.vue
index 7bf8e238c941ddaaf59ae0c2ba9ad7a562b07fda..cfbce77b433257ddab75e5d7e3ff027022f16a10 100644
--- a/resources/vue/components/courseware/ActivitiesApp.vue
+++ b/resources/vue/components/courseware/ActivitiesApp.vue
@@ -12,8 +12,8 @@
 
 <script>
 import CoursewareActivities from './CoursewareActivities.vue';
-import CoursewareActivitiesWidgetFilterType from './CoursewareActivitiesWidgetFilterType.vue';
-import CoursewareActivitiesWidgetFilterUnit from './CoursewareActivitiesWidgetFilterUnit.vue';
+import CoursewareActivitiesWidgetFilterType from './widgets/CoursewareActivitiesWidgetFilterType.vue';
+import CoursewareActivitiesWidgetFilterUnit from './widgets/CoursewareActivitiesWidgetFilterUnit.vue';
 import { mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/AdminApp.vue b/resources/vue/components/courseware/AdminApp.vue
index d210558b18b94dfb6a663dab72c7d91136fcefcd..4f2df7bbbcabfe2ff5aabbde5dd47bde4d4e3ae3 100644
--- a/resources/vue/components/courseware/AdminApp.vue
+++ b/resources/vue/components/courseware/AdminApp.vue
@@ -12,9 +12,9 @@
 </template>
 
 <script>
-import CoursewareAdminActionWidget from './CoursewareAdminActionWidget.vue';
+import CoursewareAdminActionWidget from './widgets/CoursewareAdminActionWidget.vue';
 import CoursewareAdminTemplates from './CoursewareAdminTemplates.vue';
-import CoursewareAdminViewWidget from './CoursewareAdminViewWidget.vue';
+import CoursewareAdminViewWidget from './widgets/CoursewareAdminViewWidget.vue';
 import { mapGetters, mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CommentsApp.vue b/resources/vue/components/courseware/CommentsApp.vue
index 1716d4ddf7165a24d2fc8cc7bdafe685ec3252ab..417423b28a0f04ca040ae1363357b8685a3f45bc 100644
--- a/resources/vue/components/courseware/CommentsApp.vue
+++ b/resources/vue/components/courseware/CommentsApp.vue
@@ -17,9 +17,9 @@
 <script>
 import CoursewareBlockCommentsOverview from './CoursewareBlockCommentsOverview.vue';
 import CoursewareStructuralElementCommentsOverview from './CoursewareStructuralElementCommentsOverview.vue';
-import CoursewareCommentsOverviewWidgetFilterType from './CoursewareCommentsOverviewWidgetFilterType.vue';
-import CoursewareCommentsOverviewWidgetFilterCreated from './CoursewareCommentsOverviewWidgetFilterCreated.vue';
-import CoursewareCommentsOverviewWidgetFilterUnit from './CoursewareCommentsOverviewWidgetFilterUnit.vue';
+import CoursewareCommentsOverviewWidgetFilterType from './widgets/CoursewareCommentsOverviewWidgetFilterType.vue';
+import CoursewareCommentsOverviewWidgetFilterCreated from './widgets/CoursewareCommentsOverviewWidgetFilterCreated.vue';
+import CoursewareCommentsOverviewWidgetFilterUnit from './widgets/CoursewareCommentsOverviewWidgetFilterUnit.vue';
 
 import { mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/ContentReleasesApp.vue b/resources/vue/components/courseware/ContentReleasesApp.vue
index 1a2ed6fcc9c7164901022cfe89cb18f971b69c9d..68aed78bcced81ca579865714175ed0a0b1b5c77 100644
--- a/resources/vue/components/courseware/ContentReleasesApp.vue
+++ b/resources/vue/components/courseware/ContentReleasesApp.vue
@@ -9,7 +9,7 @@
 <script>
 import CoursewareContentLinks from './CoursewareContentLinks.vue';
 import CoursewareContentShared from './CoursewareContentShared.vue';
-import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
+import CoursewareCompanionOverlay from './layouts/CoursewareCompanionOverlay.vue';
 
 export default {
     components: {
diff --git a/resources/vue/components/courseware/CoursewareActivities.vue b/resources/vue/components/courseware/CoursewareActivities.vue
index aab705f4ee9b15937219f693f59190882fd1c22d..a236842c7e06ce96e718dd13f3816614a6a50257 100644
--- a/resources/vue/components/courseware/CoursewareActivities.vue
+++ b/resources/vue/components/courseware/CoursewareActivities.vue
@@ -20,7 +20,7 @@
 
 <script>
 import CoursewareActivityItem from './CoursewareActivityItem.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
 import StudipProgressIndicator from '../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareBlockHelper.vue b/resources/vue/components/courseware/CoursewareBlockHelper.vue
deleted file mode 100644
index 1a709f8e100e8138aaa60dfc909f90b8e047e8d9..0000000000000000000000000000000000000000
--- a/resources/vue/components/courseware/CoursewareBlockHelper.vue
+++ /dev/null
@@ -1,256 +0,0 @@
-<template>
-    <div class="block-helper">
-        <courseware-companion-box :msgCompanion="currentQuestion.text" :mood="companionMood"/>
-        <div v-if="showBlocks" class="cw-block-helper-results cw-element-adder-wrapper ">
-            <courseware-blockadder-item
-                v-for="(block, index) in selectedBlockTypes"
-                :key="index"
-                :title="block.title"
-                :type="block.type"
-                :description="block.description"
-                @blockAdded="resetQuestions"
-            />
-        </div>
-        <div class="cw-block-helper-buttons">
-            <button
-                v-for="(response, index) in currentQuestion.responses"
-                class="button"
-                :key="index"
-                @click="setQuestion(response.answer)"
-            >
-                {{ response.text }}
-            </button>
-
-            <button v-if="currentQuestionId !== 'a'" class="button cw-block-helper-reset" @click="resetQuestions">
-                <translate>Zurücksetzen</translate>
-            </button>
-        </div>
-    </div>
-</template>
-
-<script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareBlockadderItem from './CoursewareBlockadderItem.vue';
-import { mapGetters } from 'vuex';
-
-export default {
-    name: 'courseware-block-helper',
-    components: {
-        CoursewareCompanionBox,
-        CoursewareBlockadderItem,
-    },
-
-    data() {
-        return {
-            companionMood: 'pointing',
-            questions: [
-                {
-                    id: 'a',
-                    text: this.$gettext(
-                        'Ich helfe Ihnen bei der Auswahl des richtigen Blocks. Beantworten Sie mir einfach ein paar Fragen. Meine Vorschläge werden dann hier anzeigen.'
-                    ),
-                    responses: [
-                        {
-                            text: this.$gettext('Ok'),
-                            answer: 'b',
-                        },
-                    ],
-                    blockChooser: false,
-                },
-                {
-                    id: 'b',
-                    text: this.$gettext('Kommt der Inhalt von einer anderen Plattform, z.B. Youtube?'),
-                    responses: [
-                        {
-                            text: this.$gettext('Ja'),
-                            answer: 'c',
-                        },
-                        {
-                            text: this.$gettext('Nein'),
-                            answer: 'd',
-                        },
-                    ],
-                    blockChooser: false,
-                },
-                {
-                    id: 'c',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: 'external', fileType: false },
-                },
-                {
-                    id: 'd',
-                    text: this.$gettext('Enthält der Inhalt eine oder mehrere Dateien?'),
-                    responses: [
-                        {
-                            text: this.$gettext('Ja'),
-                            answer: 'e',
-                        },
-                        {
-                            text: this.$gettext('Nein'),
-                            answer: 'f',
-                        },
-                    ],
-                    blockChooser: false,
-                },
-                {
-                    id: 'f',
-                    text: this.$gettext('Handelt es sich bei dem Inhalt hauptsächlich um Text?'),
-                    responses: [
-                        {
-                            text: this.$gettext('Ja'),
-                            answer: 'g',
-                        },
-                        {
-                            text: this.$gettext('Nein'),
-                            answer: 'h',
-                        },
-                    ],
-                    blockChooser: false,
-                },
-                {
-                    id: 'g',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: 'text', fileType: false },
-                },
-                {
-                    id: 'h',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: 'layout', fileType: false },
-                },
-                {
-                    id: 'e',
-                    text: this.$gettext('Um weleche Art von Datei(en) handelt es sich?'),
-                    responses: [
-                        {
-                            text: this.$gettext('Audio'),
-                            answer: 'i',
-                        },
-                        {
-                            text: this.$gettext('Bild'),
-                            answer: 'j',
-                        },
-                        {
-                            text: this.$gettext('Dokument'),
-                            answer: 'k',
-                        },
-                        {
-                            text: this.$gettext('Video'),
-                            answer: 'l',
-                        },
-                        {
-                            text: this.$gettext('beliebig'),
-                            answer: 'm',
-                        },
-                    ],
-                    blockChooser: false,
-                },
-                {
-                    id: 'i',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: false, fileType: 'audio' },
-                },
-                {
-                    id: 'j',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: false, fileType: 'image' },
-                },
-                {
-                    id: 'k',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: false, fileType: 'document' },
-                },
-                {
-                    id: 'l',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: false, fileType: 'video' },
-                },
-                {
-                    id: 'm',
-                    text: this.$gettext('Prima! Hier sind meine Vorschläge.'),
-                    responses: [],
-                    blockChooser: { category: false, fileType: 'all' },
-                },
-            ],
-            currentQuestionId: 'a',
-            showBlocks: false,
-            selectedBlockTypes: [],
-        };
-    },
-    computed: {
-        ...mapGetters({ blockTypes: 'blockTypes' }),
-        currentQuestion() {
-            let question = {};
-            let view = this;
-            this.questions.forEach((q) => {
-                if (q.id === view.currentQuestionId) {
-                    question = q;
-                }
-            });
-            return question;
-        },
-    },
-    methods: {
-        blockChooser(choice) {
-            if (choice.category) {
-                this.setSelectedBlockTypesByCategory(choice.category);
-                this.showBlocks = true;
-            } else if (choice.fileType) {
-                this.setSelectedBlockTypesByFileTypes(choice.fileType);
-                this.showBlocks = true;
-            }
-        },
-        setQuestion(q) {
-            this.currentQuestionId = q;
-            if(this.currentQuestion.responses.length === 0) {
-                this.companionMood= 'special';
-            } else {
-                this.companionMood= 'unsure';
-            }
-        },
-        setSelectedBlockTypesByCategory(cat) {
-            this.selectedBlockTypes = [];
-
-            this.blockTypes.forEach((block) => {
-                if (block.categories.includes(cat)) {
-                    this.selectedBlockTypes.push(block);
-                }
-            });
-            this.selectedBlockTypes.sort((a, b) => {
-                return a.title > b.title ? 1 : b.title > a.title ? -1 : 0;
-            });
-        },
-        setSelectedBlockTypesByFileTypes(type) {
-            this.selectedBlockTypes = [];
-
-            this.blockTypes.forEach((block) => {
-                if (type === 'all' && block.file_types.length > 0) {
-                    this.selectedBlockTypes.push(block);
-                } else if (block.file_types.includes(type)) {
-                    this.selectedBlockTypes.push(block);
-                }
-            });
-            this.selectedBlockTypes.sort((a, b) => {
-                return a.title > b.title ? 1 : b.title > a.title ? -1 : 0;
-            });
-        },
-        resetQuestions() {
-            this.currentQuestionId = 'a';
-            this.showBlocks = false;
-            this.selectedBlockTypes = [];
-            this.companionMood= 'pointing';
-        },
-    },
-    watch: {
-        currentQuestionId() {
-            this.blockChooser(this.currentQuestion.blockChooser);
-        },
-    },
-};
-</script>
diff --git a/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue b/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue
index 3858479e742c14cea4c2685a2a652325dc693ec3..825ee8fb3cc29df63b5c002dc74192ec9451a806 100644
--- a/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue
+++ b/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue
@@ -31,17 +31,17 @@
 </template>
 
 <script>
-import CoursewareBlockComments from './CoursewareBlockComments.vue';
-import CoursewareStructuralElementComments from './CoursewareStructuralElementComments.vue';
-import CoursewareBlockFeedback from './CoursewareBlockFeedback.vue';
-import CoursewareStructuralElementFeedback from './CoursewareStructuralElementFeedback.vue';
+import CoursewareBlockComments from './blocks/CoursewareBlockComments.vue';
+import CoursewareBlockFeedback from './blocks/CoursewareBlockFeedback.vue';
+import CoursewareStructuralElementComments from './structural-element/CoursewareStructuralElementComments.vue';
+import CoursewareStructuralElementFeedback from './structural-element/CoursewareStructuralElementFeedback.vue';
 
 export default {
     name: 'courseware-comments-overview-dialog',
     components: {
         CoursewareBlockComments,
-        CoursewareStructuralElementComments,
         CoursewareBlockFeedback,
+        CoursewareStructuralElementComments,
         CoursewareStructuralElementFeedback
     },
     props: {
diff --git a/resources/vue/components/courseware/CoursewareDashboardStudents.vue b/resources/vue/components/courseware/CoursewareDashboardStudents.vue
index 897388dbb4c5d7dcf4d99fcf102648fa2829d02a..ff59669729a601d3373bf5705a56475595de1cc1 100644
--- a/resources/vue/components/courseware/CoursewareDashboardStudents.vue
+++ b/resources/vue/components/courseware/CoursewareDashboardStudents.vue
@@ -233,8 +233,8 @@
 <script>
 import StudipIcon from './../StudipIcon.vue';
 import StudipDialog from './../StudipDialog.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareDateInput from './CoursewareDateInput.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
+import CoursewareDateInput from './layouts/CoursewareDateInput.vue';
 import CoursewareTasksDialogDistribute from './CoursewareTasksDialogDistribute.vue';
 import taskHelperMixin from '../../mixins/courseware/task-helper.js';
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareDashboardTasks.vue b/resources/vue/components/courseware/CoursewareDashboardTasks.vue
index 8bee6f552c4e41b01280a060f047aab6bedbecfe..caaea0bb1b6f654782b34cc392a2bd95e2d0649c 100644
--- a/resources/vue/components/courseware/CoursewareDashboardTasks.vue
+++ b/resources/vue/components/courseware/CoursewareDashboardTasks.vue
@@ -102,10 +102,10 @@
     </div>
 </template>
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import StudipIcon from './../StudipIcon.vue';
-import StudipActionMenu from './../StudipActionMenu.vue';
-import StudipDialog from './../StudipDialog.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
+import StudipIcon from '../StudipIcon.vue';
+import StudipActionMenu from '../StudipActionMenu.vue';
+import StudipDialog from '../StudipDialog.vue';
 import taskHelperMixin from '../../mixins/courseware/task-helper.js';
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareDefaultBlockElements.vue b/resources/vue/components/courseware/CoursewareDefaultBlockElements.vue
deleted file mode 100644
index 17d8834ee1edd064e7f7343dfd897fa2e4fd5927..0000000000000000000000000000000000000000
--- a/resources/vue/components/courseware/CoursewareDefaultBlockElements.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-<template>
-    <div class="cw-default-block-elements">
-        <courseware-block-actions
-            :block="block"
-            :canEdit="canEdit"
-            @editBlock="editBlock"
-            @showExportOptions="showExportOptions"
-        />
-        <courseware-block-feedback v-if="canEdit" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" />
-        <courseware-block-comments :block="block" />
-        <courseware-block-export-options v-if="canEdit" :block="block" />
-    </div>
-</template>
-
-<script>
-import CoursewareBlockActions from './CoursewareBlockActions.vue';
-import CoursewareBlockComments from './CoursewareBlockComments.vue';
-import CoursewareBlockExportOptions from './CoursewareBlockExportOptions.vue';
-import CoursewareBlockFeedback from './CoursewareBlockFeedback.vue';
-
-export default {
-    name: 'courseware-default-block-elements',
-    components: {
-        CoursewareBlockActions,
-        CoursewareBlockComments,
-        CoursewareBlockExportOptions,
-        CoursewareBlockFeedback,
-    },
-    props: {
-        block: Object,
-        canEdit: Boolean,
-        isTeacher: Boolean,
-        showFeatures: Boolean,
-    },
-    data() {
-        return {
-            displayFeatures: false,
-        };
-    },
-    methods: {
-        editBlock() {
-            this.$emit('editBlock');
-        },
-        showExportOptions() {},
-    },
-};
-</script>
diff --git a/resources/vue/components/courseware/CoursewareTasksDialogDistribute.vue b/resources/vue/components/courseware/CoursewareTasksDialogDistribute.vue
index 1e82d94c99b3316a97225dce17deb3e085735752..79c8cacac60578d18d6737764254feb12e8fec4b 100644
--- a/resources/vue/components/courseware/CoursewareTasksDialogDistribute.vue
+++ b/resources/vue/components/courseware/CoursewareTasksDialogDistribute.vue
@@ -237,9 +237,9 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareStructuralElementSelector from './CoursewareStructuralElementSelector.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
+import CoursewareStructuralElementSelector from './structural-element/CoursewareStructuralElementSelector.vue';
+import StudipWizardDialog from '../StudipWizardDialog.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/IndexApp.vue b/resources/vue/components/courseware/IndexApp.vue
index 0bcf2f2cdb7ef854822e9b6e1ada1b622f791b2a..cbeeb4cc7fb218777830056e939d839f91ce12e5 100644
--- a/resources/vue/components/courseware/IndexApp.vue
+++ b/resources/vue/components/courseware/IndexApp.vue
@@ -27,7 +27,7 @@
         </div>
         <studip-progress-indicator
             v-if="structureLoadingState === 'loading'"
-            class="cw-loading-indicator-content"
+            class="loading-indicator-content"
             :description="$gettext('Lade Lernmaterial...')"
         />
         <courseware-companion-box
@@ -40,15 +40,16 @@
 </template>
 
 <script>
-import CoursewareStructuralElement from './CoursewareStructuralElement.vue';
-import CoursewareSearchResults from './CoursewareSearchResults.vue';
-import CoursewareViewWidget from './CoursewareViewWidget.vue';
-import CoursewareActionWidget from './CoursewareActionWidget.vue';
-import CoursewareExportWidget from './CoursewareExportWidget.vue';
-import CoursewareImportWidget from './CoursewareImportWidget.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareSearchWidget from './CoursewareSearchWidget.vue';
-import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
+import CoursewareStructuralElement from './structural-element/CoursewareStructuralElement.vue';
+import CoursewareSearchResults from './structural-element/CoursewareSearchResults.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
+import CoursewareCompanionOverlay from './layouts/CoursewareCompanionOverlay.vue';
+import CoursewareViewWidget from './widgets/CoursewareViewWidget.vue';
+import CoursewareActionWidget from './widgets/CoursewareActionWidget.vue';
+import CoursewareExportWidget from './widgets/CoursewareExportWidget.vue';
+import CoursewareImportWidget from './widgets/CoursewareImportWidget.vue';
+import CoursewareSearchWidget from './widgets/CoursewareSearchWidget.vue';
+
 import StudipProgressIndicator from '../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/PublicApp.vue b/resources/vue/components/courseware/PublicApp.vue
index 616db7fa69f7fcc1e8359f349ff5213c1a12c2af..0a082f0dc196e78a90429dba8460b5e76adbae12 100644
--- a/resources/vue/components/courseware/PublicApp.vue
+++ b/resources/vue/components/courseware/PublicApp.vue
@@ -10,7 +10,7 @@
         </div>
         <studip-progress-indicator
             v-if="structureLoadingState === 'loading'"
-            class="cw-loading-indicator-content"
+            class="loading-indicator-content"
             :description="$gettext('Lade Lernmaterial...')"
         />
         <courseware-companion-box
@@ -36,8 +36,8 @@
 </template>
 
 <script>
-import PublicCoursewareStructuralElement from './PublicCoursewareStructuralElement.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import PublicCoursewareStructuralElement from './structural-element/PublicCoursewareStructuralElement.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
 import StudipProgressIndicator from '../StudipProgressIndicator.vue';
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/ShelfApp.vue b/resources/vue/components/courseware/ShelfApp.vue
index d9b37a448edaf8bdd91b51ef615d56e6dc867ffe..7f0f274b04804491fc3e439b01b2c38e6ad9617e 100644
--- a/resources/vue/components/courseware/ShelfApp.vue
+++ b/resources/vue/components/courseware/ShelfApp.vue
@@ -18,14 +18,14 @@
 </template>
 
 <script>
-import CoursewareShelfActionWidget from './CoursewareShelfActionWidget.vue';
-import CoursewareShelfImportWidget from './CoursewareShelfImportWidget.vue';
-import CoursewareShelfDialogAdd from './CoursewareShelfDialogAdd.vue';
-import CoursewareShelfDialogCopy from './CoursewareShelfDialogCopy.vue';
-import CoursewareShelfDialogImport from './CoursewareShelfDialogImport.vue';
-import CoursewareUnitItems from './CoursewareUnitItems.vue';
-import CoursewareSharedItems from './CoursewareSharedItems.vue';
-import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
+import CoursewareShelfActionWidget from './widgets/CoursewareShelfActionWidget.vue';
+import CoursewareShelfImportWidget from './widgets/CoursewareShelfImportWidget.vue';
+import CoursewareShelfDialogAdd from './unit/CoursewareShelfDialogAdd.vue';
+import CoursewareShelfDialogCopy from './unit/CoursewareShelfDialogCopy.vue';
+import CoursewareShelfDialogImport from './unit/CoursewareShelfDialogImport.vue';
+import CoursewareUnitItems from './unit/CoursewareUnitItems.vue';
+import CoursewareSharedItems from './unit/CoursewareSharedItems.vue';
+import CoursewareCompanionOverlay from './layouts/CoursewareCompanionOverlay.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/TasksApp.vue b/resources/vue/components/courseware/TasksApp.vue
index 7c149b828a3f7bdd7f800e6ee1ec0b2a67d16be1..8a406d8086407df5cd567c38e86aca1c79f8c3a5 100644
--- a/resources/vue/components/courseware/TasksApp.vue
+++ b/resources/vue/components/courseware/TasksApp.vue
@@ -12,10 +12,10 @@
 </template>
 
 <script>
-import CoursewareTasksActionWidget from './CoursewareTasksActionWidget.vue';
+import CoursewareTasksActionWidget from './widgets/CoursewareTasksActionWidget.vue';
 import CoursewareDashboardTasks from './CoursewareDashboardTasks.vue';
 import CoursewareDashboardStudents from './CoursewareDashboardStudents.vue';
-import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
+import CoursewareCompanionOverlay from './layouts/CoursewareCompanionOverlay.vue';
 import { mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareAudioBlock.vue b/resources/vue/components/courseware/blocks/CoursewareAudioBlock.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareAudioBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareAudioBlock.vue
index e7f47c09eab2b780ac8baa1f2415c06307409b50..e346d2096028241dd41aca812dbc23e3561a774f 100644
--- a/resources/vue/components/courseware/CoursewareAudioBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareAudioBlock.vue
@@ -165,20 +165,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareFolderChooser from './CoursewareFolderChooser.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-audio-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareFolderChooser,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -634,3 +628,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/audio.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareBeforeAfterBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue
similarity index 90%
rename from resources/vue/components/courseware/CoursewareBeforeAfterBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue
index 2770387ad7aeb12246048fbf91dd11a106a04cc3..2c6ac693d886998d7771858b1055df6ca3ccb682 100644
--- a/resources/vue/components/courseware/CoursewareBeforeAfterBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue
@@ -19,11 +19,7 @@
             </template>
             <template v-if="canEdit" #edit>
                 <courseware-tabs>
-                    <courseware-tab
-                        :index="0"
-                        :name="$gettext('Vorher')"
-                        :selected="true"
-                    >
+                    <courseware-tab :index="0" :name="$gettext('Vorher')" :selected="true">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Quelle') }}
@@ -46,10 +42,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="1"
-                        :name="$gettext('Nachher')"
-                    >
+                    <courseware-tab :index="1" :name="$gettext('Nachher')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Quelle') }}
@@ -80,12 +73,8 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import TwentyTwenty from 'vue-twentytwenty';
 import 'vue-twentytwenty/dist/vue-twentytwenty.css';
 import { mapActions, mapGetters } from 'vuex';
@@ -93,14 +82,9 @@ import { mapActions, mapGetters } from 'vuex';
 export default {
     name: 'courseware-before-after-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareCompanionBox,
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
+    components: Object.assign(BlockComponents, {
         TwentyTwenty,
-    },
+    }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -117,12 +101,12 @@ export default {
             currentAfterFile: {},
             currentAfterWebUrl: '',
             afterFile: null,
-            beforeFile: null
+            beforeFile: null,
         };
     },
     computed: {
         ...mapGetters({
-            viewMode: 'viewMode'
+            viewMode: 'viewMode',
         }),
         beforeSource() {
             return this.block?.attributes?.payload?.before_source;
@@ -165,7 +149,7 @@ export default {
         },
         editMode() {
             return this.viewMode === 'edit';
-        }
+        },
     },
     mounted() {
         this.loadFileRefs(this.block.id).then((response) => {
@@ -180,7 +164,7 @@ export default {
             }
 
             this.currentBeforeFile = this.beforeFile;
-            this.currentAfterFile  = this.afterFile;
+            this.currentAfterFile = this.afterFile;
         });
 
         this.loadImages();
@@ -205,7 +189,7 @@ export default {
                 }
 
                 this.currentBeforeFile = this.beforeFile;
-                this.currentAfterFile  = this.afterFile;
+                this.currentAfterFile = this.afterFile;
             });
         },
 
@@ -247,7 +231,6 @@ export default {
                     attributes.payload.after_file_id = '';
                     attributes.payload.after_web_url = this.currentAfterWebUrl;
                 }
-
             } else {
                 cmpInfo = cmpInfoAfter;
             }
@@ -271,7 +254,7 @@ export default {
 
             if (cmpInfo) {
                 this.companionWarning({
-                    info: cmpInfo
+                    info: cmpInfo,
                 });
                 return false;
             } else {
@@ -285,3 +268,21 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+.cw-block-before-after {
+    .twentytwenty-container {
+        width: 100% !important;
+        z-index: 19;
+        .twentytwenty-handle {
+            z-index: 18;
+        }
+        .twentytwenty-overlay {
+            z-index: 17;
+        }
+        img {
+            width: 100%;
+            z-index: 16;
+        }
+    }
+}
+</style>
diff --git a/resources/vue/components/courseware/CoursewareBiographyAchievementsBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBiographyAchievementsBlock.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareBiographyAchievementsBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareBiographyAchievementsBlock.vue
index 20540408902595cb6ce9df9a722884ebae85ec7d..07872d89cce93a0ac785f9bb9ec25d33dcca8615 100644
--- a/resources/vue/components/courseware/CoursewareBiographyAchievementsBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBiographyAchievementsBlock.vue
@@ -78,18 +78,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
+import StudipWysiwyg from '../../StudipWysiwyg.vue';
 import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
-import StudipWysiwyg from '../StudipWysiwyg.vue';
 
 export default {
     name: 'courseware-biography-achievements-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        StudipWysiwyg,
-    },
+    components: Object.assign(BlockComponents, { StudipWysiwyg }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -198,3 +195,6 @@ export default {
     }
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/biography.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareBiographyCareerBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBiographyCareerBlock.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareBiographyCareerBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareBiographyCareerBlock.vue
index 6fd855067bf82f8199ce2d72a35dc8331459bc92..c366618d70229ccec7a85d15510a5661e18c06aa 100644
--- a/resources/vue/components/courseware/CoursewareBiographyCareerBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBiographyCareerBlock.vue
@@ -125,22 +125,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
-import StudipIcon from '../StudipIcon.vue';
 
 export default {
     name: 'courseware-biography-career-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareTabs,
-        CoursewareTab,
-        StudipIcon,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -260,3 +252,7 @@ export default {
     }
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/timeline.scss";
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/biography.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareBiographyGoalsBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBiographyGoalsBlock.vue
similarity index 92%
rename from resources/vue/components/courseware/CoursewareBiographyGoalsBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareBiographyGoalsBlock.vue
index 857672fc786ec29d9c660d0be63263fde78a94d0..7a291bd1b6b5641fa6c3570fbd069749bd202cc5 100644
--- a/resources/vue/components/courseware/CoursewareBiographyGoalsBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBiographyGoalsBlock.vue
@@ -41,18 +41,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
+import StudipWysiwyg from '../../StudipWysiwyg.vue';
 import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
-import StudipWysiwyg from '../StudipWysiwyg.vue';
 
 export default {
     name: 'courseware-biography-goals-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        StudipWysiwyg,
-    },
+    components: Object.assign(BlockComponents, { StudipWysiwyg }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -134,3 +131,6 @@ export default {
     }
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/biography.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareBiographyPersonalInformationBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBiographyPersonalInformationBlock.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareBiographyPersonalInformationBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareBiographyPersonalInformationBlock.vue
index 28e5ffc7994b7d4e234f4c64f145f33f98f1587b..8de1843ff91c826d8b842541edcff1b0c83dc245 100644
--- a/resources/vue/components/courseware/CoursewareBiographyPersonalInformationBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBiographyPersonalInformationBlock.vue
@@ -72,16 +72,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
 
 export default {
     name: 'courseware-biography-personal-information-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -183,3 +181,6 @@ export default {
     }
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/biography.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareBlockActions.vue b/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareBlockActions.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockActions.vue
index 2b6252789e8539d662abccdc32badcad3eb2b89b..3ffff182f0cf6ded29771d51a8208869c0bbcb22 100644
--- a/resources/vue/components/courseware/CoursewareBlockActions.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue
@@ -14,7 +14,7 @@
 </template>
 
 <script>
-import StudipActionMenu from './../StudipActionMenu.vue';
+import StudipActionMenu from '../../StudipActionMenu.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareBlockComments.vue b/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareBlockComments.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockComments.vue
index 6ef33221374d6511df4fcba83580a0708add2dfe..68dc648b1c0062db8cc0bb3b41cb8923554d9526 100644
--- a/resources/vue/components/courseware/CoursewareBlockComments.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import CoursewareTalkBubble from './CoursewareTalkBubble.vue';
+import CoursewareTalkBubble from '../layouts/CoursewareTalkBubble.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareBlockDiscussion.vue b/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue
similarity index 94%
rename from resources/vue/components/courseware/CoursewareBlockDiscussion.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue
index e9ce9a3af5be73376fd7b2eb14dc43fbdecf53d6..716e6ee0b09cec1f50be16e9494ddbdb01fe0ef5 100644
--- a/resources/vue/components/courseware/CoursewareBlockDiscussion.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue
@@ -25,7 +25,7 @@
 </template>
 
 <script>
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
+import CoursewareCollapsibleBox from '../layouts/CoursewareCollapsibleBox.vue';
 import CoursewareBlockComments from './CoursewareBlockComments.vue';
 import CoursewareBlockFeedback from './CoursewareBlockFeedback.vue';
 import { mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareBlockEdit.vue b/resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareBlockEdit.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue
diff --git a/resources/vue/components/courseware/CoursewareBlockExportOptions.vue b/resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareBlockExportOptions.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue
diff --git a/resources/vue/components/courseware/CoursewareBlockFeedback.vue b/resources/vue/components/courseware/blocks/CoursewareBlockFeedback.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareBlockFeedback.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockFeedback.vue
index a34ad8fed857beb3c130135d1013f20096e43612..dfc95dc451570a0ceb641a03e33ce235c5ba2e8b 100644
--- a/resources/vue/components/courseware/CoursewareBlockFeedback.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBlockFeedback.vue
@@ -27,8 +27,8 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareTalkBubble from './CoursewareTalkBubble.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import CoursewareTalkBubble from '../layouts/CoursewareTalkBubble.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 
diff --git a/resources/vue/components/courseware/CoursewareBlockInfo.vue b/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareBlockInfo.vue
rename to resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue
index 17a716553cc6eae88bb8348f1cb5958a6d06d2c7..705328ecac94dda902caaf06b839acc787ea67eb 100644
--- a/resources/vue/components/courseware/CoursewareBlockInfo.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue
@@ -30,7 +30,7 @@
 </template>
 
 <script>
-import IsoDate from './IsoDate.vue';
+import IsoDate from '../layouts/IsoDate.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareCanvasBlock.vue b/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareCanvasBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue
index e7257988a7137517986375fdaa77818fa21d4044..794e4a9adce3607043df1d35df2efb580301b043 100644
--- a/resources/vue/components/courseware/CoursewareCanvasBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue
@@ -161,24 +161,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareFolderChooser from './CoursewareFolderChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-canvas-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareFolderChooser,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -710,3 +700,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/canvas.scss';
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareChartBlock.vue b/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareChartBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareChartBlock.vue
index 4d1c6dd09fcbe2bcc3250fd06733ed3006cd79fa..42d2d8156b0d4e69002ff5a996a5df05f2cf385e 100644
--- a/resources/vue/components/courseware/CoursewareChartBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue
@@ -105,11 +105,8 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import StudipIcon from '../StudipIcon.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import Chart from 'chart.js';
 import { mapActions } from 'vuex';
 
@@ -117,12 +114,7 @@ import { mapActions } from 'vuex';
 export default {
     name: 'courseware-chart-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareTabs,
-        CoursewareTab,
-        StudipIcon,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
diff --git a/resources/vue/components/courseware/CoursewareCodeBlock.vue b/resources/vue/components/courseware/blocks/CoursewareCodeBlock.vue
similarity index 88%
rename from resources/vue/components/courseware/CoursewareCodeBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareCodeBlock.vue
index 3ed8d226368f27f78940b161765e26bec640dfcc..66f10694fc9022ade54b88d5ca3a75781b1523c9 100644
--- a/resources/vue/components/courseware/CoursewareCodeBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareCodeBlock.vue
@@ -10,7 +10,9 @@
             @closeEdit="initCurrentData"
         >
             <template #content>
-                <pre v-show="currentContent !== ''"  v-highlightjs="currentContent"><code ref="code" :class="[currentLang]"></code></pre>
+                <pre v-show="currentContent !== ''" v-highlightjs="currentContent">
+                    <code ref="code" :class="[currentLang]"></code>
+                </pre>
                 <div v-show="currentLang !== ''" class="code-lang">
                     <span>{{ currentLang }}</span>
                 </div>
@@ -35,8 +37,8 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import hljs from 'highlight.js';
 
 import { mapActions } from 'vuex';
@@ -44,9 +46,7 @@ import { mapActions } from 'vuex';
 export default {
     name: 'courseware-code-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -115,3 +115,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/code.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareConfirmBlock.vue b/resources/vue/components/courseware/blocks/CoursewareConfirmBlock.vue
similarity index 91%
rename from resources/vue/components/courseware/CoursewareConfirmBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareConfirmBlock.vue
index 58dbc685025c06c52797add734f37458af945a1b..040d27f9b5e73f2d361c466f4e0dd61c49fc5e8e 100644
--- a/resources/vue/components/courseware/CoursewareConfirmBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareConfirmBlock.vue
@@ -16,7 +16,7 @@
                 </div>
                 <form class="default cw-block-confirm-content" prevent.default="">
                     <label>
-                        <input type="checkbox" :disabled="confirm" :checked="confirm" @click="setConfirm"/>
+                        <input type="checkbox" :disabled="confirm" :checked="confirm" @click="setConfirm" />
                         <span>{{ currentText }}</span>
                     </label>
                 </form>
@@ -35,16 +35,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
-import { blockMixin } from './block-mixin.js';
 
 export default {
     name: 'courseware-confirm-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -74,7 +72,7 @@ export default {
     methods: {
         ...mapActions({
             updateBlock: 'updateBlockInContainer',
-            updateUserDataFields: 'courseware-user-data-fields/update'
+            updateUserDataFields: 'courseware-user-data-fields/update',
         }),
         initCurrentData() {
             this.currentText = this.text;
@@ -116,3 +114,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/confirm.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareDateBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDateBlock.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareDateBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareDateBlock.vue
index 1361b60a9779d6f7cf57d770f6e527c8547cee8c..7fbc1b24e330925431f46a47b26b0d4995eccba4 100644
--- a/resources/vue/components/courseware/CoursewareDateBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareDateBlock.vue
@@ -83,15 +83,13 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
 export default {
     name: 'courseware-date-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -183,7 +181,7 @@ export default {
             }
             if (cmpInfo) {
                 this.companionWarning({
-                    info: cmpInfo
+                    info: cmpInfo,
                 });
                 return false;
             } else {
@@ -202,3 +200,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/date.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareDefaultBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareDefaultBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue
index a9548608e7f522623c7dea9ad2191f32d13da1da..d11a53834dc4d12054388e34b62dd880c811ed2e 100644
--- a/resources/vue/components/courseware/CoursewareDefaultBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue
@@ -84,27 +84,29 @@
 </template>
 
 <script>
+import CoursewareBlockActions from './CoursewareBlockActions.vue';
+import CoursewareBlockDiscussion from './CoursewareBlockDiscussion.vue';
 import CoursewareBlockEdit from './CoursewareBlockEdit.vue';
 import CoursewareBlockExportOptions from './CoursewareBlockExportOptions.vue';
 import CoursewareBlockInfo from './CoursewareBlockInfo.vue';
-import CoursewareBlockActions from './CoursewareBlockActions.vue';
-import StudipDialog from '../StudipDialog.vue';
-import StudipIcon from '../StudipIcon.vue';
-import { blockMixin } from './block-mixin.js';
+import StudipDialog from '../../StudipDialog.vue';
+import StudipIcon from '../../StudipIcon.vue';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
-import CoursewareBlockDiscussion from './CoursewareBlockDiscussion.vue';
+
 
 export default {
     name: 'courseware-default-block',
     mixins: [blockMixin],
     components: {
+        CoursewareBlockActions,
+        CoursewareBlockDiscussion,
         CoursewareBlockEdit,
         CoursewareBlockExportOptions,
-        CoursewareBlockActions,
         CoursewareBlockInfo,
         StudipDialog,
         StudipIcon,
-        CoursewareBlockDiscussion,
+        
     },
     props: {
         block: Object,
@@ -384,4 +386,4 @@ export default {
         }
     }
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareDialogCardsBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDialogCardsBlock.vue
similarity index 90%
rename from resources/vue/components/courseware/CoursewareDialogCardsBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareDialogCardsBlock.vue
index 4df490b4c73df2e92d555379a51b76d60d72c28d..5bfc2f78c3124624de3e84972e953339455e92b4 100644
--- a/resources/vue/components/courseware/CoursewareDialogCardsBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareDialogCardsBlock.vue
@@ -13,11 +13,10 @@
                 <div class="cw-block-dialog-cards-content">
                     <button
                         class="cw-dialogcards-prev cw-dialogcards-navbutton"
-                        :class="{'cw-dialogcards-prev-disabled': hasNoPerv}"
+                        :class="{ 'cw-dialogcards-prev-disabled': hasNoPerv }"
                         @click="prevCard"
                         :title="hasNoPerv ? $gettext('keine vorherige Karte') : $gettext('zur vorherigen Karte')"
-                    >
-                    </button>
+                    ></button>
                     <div class="cw-dialogcards">
                         <div
                             class="scene scene--card"
@@ -48,11 +47,10 @@
                     </div>
                     <button
                         class="cw-dialogcards-next cw-dialogcards-navbutton"
-                        :class="{'cw-dialogcards-next-disabled': hasNoNext}"
+                        :class="{ 'cw-dialogcards-next-disabled': hasNoNext }"
                         @click="nextCard"
                         :title="hasNoNext ? $gettext('keine nächste Karte') : $gettext('zur nächsten Karte')"
-                    >
-                    </button>
+                    ></button>
                 </div>
             </template>
             <template v-if="canEdit" #edit>
@@ -60,13 +58,13 @@
                 <courseware-tabs
                     v-if="currentCards.length > 0"
                     :setSelected="setCardTab"
-                    @selectTab="activateCard(parseInt($event.name.replace($gettext('Karte') +  ' ', '')) - 1)"
+                    @selectTab="activateCard(parseInt($event.name.replace($gettext('Karte') + ' ', '')) - 1)"
                 >
                     <courseware-tab
                         v-for="(card, index) in currentCards"
                         :key="index"
                         :index="index"
-                        :name="$gettext('Karte') +  ' ' + (index + 1).toString()"
+                        :name="$gettext('Karte') + ' ' + (index + 1).toString()"
                         :selected="index === 0"
                         canBeEmpty
                     >
@@ -114,22 +112,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions } from 'vuex';
 
 export default {
     name: 'courseware-dialog-cards-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -138,7 +128,7 @@ export default {
     data() {
         return {
             currentCards: [],
-            setCardTab: 0
+            setCardTab: 0,
         };
     },
     computed: {
@@ -149,7 +139,7 @@ export default {
             return this.currentCards.length === 1;
         },
         hasNoPerv() {
-            if(this.currentCards[0] !== undefined) {
+            if (this.currentCards[0] !== undefined) {
                 return this.currentCards[0].active;
             } else {
                 return true;
@@ -161,7 +151,7 @@ export default {
             } else {
                 return true;
             }
-        }
+        },
     },
     mounted() {
         this.initCurrentData();
@@ -206,8 +196,7 @@ export default {
                 if (file) {
                     this.currentCards[cardIndex].front_file_id = file.id;
                     this.currentCards[cardIndex].front_file = file;
-                }
-                else {
+                } else {
                     this.currentCards[cardIndex].front_file_id = '';
                     this.currentCards[cardIndex].front_file = [];
                 }
@@ -231,17 +220,21 @@ export default {
                 back_file_id: '',
                 back_text: '',
                 back_file: [],
-                active: false
+                active: false,
             });
             const index = this.currentCards.length - 1;
             this.activateCard(index);
-            this.$nextTick(() => { this.setCardTab = index; });
+            this.$nextTick(() => {
+                this.setCardTab = index;
+            });
         },
-        removeCard(cardIndex){
+        removeCard(cardIndex) {
             this.currentCards = this.currentCards.filter((val, index) => {
                 return !(index === cardIndex);
             });
-            this.$nextTick(() => { this.setCardTab = 0; });
+            this.$nextTick(() => {
+                this.setCardTab = 0;
+            });
         },
         flipCard(event) {
             event.currentTarget.classList.toggle('is-flipped');
@@ -293,3 +286,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/dialog-cards.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareDocumentBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue
similarity index 79%
rename from resources/vue/components/courseware/CoursewareDocumentBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue
index 58b0af70db95f8771fca0fba782d3e3d4c8ab28f..7f7b10ce003f1805cc7ea6fbd8f8f99750fccffc 100644
--- a/resources/vue/components/courseware/CoursewareDocumentBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareDocumentBlock.vue
@@ -20,14 +20,20 @@
                                 <div class="cw-pdf-toc">
                                     <button
                                         class="undecorated"
-                                        :class="{active: pdfTOCDisplay}"
+                                        :class="{ active: pdfTOCDisplay }"
                                         :title="$gettext('Inhaltsverzeichnis')"
                                         :aria-pressed="pdfTOCDisplay ? 'true' : 'false'"
                                         @click="toggleTOCViewer"
                                     >
                                         <studip-icon
                                             shape="table-of-contents"
-                                            :role="pdfTOC.length === 0 ? 'inactive' : pdfTOCDisplay ? 'info_alt' :'clickable'"
+                                            :role="
+                                                pdfTOC.length === 0
+                                                    ? 'inactive'
+                                                    : pdfTOCDisplay
+                                                    ? 'info_alt'
+                                                    : 'clickable'
+                                            "
                                             :size="18"
                                             class="text-bottom"
                                         />
@@ -36,7 +42,7 @@
                                 <div class="cw-pdf-search-toggle-btn">
                                     <button
                                         class="undecorated"
-                                        :class="{active: showPdfSearchBox}"
+                                        :class="{ active: showPdfSearchBox }"
                                         :title="$gettext('Suche')"
                                         :aria-pressed="showPdfSearchBox ? 'true' : 'false'"
                                         @click="togglePdfSearchBox"
@@ -50,7 +56,12 @@
                                     </button>
                                 </div>
                                 <div class="cw-pdf-search-box" v-show="showPdfSearchBox">
-                                    <input ref="pdfSearchInput" type="text" v-model="pdfSearch" @change="doSearchInPdf">
+                                    <input
+                                        ref="pdfSearchInput"
+                                        type="text"
+                                        v-model="pdfSearch"
+                                        @change="doSearchInPdf"
+                                    />
                                     <div class="cw-pdf-search-navs" v-if="pdfSearchFoundNums > 1">
                                         <button class="undecorated" @click="prevPdfSearch" :title="$gettext('Letzte')">
                                             <studip-icon
@@ -63,18 +74,27 @@
                                         <button class="undecorated" @click="nextPdfSearch" :title="$gettext('Nächste')">
                                             <studip-icon
                                                 shape="arr_1right"
-                                                :role="pdfSearchFoundSelectedIndex === pdfSearchFoundNums - 1 ? 'inactive' : 'clickable'"
+                                                :role="
+                                                    pdfSearchFoundSelectedIndex === pdfSearchFoundNums - 1
+                                                        ? 'inactive'
+                                                        : 'clickable'
+                                                "
                                                 :size="18"
                                                 class="text-bottom"
                                             />
                                         </button>
                                     </div>
                                     <span class="cw-pdf-search-num" v-if="pdfSearchFoundNums > 0">
-                                        {{ (pdfSearchFoundSelectedIndex + 1) }} / {{ pdfSearchFoundNums }} {{ $gettext('Treffer') }}
+                                        {{ pdfSearchFoundSelectedIndex + 1 }} / {{ pdfSearchFoundNums }}
+                                        {{ $gettext('Treffer') }}
                                     </span>
                                 </div>
                                 <div class="cw-pdf-page-nav">
-                                    <button class="undecorated" @click="prevPage" :title="$gettext('Eine Seite zurück')">
+                                    <button
+                                        class="undecorated"
+                                        @click="prevPage"
+                                        :title="$gettext('Eine Seite zurück')"
+                                    >
                                         <studip-icon
                                             shape="arr_1up"
                                             :role="pageNum - 1 === 0 ? 'inactive' : 'clickable'"
@@ -97,10 +117,8 @@
                                         :aria-label="$gettext('Seite')"
                                         :value="pageNum"
                                         @change="updatePageNum"
-                                    >
-                                    <span>
-                                        {{ $gettext('von') }} {{ pageCount }}
-                                    </span>
+                                    />
+                                    <span> {{ $gettext('von') }} {{ pageCount }} </span>
                                 </div>
                             </div>
                             <div class="cw-pdf-toolbar-middle">
@@ -113,7 +131,9 @@
                                     </button>
                                     <select v-model="currentScale" :aria-label="$gettext('Zoom')" @change="updateZoom">
                                         <option v-show="false" :value="currentScale">{{ formattedZoom }}%</option>
-                                        <option v-for="(value, index) in scaleValues" :key="index" :value="value">{{ value * 100 }}%</option>
+                                        <option v-for="(value, index) in scaleValues" :key="index" :value="value">
+                                            {{ value * 100 }}%
+                                        </option>
                                     </select>
                                 </div>
                                 <div class="cw-pdf-rotate">
@@ -126,7 +146,7 @@
                                 <div class="cw-pdf-handtool">
                                     <button
                                         class="undecorated"
-                                        :class="{active: pdfHandTool}"
+                                        :class="{ active: pdfHandTool }"
                                         :title="$gettext('Hand-Werkzeug')"
                                         :aria-pressed="pdfHandTool ? 'true' : 'false'"
                                         @click="toggleHandTool"
@@ -140,8 +160,13 @@
                                     </button>
                                 </div>
                                 <div class="cw-pdf-download">
-                                    <a v-if="downloadable === 'true'" :href="currentUrl" download :title="$gettext('Speichern')">
-                                        <studip-icon shape="download" :size="18" class="text-bottom"/>
+                                    <a
+                                        v-if="downloadable === 'true'"
+                                        :href="currentUrl"
+                                        download
+                                        :title="$gettext('Speichern')"
+                                    >
+                                        <studip-icon shape="download" :size="18" class="text-bottom" />
                                     </a>
                                 </div>
                             </div>
@@ -151,29 +176,38 @@
                                 <span class="sr-only" aria-live="polite">{{ srMessage }}</span>
                                 <div class="cw-pdf-sidebar" v-show="pdfTOCDisplay">
                                     <ul class="cw-pdf-toc-list">
-                                        <CoursewarePDFTableOfContent v-for="(item, index) in pdfTOC" :item="item" :key="index" @tocPageNav="tocPageNav" />
+                                        <CoursewarePDFTableOfContent
+                                            v-for="(item, index) in pdfTOC"
+                                            :item="item"
+                                            :key="index"
+                                            @tocPageNav="tocPageNav"
+                                        />
                                     </ul>
                                 </div>
                                 <div
                                     ref="container"
                                     class="cw-pdf-viewer-container"
-                                    :class="{'hand-cursor-grab': pdfHandTool, 'grabbing':  pdfGrabbing, 'has-error': pdfError}"
+                                    :class="{
+                                        'hand-cursor-grab': pdfHandTool,
+                                        grabbing: pdfGrabbing,
+                                        'has-error': pdfError,
+                                    }"
                                     v-dragscroll="pdfHandTool"
                                     @mousedown="handleMouseDown"
                                     @mouseup="handleMouseUp"
                                 >
-                                    <div class="pdfViewer"/>
+                                    <div class="pdfViewer" />
                                 </div>
                             </div>
                             <div v-show="pdfError" class="cw-pdf-error-page">
-                                <courseware-companion-box 
+                                <courseware-companion-box
                                     mood="sad"
                                     :msgCompanion="$gettext('Es gab einen Fehler. Bitte versuchen Sie es erneut!')"
                                 >
                                 </courseware-companion-box>
                             </div>
                             <div ref="fakeContainer" class="cw-pdf-viewer-fake-container">
-                                <div class="pdfViewer"/>
+                                <div class="pdfViewer" />
                             </div>
                         </div>
                     </template>
@@ -216,11 +250,9 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import CoursewarePDFTableOfContent from './CoursewarePDFTableOfContent.vue';
-import { blockMixin } from './block-mixin.js';
 import { getDocument } from 'pdfjs-dist';
 import {
     DefaultAnnotationLayerFactory,
@@ -231,11 +263,11 @@ import {
     PDFLinkService,
     PDFPageView,
     PDFViewer,
-    EventBus
+    EventBus,
 } from 'pdfjs-dist/web/pdf_viewer.js';
 // pdfjsWorker must be imported!
 import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
-import { dragscroll } from 'vue-dragscroll'
+import { dragscroll } from 'vue-dragscroll';
 
 import { mapActions } from 'vuex';
 import 'pdfjs-dist/web/pdf_viewer.css';
@@ -243,14 +275,9 @@ import 'pdfjs-dist/web/pdf_viewer.css';
 export default {
     name: 'courseware-document-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareCompanionBox,
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewarePDFTableOfContent
-    },
+    components: Object.assign(BlockComponents, { CoursewarePDFTableOfContent }),
     directives: {
-        dragscroll
+        dragscroll,
     },
     props: {
         block: Object,
@@ -296,7 +323,7 @@ export default {
             scaleValues: [0.5, 1, 1.5, 2, 3, 4],
             file: null,
 
-            srMessage: ''
+            srMessage: '',
         };
     },
     computed: {
@@ -325,7 +352,7 @@ export default {
         hasFile() {
             return this.currentFileId !== '';
         },
-        formattedZoom () {
+        formattedZoom() {
             return Number.parseInt(this.scale * 100, 10);
         },
     },
@@ -341,7 +368,7 @@ export default {
         },
         showPdfSearchBox() {
             this.resetPdfSearch();
-        }
+        },
     },
     mounted() {
         this.loadFileRefs(this.block.id).then((response) => {
@@ -380,7 +407,7 @@ export default {
                 // Find Controller
                 view.pdfFindController = new PDFFindController({
                     eventBus: view.pdfEventBus,
-                    linkService: view.pdfLinkService
+                    linkService: view.pdfLinkService,
                 });
                 // Annotation Layer
                 view.pdfAnnotationLayer = new DefaultAnnotationLayerFactory();
@@ -390,7 +417,7 @@ export default {
                 view.loadPdfDocument();
 
                 // Handle search results.
-                view.pdfEventBus.on('updatetextlayermatches', ({source, pageIndex}) => {
+                view.pdfEventBus.on('updatetextlayermatches', ({ source, pageIndex }) => {
                     if (view.pdfViewer.pdfPage._pageIndex == pageIndex) {
                         setTimeout(() => {
                             view.handleSearchMatches();
@@ -433,57 +460,58 @@ export default {
                 let container = this.$refs.container;
                 let outerContainer = this.$refs.outerContainer;
                 let fakeContainer = this.$refs.fakeContainer;
-                this.pdfDoc.getPage(parseInt(view.pageNum)).then((pdfPage) => {
-                    view.pdfPage = pdfPage;
-                    // Creating the page view with default parameters.
-                    let defaultViewport = pdfPage.getViewport({
-                        scale: 1.35,
-                    });
+                this.pdfDoc
+                    .getPage(parseInt(view.pageNum))
+                    .then((pdfPage) => {
+                        view.pdfPage = pdfPage;
+                        // Creating the page view with default parameters.
+                        let defaultViewport = pdfPage.getViewport({
+                            scale: 1.35,
+                        });
 
-                    view.pdfBasePage = new PDFViewer({
-                        container: fakeContainer,
-                        eventBus: view.pdfEventBus,
-                        findController: view.pdfFindController
-                    });
+                        view.pdfBasePage = new PDFViewer({
+                            container: fakeContainer,
+                            eventBus: view.pdfEventBus,
+                            findController: view.pdfFindController,
+                        });
 
-                    let pdfPageViewOptions = {
-                        container: container,
-                        id: view.pageNum,
-                        scale: view.scale,
-                        defaultViewport: defaultViewport,
-                        eventBus: view.pdfEventBus,
-                        findController: view.pdfFindController,
-                        textHighlighterFactory: view.pdfBasePage,
-                        xfaLayerFactory: view.pdfDoc.isPureXfa
-                            ? new DefaultXfaLayerFactory()
-                            : null,
-                        structTreeLayerFactory: new DefaultStructTreeLayerFactory()
-                    };
-                    if (view.pdfHandTool === false) {
-                        pdfPageViewOptions.textLayerFactory = view.pdfTextLayer;
-                        pdfPageViewOptions.annotationLayerFactory = view.pdfAnnotationLayer;
-                    } else {
-                        pdfPageViewOptions.textLayerMode = 0;
-                        pdfPageViewOptions.annotationMode = 0;
-                    }
-                    // Force annotation to be disabled.
-                    if (!this.pdfAnnotation && pdfPageViewOptions?.annotationLayerFactory) {
-                        pdfPageViewOptions.annotationLayerFactory = null;
-                        pdfPageViewOptions.annotationMode = 0;
-                    }
-                    view.pdfViewer = new PDFPageView(pdfPageViewOptions);
-                    // Associates the actual page with the view, and drawing it
-                    view.pdfViewer.setPdfPage(view.pdfPage);
-                    // Set LinkService viewer
-                    view.pdfLinkService.setViewer(view.pdfViewer);
-                    // Set outer container height
-                    outerContainer.style.height = container.offsetHeight + 'px';
-                    view.renderPage();
-                }).catch(err => {
-                    console.log(err);
-                    outerContainer.style.minHeight = '350px';
-                    view.pdfError = true;
-                });
+                        let pdfPageViewOptions = {
+                            container: container,
+                            id: view.pageNum,
+                            scale: view.scale,
+                            defaultViewport: defaultViewport,
+                            eventBus: view.pdfEventBus,
+                            findController: view.pdfFindController,
+                            textHighlighterFactory: view.pdfBasePage,
+                            xfaLayerFactory: view.pdfDoc.isPureXfa ? new DefaultXfaLayerFactory() : null,
+                            structTreeLayerFactory: new DefaultStructTreeLayerFactory(),
+                        };
+                        if (view.pdfHandTool === false) {
+                            pdfPageViewOptions.textLayerFactory = view.pdfTextLayer;
+                            pdfPageViewOptions.annotationLayerFactory = view.pdfAnnotationLayer;
+                        } else {
+                            pdfPageViewOptions.textLayerMode = 0;
+                            pdfPageViewOptions.annotationMode = 0;
+                        }
+                        // Force annotation to be disabled.
+                        if (!this.pdfAnnotation && pdfPageViewOptions?.annotationLayerFactory) {
+                            pdfPageViewOptions.annotationLayerFactory = null;
+                            pdfPageViewOptions.annotationMode = 0;
+                        }
+                        view.pdfViewer = new PDFPageView(pdfPageViewOptions);
+                        // Associates the actual page with the view, and drawing it
+                        view.pdfViewer.setPdfPage(view.pdfPage);
+                        // Set LinkService viewer
+                        view.pdfLinkService.setViewer(view.pdfViewer);
+                        // Set outer container height
+                        outerContainer.style.height = container.offsetHeight + 'px';
+                        view.renderPage();
+                    })
+                    .catch((err) => {
+                        console.log(err);
+                        outerContainer.style.minHeight = '350px';
+                        view.pdfError = true;
+                    });
             }
         },
         renderPage() {
@@ -539,10 +567,15 @@ export default {
         },
         tocPageNav(dest) {
             let view = this;
-            let destObj = dest.find((ref) =>
-                typeof ref === "object" && ref !== null &&
-                Number.isInteger(ref.num) && ref.num >= 0 &&
-                Number.isInteger(ref.gen) && ref.gen >= 0);
+            let destObj = dest.find(
+                (ref) =>
+                    typeof ref === 'object' &&
+                    ref !== null &&
+                    Number.isInteger(ref.num) &&
+                    ref.num >= 0 &&
+                    Number.isInteger(ref.gen) &&
+                    ref.gen >= 0
+            );
             if (destObj) {
                 view.pdfDoc.getPageIndex(destObj).then((pageIndex) => {
                     view.goToPage(pageIndex + 1);
@@ -628,18 +661,20 @@ export default {
                         selectIndex: searchSelectIndex,
                         matchIndex: matchIndex,
                         pageNum: pageNum,
-                    }
+                    };
                     view.pdfSearchMatchesMapping.push(mappingObj);
                     searchSelectIndex++;
                 }
             }
             // Find next match if there the current page has nothing.
             if (
-                view.pdfSearchFoundSelectedIndex === 0
-                && view.pdfViewer.pdfPage._pageIndex > 0
-                && matchesPageCount > 0
+                view.pdfSearchFoundSelectedIndex === 0 &&
+                view.pdfViewer.pdfPage._pageIndex > 0 &&
+                matchesPageCount > 0
             ) {
-                let nextMapped = view.pdfSearchMatchesMapping.filter(map => map.pageNum >= view.pdfViewer.pdfPage._pageIndex + 1);
+                let nextMapped = view.pdfSearchMatchesMapping.filter(
+                    (map) => map.pageNum >= view.pdfViewer.pdfPage._pageIndex + 1
+                );
                 if (nextMapped.length) {
                     view.pdfSearchFoundSelectedIndex = nextMapped[0].selectIndex;
                 }
@@ -656,7 +691,7 @@ export default {
                 entireWord: true,
                 highlightAll: true,
                 findPrevious: false,
-                matchDiacritics: false
+                matchDiacritics: false,
             };
             this.pdfEventBus.dispatch('find', findObj);
         },
@@ -676,8 +711,8 @@ export default {
         },
         pdfSearchDisplayHandler() {
             // Go to page based on selected index.
-            let pageMatches = this.pdfSearchMatchesMapping.filter(map => 
-                map.selectIndex === this.pdfSearchFoundSelectedIndex
+            let pageMatches = this.pdfSearchMatchesMapping.filter(
+                (map) => map.selectIndex === this.pdfSearchFoundSelectedIndex
             );
             if (pageMatches.length) {
                 let matchObj = pageMatches[0];
@@ -698,7 +733,7 @@ export default {
                 let selectedSpan = this.pdfSearchHighlightedList[matchIndex];
                 if (selectedSpan) {
                     selectedSpan.classList.add('selected');
-                    selectedSpan.scrollIntoView({ behavior: 'smooth', block: "center" });
+                    selectedSpan.scrollIntoView({ behavior: 'smooth', block: 'center' });
                 }
             }
         },
@@ -744,7 +779,7 @@ export default {
         storeBlock() {
             if (this.currentFile === undefined) {
                 this.companionWarning({
-                    info: this.$gettext('Bitte wählen Sie eine Datei aus.')
+                    info: this.$gettext('Bitte wählen Sie eine Datei aus.'),
                 });
                 return false;
             } else {
@@ -765,7 +800,10 @@ export default {
         updateSrMessage(message) {
             this.srMessage = '';
             this.srMessage = message;
-        }
+        },
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/document.scss';
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareDownloadBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue
similarity index 88%
rename from resources/vue/components/courseware/CoursewareDownloadBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue
index e642e79af1a699986a9c80f6be8cece384896c7c..2897b085568befd5da8baa6b17cfc323cddc0f68 100644
--- a/resources/vue/components/courseware/CoursewareDownloadBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue
@@ -43,11 +43,7 @@
             </template>
             <template v-if="canEdit" #edit>
                 <courseware-tabs>
-                    <courseware-tab
-                        :index="0"
-                        :name="$gettext('Datei')"
-                        :selected="true"
-                    >
+                    <courseware-tab :index="0" :name="$gettext('Datei')" :selected="true">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Überschrift') }}
@@ -59,10 +55,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="1"
-                        :name="$gettext('Infobox')"
-                    >
+                    <courseware-tab :index="1" :name="$gettext('Infobox')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Infobox vor Download') }}
@@ -74,10 +67,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="2"
-                        :name="$gettext('Fortschritt')"
-                    >
+                    <courseware-tab :index="2" :name="$gettext('Fortschritt')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Fortschritt erst beim Herunterladen') }}
@@ -98,22 +88,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-download-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -162,7 +144,7 @@ export default {
             }
 
             return downloaded;
-        }
+        },
     },
     mounted() {
         this.initCurrentData();
@@ -174,7 +156,7 @@ export default {
         ...mapActions({
             loadFileRef: 'file-refs/loadById',
             updateBlock: 'updateBlockInContainer',
-            updateUserDataFields: 'courseware-user-data-fields/update'
+            updateUserDataFields: 'courseware-user-data-fields/update',
         }),
         initCurrentData() {
             this.currentTitle = this.title;
@@ -191,7 +173,12 @@ export default {
             const options = { include: 'terms-of-use' };
             await this.loadFileRef({ id: id, options });
             const fileRef = this.fileRefById({ id: id });
-            if (fileRef && this.relatedTermOfUse({parent: fileRef, relationship: 'terms-of-use'}).attributes['download-condition'] === 0) {
+            if (
+                fileRef &&
+                this.relatedTermOfUse({ parent: fileRef, relationship: 'terms-of-use' }).attributes[
+                    'download-condition'
+                ] === 0
+            ) {
                 this.updateCurrentFile({
                     id: fileRef.id,
                     name: fileRef.attributes.name,
@@ -278,15 +265,15 @@ export default {
                     block: {
                         data: {
                             id: this.block.id,
-                            type: this.block.type
-                        }
-                    }
+                            type: this.block.type,
+                        },
+                    },
                 },
                 attributes: {
                     payload: {
-                        downloaded: true
-                    }
-                }
+                        downloaded: true,
+                    },
+                },
             };
             this.updateUserDataFields(data);
             this.userProgress = 1;
@@ -294,3 +281,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/files.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareEmbedBlock.vue b/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareEmbedBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue
index 59457ce17145598be0916f4227d683e03f5f9f55..75ed4eec3d40cd3f3c6a691f1e89bdf1b1f75a31 100644
--- a/resources/vue/components/courseware/CoursewareEmbedBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue
@@ -87,16 +87,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions } from 'vuex';
 
 export default {
     name: 'courseware-embed-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -159,7 +157,7 @@ export default {
         window.addEventListener('resize', this.calcContentHeight);
     },
 
-    created () {
+    created() {
         STUDIP.eventBus.on('courseware:update-tab', (data) => {
             this.recalculateContentHeight(data);
         });
@@ -186,7 +184,7 @@ export default {
                 this.calcContentHeight();
             }
         },
-        recalculateContentHeight(data){
+        recalculateContentHeight(data) {
             if (this.$parent._uid === data.uid) {
                 if (this.oembedData) {
                     this.calcContentHeight();
@@ -247,6 +245,8 @@ export default {
             });
         },
     },
-
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/embed.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareErrorBlock.vue b/resources/vue/components/courseware/blocks/CoursewareErrorBlock.vue
similarity index 83%
rename from resources/vue/components/courseware/CoursewareErrorBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareErrorBlock.vue
index f0eb1f671fd81e27b47ff1caab1e728166d6bac2..39860ea6228e6cdfb4e8c88d52a143d284eadc56 100644
--- a/resources/vue/components/courseware/CoursewareErrorBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareErrorBlock.vue
@@ -22,17 +22,13 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 
 export default {
     name: 'courseware-error-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareCompanionBox,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
diff --git a/resources/vue/components/courseware/CoursewareFolderBlock.vue b/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue
similarity index 82%
rename from resources/vue/components/courseware/CoursewareFolderBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue
index 2090c35358a3bde687e908d9bebc4a8bf3de0eca..6bbc48d00a8455edd368a47c5ecac5ff10ea69d4 100644
--- a/resources/vue/components/courseware/CoursewareFolderBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue
@@ -13,7 +13,11 @@
                 <div v-if="currentTitle !== ''" class="cw-block-title">{{ currentTitle }}</div>
                 <div v-if="isHomework" class="cw-block-folder-info">
                     <p>
-                        {{ $gettext('Dieser Ordner ist ein Hausaufgabenordner. Es können nur Dateien eingestellt werden.') }}
+                        {{
+                            $gettext(
+                                'Dieser Ordner ist ein Hausaufgabenordner. Es können nur Dateien eingestellt werden.'
+                            )
+                        }}
                     </p>
                     <p v-if="!isTeacher">
                         {{ $gettext('Sie selbst haben folgende Dateien in diesen Ordner eingestellt') }}:
@@ -28,7 +32,10 @@
                             :title="$gettext('Datei herunterladen')"
                             :href="file.meta['download-url']"
                         >
-                            <span class="cw-block-file-info" :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]">
+                            <span
+                                class="cw-block-file-info"
+                                :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]"
+                            >
                                 {{ file.attributes.name }}
                             </span>
                             <div v-if="isTeacher && isHomework" class="cw-block-file-details">
@@ -41,7 +48,10 @@
                             </div>
                         </a>
                         <template v-else>
-                            <span class="cw-block-file-info download-disabled" :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]">
+                            <span
+                                class="cw-block-file-info download-disabled"
+                                :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]"
+                            >
                                 {{ file.attributes.name }}
                             </span>
                             <div class="cw-block-file-details">
@@ -61,7 +71,7 @@
                     <form class="default" @submit.prevent="">
                         <label>
                             {{ $gettext('Dateien zum Hochladen auswählen') }}
-                            <input class="cw-file-input" ref="uploadFile" type="file" @change="displayTermSelector"/>
+                            <input class="cw-file-input" ref="uploadFile" type="file" @change="displayTermSelector" />
                             <button class="button" @click="uploadFile">
                                 {{ $gettext('Datei hochladen') }}
                             </button>
@@ -81,8 +91,12 @@
                     >
                         <template v-slot:dialogContent>
                             <form class="default" @submit.prevent="">
-                                <div style="margin-bottom: 1ex;">
-                                    {{ $gettext('Bereitgestellte Dateien können heruntergeladen und ggf. weiterverbreitet werden. Dabei ist das Urheberrecht sowohl beim Hochladen der Datei als auch bei der Nutzung zu beachten. Bitte geben Sie daher an, um welche Art von Bereitstellung es sich handelt. Diese Angabe dient mehreren Zwecken: Beim Herunterladen wird ein Hinweis angezeigt, welche Nutzung der Datei zulässig ist. Beim Hochladen stellt die Angabe eine Entscheidungshilfe dar, damit Sie sichergehen können, dass die Datei tatsächlich bereitgestellt werden darf.') }}
+                                <div style="margin-bottom: 1ex">
+                                    {{
+                                        $gettext(
+                                            'Bereitgestellte Dateien können heruntergeladen und ggf. weiterverbreitet werden. Dabei ist das Urheberrecht sowohl beim Hochladen der Datei als auch bei der Nutzung zu beachten. Bitte geben Sie daher an, um welche Art von Bereitstellung es sich handelt. Diese Angabe dient mehreren Zwecken: Beim Herunterladen wird ein Hinweis angezeigt, welche Nutzung der Datei zulässig ist. Beim Hochladen stellt die Angabe eine Entscheidungshilfe dar, damit Sie sichergehen können, dass die Datei tatsächlich bereitgestellt werden darf.'
+                                        )
+                                    }}
                                 </div>
                                 <fieldset class="select_terms_of_use">
                                     <template v-for="term in termsOfUse">
@@ -98,13 +112,13 @@
                                         />
                                         <label @click="selectedTerm = term.id" :key="term.id + 'label'">
                                             <div class="icon">
-                                                <studip-icon :shape="term.attributes.icon" size="32"/>
+                                                <studip-icon :shape="term.attributes.icon" :size="32" />
                                             </div>
                                             <div class="text">
                                                 {{ term.attributes.name }}
                                             </div>
-                                            <studip-icon shape="arr_1down" size="24" class="arrow" />
-                                            <studip-icon shape="check-circle" size="24" class="check" />
+                                            <studip-icon shape="arr_1down" :size="24" class="arrow" />
+                                            <studip-icon shape="check-circle" :size="24" class="check" />
                                         </label>
                                         <div class="terms_of_use_description" :key="term.id + '_description'">
                                             <div class="description">
@@ -138,21 +152,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFolderChooser from './CoursewareFolderChooser.vue';
-import StudipDialog from '../StudipDialog.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 
-import { blockMixin } from './block-mixin.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-folder-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFolderChooser,
-        StudipDialog
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -170,7 +178,7 @@ export default {
     computed: {
         ...mapGetters({
             folderById: 'folders/byId',
-            termsOfUse: 'terms-of-use/all'
+            termsOfUse: 'terms-of-use/all',
         }),
         folderType() {
             return this.block?.attributes?.payload?.type;
@@ -198,7 +206,7 @@ export default {
         },
         downloadEnabled() {
             return this.isTeacher || !this.isHomework;
-        }
+        },
     },
     async mounted() {
         await this.loadTermsOfUse();
@@ -213,7 +221,7 @@ export default {
             companionWarning: 'companionWarning',
             companionSuccess: 'companionSuccess',
             companionError: 'companionError',
-            loadTermsOfUse: 'terms-of-use/loadAll'
+            loadTermsOfUse: 'terms-of-use/loadAll',
         }),
         async initCurrentData() {
             this.currentTitle = this.title;
@@ -274,13 +282,15 @@ export default {
         },
         getFormattedDate(unformattedDate) {
             const date = new Date(unformattedDate);
-            const localeDate = date.toLocaleDateString("de-DE", {
-                year: "numeric",
-                month: "2-digit",
-                day: "2-digit",
+            const localeDate = date.toLocaleDateString('de-DE', {
+                year: 'numeric',
+                month: '2-digit',
+                day: '2-digit',
             });
 
-            return `${localeDate} ${date.getHours()}:${(date.getMinutes() < 10 ? '0' : '') + date.getMinutes()}:${(date.getSeconds() < 10 ? '0' : '') + date.getSeconds()}`;
+            return `${localeDate} ${date.getHours()}:${(date.getMinutes() < 10 ? '0' : '') + date.getMinutes()}:${
+                (date.getSeconds() < 10 ? '0' : '') + date.getSeconds()
+            }`;
         },
         storeBlock() {
             let attributes = {};
@@ -306,36 +316,36 @@ export default {
             const userFile = this.$refs?.uploadFile?.files[0];
             if (!userFile) {
                 this.companionWarning({
-                    info: this.$gettext('Bitte wählen Sie eine Datei aus.')
+                    info: this.$gettext('Bitte wählen Sie eine Datei aus.'),
                 });
                 return;
             }
 
             let file = {
                 attributes: {
-                    name: userFile.name.replace(/\s/g, '_')
+                    name: userFile.name.replace(/\s/g, '_'),
                 },
                 relationships: {
                     'terms-of-use': {
                         data: {
-                            id: this.selectedTerm
-                        }
-                    }
-                }
+                            id: this.selectedTerm,
+                        },
+                    },
+                },
             };
             let fileObj = await this.createFile({
                 file: file,
                 filedata: userFile,
-                folder: { id: this.currentFolderId }
+                folder: { id: this.currentFolderId },
             });
             if (fileObj && fileObj.type === 'file-refs') {
                 this.companionSuccess({
-                    info: this.$gettext('Die Datei wurde erfolgreich im Dateibereich abgelegt.')
+                    info: this.$gettext('Die Datei wurde erfolgreich im Dateibereich abgelegt.'),
                 });
             } else {
                 if (this.folderType !== 'HomeworkFolder') {
                     this.companionError({
-                        info: this.$gettext('Es ist ein Fehler aufgetretten.')
+                        info: this.$gettext('Es ist ein Fehler aufgetretten.'),
                     });
                 }
             }
@@ -346,12 +356,12 @@ export default {
             this.initCurrentData();
         },
         getDefaultTerm() {
-            const defaultTerm = this.termsOfUse.filter(term => term.attributes['is-default'])[0];
+            const defaultTerm = this.termsOfUse.filter((term) => term.attributes['is-default'])[0];
             if (defaultTerm) {
                 return defaultTerm.id;
             }
             return null;
-        }
+        },
     },
     watch: {
         currentFolderId() {
@@ -362,3 +372,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/files.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareGalleryBlock.vue b/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue
similarity index 85%
rename from resources/vue/components/courseware/CoursewareGalleryBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue
index 29ba44fece4888d29ef64484601f4bbfe4b640db..40bc33c5dad2cc1030055226053856b2aef91793 100644
--- a/resources/vue/components/courseware/CoursewareGalleryBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue
@@ -11,7 +11,11 @@
         >
             <template #content>
                 <template v-if="files.length !== 0">
-                    <div v-if="currentLayout === 'carousel'" class="cw-block-gallery-content" :style="{ height: `${currentHeight}px` }">
+                    <div
+                        v-if="currentLayout === 'carousel'"
+                        class="cw-block-gallery-content"
+                        :style="{ height: `${currentHeight}px` }"
+                    >
                         <div
                             v-for="(image, index) in files"
                             :key="image.id"
@@ -28,30 +32,39 @@
                                     }
                                 "
                             />
-                            <div class="cw-block-gallery-file-description"
-                                :class="{'show-on-hover': currentMouseoverFileNames === 'true'}">
+                            <div
+                                class="cw-block-gallery-file-description"
+                                :class="{ 'show-on-hover': currentMouseoverFileNames === 'true' }"
+                            >
                                 <p v-if="currentShowFileNames === 'true'">{{ image?.attributes?.name }}</p>
                                 <p v-if="currentShowFileDescription === 'true'">{{ image?.attributes?.description }}</p>
                             </div>
                         </div>
                         <div v-if="currentNav === 'true'">
-                            <button class="cw-block-gallery-prev" :title="$gettext('Vorheriges Bild')" @click="plusSlides(-1)"></button>
-                            <button class="cw-block-gallery-next" :title="$gettext('Nächstes Bild')" @click="plusSlides(1)"></button>
+                            <button
+                                class="cw-block-gallery-prev"
+                                :title="$gettext('Vorheriges Bild')"
+                                @click="plusSlides(-1)"
+                            ></button>
+                            <button
+                                class="cw-block-gallery-next"
+                                :title="$gettext('Nächstes Bild')"
+                                @click="plusSlides(1)"
+                            ></button>
                         </div>
                     </div>
                     <div v-if="currentLayout === 'grid'" class="cw-block-gallery-content">
                         <div class="cw-block-gallery-grid">
-                            <figure
-                                v-for="image in files"
-                                :key="image.id"
-                                :style="{ 'max-width': gridWidth }"
-                            >
-                                <img :src="image.meta['download-url']" :title="image?.attributes?.name"/>
+                            <figure v-for="image in files" :key="image.id" :style="{ 'max-width': gridWidth }">
+                                <img :src="image.meta['download-url']" :title="image?.attributes?.name" />
                                 <figcaption v-if="showDescription">
                                     <p v-if="currentShowFileNames === 'true'" class="cw-block-gallery-grid-file-name">
                                         {{ image?.attributes?.name }}
                                     </p>
-                                    <p v-if="currentShowFileDescription === 'true'" class="cw-block-gallery-grid-file-description">
+                                    <p
+                                        v-if="currentShowFileDescription === 'true'"
+                                        class="cw-block-gallery-grid-file-description"
+                                    >
                                         {{ image?.attributes?.description }}
                                     </p>
                                 </figcaption>
@@ -62,11 +75,7 @@
             </template>
             <template v-if="canEdit" #edit>
                 <courseware-tabs>
-                    <courseware-tab
-                        :index="0"
-                        :name="$gettext('Einstellungen')"
-                        :selected="true"
-                    >
+                    <courseware-tab :index="0" :name="$gettext('Einstellungen')" :selected="true">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Layout') }}
@@ -95,10 +104,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="1"
-                        :name="$gettext('Beschreibung')"
-                    >
+                    <courseware-tab :index="1" :name="$gettext('Beschreibung')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Dateinamen anzeigen') }}
@@ -117,7 +123,12 @@
                             <label v-if="showDescription && currentLayout === 'carousel'">
                                 {{ $gettext('Beschreibung erscheint bei Mouseover') }}
                                 <studip-tooltip-icon
-                                    :text="$gettext('Der Beschreibungstext wird angezeigt, wenn Sie den Mauszeiger über das Bild bewegen.')"/>
+                                    :text="
+                                        $gettext(
+                                            'Der Beschreibungstext wird angezeigt, wenn Sie den Mauszeiger über das Bild bewegen.'
+                                        )
+                                    "
+                                />
                                 <select v-model="currentMouseoverFileNames">
                                     <option value="true">{{ $gettext('Ja') }}</option>
                                     <option value="false">{{ $gettext('Nein') }}</option>
@@ -125,11 +136,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        v-if="currentLayout === 'carousel'"
-                        :index="2"
-                        :name="$gettext('Autoplay')"
-                    >
+                    <courseware-tab v-if="currentLayout === 'carousel'" :index="2" :name="$gettext('Autoplay')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Autoplay') }}
@@ -151,7 +158,6 @@
                             </label>
                         </form>
                     </courseware-tab>
-
                 </courseware-tabs>
             </template>
             <template #info>
@@ -162,22 +168,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFolderChooser from './CoursewareFolderChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-gallery-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFolderChooser,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -247,7 +245,7 @@ export default {
         },
         showDescription() {
             return this.currentShowFileNames === 'true' || this.currentShowFileDescription === 'true';
-        }
+        },
     },
     mounted() {
         this.initCurrentData();
@@ -279,7 +277,7 @@ export default {
         async getFolderFiles() {
             const parent = { type: 'folders', id: `${this.currentFolderId}` };
             const relationship = 'file-refs';
-            const options = { include: 'terms-of-use'}
+            const options = { include: 'terms-of-use' };
             await this.loadRelatedFileRefs({ parent, relationship, options });
 
             const files = this.relatedFileRefs({ parent, relationship });
@@ -288,10 +286,14 @@ export default {
         processFiles(files) {
             this.editModeFiles = files
                 .filter((file) => {
-                    if (this.relatedTermOfUse({parent: file, relationship: 'terms-of-use'}).attributes['download-condition'] !== 0) {
+                    if (
+                        this.relatedTermOfUse({ parent: file, relationship: 'terms-of-use' }).attributes[
+                            'download-condition'
+                        ] !== 0
+                    ) {
                         return false;
                     }
-                    if (! file.attributes['mime-type'].includes('image')) {
+                    if (!file.attributes['mime-type'].includes('image')) {
                         return false;
                     }
 
@@ -301,7 +303,7 @@ export default {
                     id: file.id,
                     attributes: {
                         name: file.attributes.name,
-                        description: file.attributes.description
+                        description: file.attributes.description,
                     },
                     meta: {
                         'download-url': this.urlHelper.getURL(
@@ -393,3 +395,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/gallery.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareHeadlineBlock.vue b/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareHeadlineBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue
index c993300ede2c6225fafd10590388062e7e550d99..c7dd6b52ab426e2f0290b9903f3a5ea4a78728f1 100644
--- a/resources/vue/components/courseware/CoursewareHeadlineBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue
@@ -293,30 +293,24 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
+import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js';
+import StockImageSelector from '../../stock-images/SelectorDialog.vue';
+import StockImageSelectableImageCard from '../../stock-images/SelectableImageCard.vue';
+import StockImageThumbnail from '../../stock-images/Thumbnail.vue';
+
 import { mapGetters, mapActions } from 'vuex';
-import contentIcons from './content-icons.js';
-import StockImageSelector from '../stock-images/SelectorDialog.vue';
-import StockImageSelectableImageCard from '../stock-images/SelectableImageCard.vue';
-import StockImageThumbnail from '../stock-images/Thumbnail.vue';
 
 export default {
     name: 'courseware-headline-block',
-    mixins: [blockMixin, colorMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
+    mixins: [blockMixin, colorMixin, contentIconsMixin],
+    components: Object.assign(BlockComponents, {
         StockImageSelector,
         StockImageSelectableImageCard,
         StockImageThumbnail,
-    },
+    }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -401,7 +395,7 @@ export default {
             return this.calcComplement(this.backgroundColor);
         },
         icons() {
-            return contentIcons;
+            return this.contentIcons;
         },
         colors() {
             return this.mixinColors;
@@ -632,3 +626,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+    @import "../../../../assets/stylesheets/scss/courseware/blocks/headline.scss";
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareIframeBlock.vue b/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue
similarity index 91%
rename from resources/vue/components/courseware/CoursewareIframeBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue
index e1aa21e5b5d5415739593d2e214f013fb10e437e..90df3f66e0970660bbcc3f4b50ba36b7da804ab3 100644
--- a/resources/vue/components/courseware/CoursewareIframeBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue
@@ -31,11 +31,7 @@
             </template>
             <template v-if="canEdit" #edit>
                 <courseware-tabs>
-                    <courseware-tab
-                        :index="0"
-                        :name="$gettext('Grunddaten')"
-                        :selected="true"
-                    >
+                    <courseware-tab :index="0" :name="$gettext('Grunddaten')" :selected="true">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Titel') }}
@@ -51,10 +47,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="1"
-                        :name="$gettext('Nutzerspezifische ID')"
-                    >
+                    <courseware-tab :index="1" :name="$gettext('Nutzerspezifische ID')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Nutzerspezifische ID übergeben') }}
@@ -74,10 +67,7 @@
                             </label>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="2"
-                        :name="$gettext('Creative Commons')"
-                    >
+                    <courseware-tab :index="2" :name="$gettext('Creative Commons')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Creative Commons Lizenz') }}
@@ -94,11 +84,16 @@
                                         (by-nd) {{ $gettext('Namensnennung & Keine Bearbeitung') }}
                                     </option>
                                     <option value="by-nc-nd">
-                                        (by-nc-nd) {{ $gettext('Namensnennung & Nicht kommerziell & Keine Bearbeitung') }}
+                                        (by-nc-nd)
+                                        {{ $gettext('Namensnennung & Nicht kommerziell & Keine Bearbeitung') }}
                                     </option>
                                     <option value="by-nc-sa">
                                         (by-nc-sa)
-                                        {{ $gettext('Namensnennung & Nicht kommerziell & Weitergabe unter gleichen Bedingungen') }}
+                                        {{
+                                            $gettext(
+                                                'Namensnennung & Nicht kommerziell & Weitergabe unter gleichen Bedingungen'
+                                            )
+                                        }}
                                     </option>
                                 </select>
                             </label>
@@ -126,21 +121,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 import md5 from 'md5';
 
 export default {
     name: 'courseware-iframe-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -264,3 +253,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/iframe.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareImageMapBlock.vue b/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue
similarity index 88%
rename from resources/vue/components/courseware/CoursewareImageMapBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue
index cfcd8f769dee4ac6b1fdcda68e456cdb47679773..41b39d2cb395d2f27139e81f785a7b3b8191903e 100644
--- a/resources/vue/components/courseware/CoursewareImageMapBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue
@@ -28,33 +28,38 @@
                         :title="area.title"
                         :href="area.external_target"
                         :target="area.link_target"
-                        @click=" 
+                        @click="
                             if (area.target_type === 'internal') {
                                 areaLink(area.internal_target);
                             }
                         "
                     />
                 </map>
-                <div v-if="showEditMode && viewMode === 'edit' && currentShapes.length > 0"
-                    ref="draggableShapeWrapper" class="cw-draggable-shapes-wrapper">
+                <div
+                    v-if="showEditMode && viewMode === 'edit' && currentShapes.length > 0"
+                    ref="draggableShapeWrapper"
+                    class="cw-draggable-shapes-wrapper"
+                >
                     <vue-resizeable
-                            v-for="(shape, index) in currentShapes"
-                            :key="index"
-                            :index="index"
-                            style="position: absolute"
-                            ref="resizableAreaComponents"
-                            :fitParent="true"
-                            :dragSelector="dragSelector"
-                            :active="handlers"
-                            :left="getShapeOffsetLeft(shape)"
-                            :top="getShapeOffsetTop(shape)"
-                            :width="getShapeWidth(shape)"
-                            :height="getShapeHeight(shape)"
-                            @resize:start="dragStartHandler"
-                            @resize:end="endDraggingShape"
-                            @drag:start="dragStartHandler"
-                            @drag:end="endDraggingShape">
-                        <div class="cw-draggable-area"
+                        v-for="(shape, index) in currentShapes"
+                        :key="index"
+                        :index="index"
+                        style="position: absolute"
+                        ref="resizableAreaComponents"
+                        :fitParent="true"
+                        :dragSelector="dragSelector"
+                        :active="handlers"
+                        :left="getShapeOffsetLeft(shape)"
+                        :top="getShapeOffsetTop(shape)"
+                        :width="getShapeWidth(shape)"
+                        :height="getShapeHeight(shape)"
+                        @resize:start="dragStartHandler"
+                        @resize:end="endDraggingShape"
+                        @drag:start="dragStartHandler"
+                        @drag:end="endDraggingShape"
+                    >
+                        <div
+                            class="cw-draggable-area"
                             :style="{
                                 backgroundColor: getColorRGBA(shape.data.color),
                                 color: shape.data.textcolor ? getColorRGBA(shape.data.textcolor) : '',
@@ -62,7 +67,8 @@
                                 border: getShapeBorder(shape),
                                 cursor: selectedShapeIndex !== false ? 'grabbing' : '',
                             }"
-                            @click="followLink(index)">
+                            @click="followLink(index)"
+                        >
                             {{ shape.data.text }}
                         </div>
                     </vue-resizeable>
@@ -97,22 +103,26 @@
                                 <studip-select
                                     :options="colors"
                                     label="name"
-                                    :reduce="color => color.class"
+                                    :reduce="(color) => color.class"
                                     :clearable="false"
                                     v-model="shape.data.color"
                                     @input="drawScreen"
                                 >
                                     <template #open-indicator="selectAttributes">
-                                        <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span>
+                                        <span v-bind="selectAttributes"
+                                            ><studip-icon shape="arr_1down" size="10"
+                                        /></span>
                                     </template>
                                     <template #no-options>
                                         {{ $gettext('Es steht keine Auswahl zur Verfügung.') }}
                                     </template>
-                                    <template #selected-option="{name, rgba}">
-                                        <span class="vs__option-color" :style="{'background-color': rgba}"></span><span>{{name}}</span>
+                                    <template #selected-option="{ name, rgba }">
+                                        <span class="vs__option-color" :style="{ 'background-color': rgba }"></span
+                                        ><span>{{ name }}</span>
                                     </template>
-                                    <template #option="{name, rgba}">
-                                        <span class="vs__option-color" :style="{'background-color': rgba}"></span><span>{{name}}</span>
+                                    <template #option="{ name, rgba }">
+                                        <span class="vs__option-color" :style="{ 'background-color': rgba }"></span
+                                        ><span>{{ name }}</span>
                                     </template>
                                 </studip-select>
                             </label>
@@ -121,26 +131,30 @@
                                 <studip-select
                                     :options="colors"
                                     label="name"
-                                    :reduce="color => color.class"
+                                    :reduce="(color) => color.class"
                                     :clearable="false"
                                     v-model="shape.data.textcolor"
                                     @input="drawScreen"
                                 >
                                     <template #open-indicator="selectAttributes">
-                                        <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span>
+                                        <span v-bind="selectAttributes"
+                                            ><studip-icon shape="arr_1down" size="10"
+                                        /></span>
                                     </template>
                                     <template #no-options>
                                         {{ $gettext('Es steht keine Auswahl zur Verfügung.') }}
                                     </template>
-                                    <template #selected-option="{name, rgba}">
-                                        <span class="vs__option-color" :style="{'background-color': rgba}"></span><span>{{name}}</span>
+                                    <template #selected-option="{ name, rgba }">
+                                        <span class="vs__option-color" :style="{ 'background-color': rgba }"></span
+                                        ><span>{{ name }}</span>
                                     </template>
-                                    <template #option="{name, rgba}">
-                                        <span class="vs__option-color" :style="{'background-color': rgba}"></span><span>{{name}}</span>
+                                    <template #option="{ name, rgba }">
+                                        <span class="vs__option-color" :style="{ 'background-color': rgba }"></span
+                                        ><span>{{ name }}</span>
                                     </template>
                                 </studip-select>
                             </label>
-                            <br>
+                            <br />
                             <template v-if="shape.type === 'arc'">
                                 <label class="col-1">
                                     X
@@ -199,7 +213,7 @@
                                 {{ $gettext('Beschriftung') }}
                                 <input type="text" v-model="shape.data.text" @change="drawScreen" />
                             </label>
-                            <br>
+                            <br />
                             <label class="col-2">
                                 {{ $gettext('Art des Links') }}
                                 <select v-model="shape.link_type">
@@ -228,9 +242,9 @@
                                 />
                             </label>
                             <label>
-                                <a class="button cancel" @click="removeShape(index)"
-                                    >{{ $gettext('Form entfernen') }}</a
-                                >
+                                <a class="button cancel" @click="removeShape(index)">{{
+                                    $gettext('Form entfernen')
+                                }}</a>
                             </label>
                         </courseware-tab>
                     </courseware-tabs>
@@ -244,24 +258,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import VueResizeable from 'vrp-vue-resizable';
-import { blockMixin } from './block-mixin.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-image-map-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
-        VueResizeable,
-    },
+    components: Object.assign(BlockComponents, { VueResizeable }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -288,11 +293,11 @@ export default {
                 { name: this.$gettext('Orange'), class: 'orange', rgba: 'rgba(243,156,18,1)' },
                 { name: this.$gettext('Grau'), class: 'grey', rgba: 'rgba(236, 240, 241,1)' },
                 { name: this.$gettext('Dunkelgrau'), class: 'darkgrey', rgba: 'rgba(52,73,94,1)' },
-                { name: this.$gettext('Schwarz'), class: 'black', rgba: 'rgba(0,0,0,1)' }
+                { name: this.$gettext('Schwarz'), class: 'black', rgba: 'rgba(0,0,0,1)' },
             ],
             file: null,
-            dragSelector: ".cw-draggable-area",
-            handlers: ["r", "rb", "b", "lb", "l", "lt", "t", "rt"],
+            dragSelector: '.cw-draggable-area',
+            handlers: ['r', 'rb', 'b', 'lb', 'l', 'lt', 't', 'rt'],
             draggedShapeWidth: 50,
             draggedShapeHeight: 50,
             selectedShapeIndex: false,
@@ -423,7 +428,9 @@ export default {
                             text_X = shape.data.centerX;
                             text_Y = shape.data.centerY - shape.data.radius * 0.75;
                             context.arc(shape.data.centerX, shape.data.centerY, shape.data.radius, 0, 2 * Math.PI); // x, y, r, startAngle, endAngle ... Angle in radians!
-                            context.fillStyle = view.colors.filter((color) => {return color.class === shape.data.color})[0].rgba;
+                            context.fillStyle = view.colors.filter((color) => {
+                                return color.class === shape.data.color;
+                            })[0].rgba;
                             context.fill();
                             break;
                         case 'ellipse':
@@ -440,7 +447,9 @@ export default {
                                 0,
                                 2 * Math.PI
                             );
-                            context.fillStyle = view.colors.filter((color) => {return color.class === shape.data.color})[0].rgba;
+                            context.fillStyle = view.colors.filter((color) => {
+                                return color.class === shape.data.color;
+                            })[0].rgba;
                             context.fill();
                             break;
                         case 'rect':
@@ -449,7 +458,9 @@ export default {
                             text_X = shape.data.X + shape.data.width / 2;
                             text_Y = shape.data.Y;
                             context.rect(shape.data.X, shape.data.Y, shape.data.width, shape.data.height);
-                            context.fillStyle = view.colors.filter((color) => {return color.class === shape.data.color})[0].rgba;
+                            context.fillStyle = view.colors.filter((color) => {
+                                return color.class === shape.data.color;
+                            })[0].rgba;
                             context.fill();
                             break;
                         default:
@@ -479,7 +490,7 @@ export default {
                 }
             });
         },
-        fitTextToShape( context , text, shapeWidth) {
+        fitTextToShape(context, text, shapeWidth) {
             shapeWidth = shapeWidth || 0;
 
             let newText = [];
@@ -492,15 +503,14 @@ export default {
             while (words.length > 0 && i <= words.length) {
                 let word = words.slice(0, i).join(' ');
                 let wordWidth = context.measureText(word).width + 2;
-                if ( wordWidth > shapeWidth ) {
+                if (wordWidth > shapeWidth) {
                     if (i === 1) {
                         i = 2;
                     }
                     newText.push(words.slice(0, i - 1).join(' '));
                     words = words.splice(i - 1);
                     i = 1;
-                }
-                else {
+                } else {
                     i++;
                 }
             }
@@ -509,7 +519,6 @@ export default {
             }
 
             return newText;
-
         },
         mapImage() {
             let view = this;
@@ -634,12 +643,12 @@ export default {
             // set current draggable div shape to canvas shape coordinates
             let canvas = this.$refs.image_from_canvas;
             let canvasSpecs = canvas.getBoundingClientRect();
-            let mouseX = (data.clientX - canvasSpecs.left) * (canvas.width/canvasSpecs.width);
-            let mouseY = (data.clientY - canvasSpecs.top) * (canvas.height/canvasSpecs.height);
+            let mouseX = (data.clientX - canvasSpecs.left) * (canvas.width / canvasSpecs.width);
+            let mouseY = (data.clientY - canvasSpecs.top) * (canvas.height / canvasSpecs.height);
             this.currentShapes.forEach((value, key) => {
                 let shape = value;
                 // if the event target is the draggable area, check for the shape area normally
-                // else check if the click was on a resizable area that belongs to a shape since 
+                // else check if the click was on a resizable area that belongs to a shape since
                 // resizable areas are partly outside the shape
                 if (data.target.classList.contains('cw-draggable-area')) {
                     if (this.mouseHit(mouseX, mouseY, shape)) {
@@ -671,9 +680,12 @@ export default {
             // transfer div shape data to canvas according to shape
             let shape = this.currentShapes[this.selectedShapeIndex];
             if (shape.type == 'arc') {
-                let circle_width = data.width != shape.data.radius * 2? data.width : data.height;
+                let circle_width = data.width != shape.data.radius * 2 ? data.width : data.height;
                 // if the shape was clicked and not dragged, set the dragging status to false to follow the link
-                if (shape.data.centerX == data.left + shape.data.radius || shape.data.centerY == data.top + shape.data.radius) {
+                if (
+                    shape.data.centerX == data.left + shape.data.radius ||
+                    shape.data.centerY == data.top + shape.data.radius
+                ) {
                     this.draggingActive = false;
                 }
                 shape.data.radius = circle_width / 2;
@@ -707,21 +719,23 @@ export default {
             if (shape.type == 'arc') {
                 let dx = shape.data.centerX - mouseX;
                 let dy = shape.data.centerY - mouseY;
-                return (dx*dx + dy*dy < shape.data.radius*shape.data.radius);
+                return dx * dx + dy * dy < shape.data.radius * shape.data.radius;
             }
-            if ((shape.type == 'rect') || (shape.type == 'text')) {
+            if (shape.type == 'rect' || shape.type == 'text') {
                 let dx = mouseX - shape.data.X;
                 let dy = mouseY - shape.data.Y;
-                return ((dx <= shape.data.width) && (dy <= shape.data.height) && (dx >= 0) && (dy >= 0));
+                return dx <= shape.data.width && dy <= shape.data.height && dx >= 0 && dy >= 0;
             }
             if (shape.type == 'ellipse') {
                 let dx = shape.data.X - mouseX;
                 let dy = shape.data.Y - mouseY;
-                return ((Math.abs(dx) < shape.data.radiusX) && (Math.abs(dy) < shape.data.radiusY));
+                return Math.abs(dx) < shape.data.radiusX && Math.abs(dy) < shape.data.radiusY;
             }
         },
         getColorRGBA(color) {
-            return this.colors.filter((col) => {return col.class === color})[0].rgba;
+            return this.colors.filter((col) => {
+                return col.class === color;
+            })[0].rgba;
         },
         getShapeBorder(shape) {
             return shape.data.color === 'transparent' ? 'dashed thin #000' : 'none';
@@ -782,6 +796,9 @@ export default {
                 this.$refs.map.areas[index].click();
             }
         },
-    }
+    },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/image-map.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareKeyPointBlock.vue b/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue
similarity index 78%
rename from resources/vue/components/courseware/CoursewareKeyPointBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue
index 687ea0b589e28cabbda4c1db99f3d2be867b3032..ab79edc3d467f4396161884de323a7557bacbdc3 100644
--- a/resources/vue/components/courseware/CoursewareKeyPointBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="cw-block cw-block-key-point">
+    <div class="cw-block cw-block-keypoint">
         <courseware-default-block
             :block="block"
             :canEdit="canEdit"
@@ -11,8 +11,8 @@
         >
             <template #content>
                 <div class="cw-keypoint-content" :class="['cw-keypoint-' + currentColor]">
-                    <studip-icon v-if="currentIcon" size="48" :shape="currentIcon" :role="currentRole"/>
-                    <p class="cw-keypoint-sentence">{{currentText}}</p>
+                    <studip-icon v-if="currentIcon" size="48" :shape="currentIcon" :role="currentRole" />
+                    <p class="cw-keypoint-sentence">{{ currentText }}</p>
                 </div>
             </template>
             <template v-if="canEdit" #edit>
@@ -27,27 +27,29 @@
                             spellcheck="true"
                         />
                     </label>
-                    <br>
+                    <br />
                     <label class="col-2">
                         {{ $gettext('Farbe') }}
                         <studip-select
                             :options="colors"
                             label="icon"
                             :clearable="false"
-                            :reduce="option => option.icon"
+                            :reduce="(option) => option.icon"
                             v-model="currentColor"
                         >
                             <template #open-indicator="selectAttributes">
-                                <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span>
+                                <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10" /></span>
                             </template>
                             <template #no-options>
                                 {{ $gettext('Es steht keine Auswahl zur Verfügung.') }}
                             </template>
-                            <template #selected-option="{name, hex}">
-                                <span class="vs__option-color" :style="{'background-color': hex}"></span><span>{{name}}</span>
+                            <template #selected-option="{ name, hex }">
+                                <span class="vs__option-color" :style="{ 'background-color': hex }"></span
+                                ><span>{{ name }}</span>
                             </template>
-                            <template #option="{name, hex}">
-                                <span class="vs__option-color" :style="{'background-color': hex}"></span><span>{{name}}</span>
+                            <template #option="{ name, hex }">
+                                <span class="vs__option-color" :style="{ 'background-color': hex }"></span
+                                ><span>{{ name }}</span>
                             </template>
                         </studip-select>
                     </label>
@@ -55,16 +57,18 @@
                         {{ $gettext('Icon') }}
                         <studip-select :options="icons" :clearable="false" v-model="currentIcon">
                             <template #open-indicator="selectAttributes">
-                                <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span>
+                                <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10" /></span>
                             </template>
                             <template #no-options>
                                 {{ $gettext('Es steht keine Auswahl zur Verfügung.') }}
                             </template>
                             <template #selected-option="option">
-                                <studip-icon :shape="option.label"/> <span class="vs__option-with-icon">{{option.label}}</span>
+                                <studip-icon :shape="option.label" />
+                                <span class="vs__option-with-icon">{{ option.label }}</span>
                             </template>
                             <template #option="option">
-                                <studip-icon :shape="option.label"/> <span class="vs__option-with-icon">{{option.label}}</span>
+                                <studip-icon :shape="option.label" />
+                                <span class="vs__option-with-icon">{{ option.label }}</span>
                             </template>
                         </studip-select>
                     </label>
@@ -78,18 +82,16 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
-import { blockMixin } from './block-mixin.js';
+import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js';
 import { mapActions } from 'vuex';
-import contentIcons from './content-icons.js';
 
 export default {
     name: 'courseware-key-point-block',
-    mixins: [blockMixin, colorMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    mixins: [blockMixin, colorMixin, contentIconsMixin],
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -107,11 +109,11 @@ export default {
             return `icons/${this.color}/${this.icon}.svg`;
         },
         icons() {
-            return contentIcons;
+            return this.contentIcons;
         },
         colors() {
-            return this.mixinColors.filter(color => 
-                color.icon && color.class !== 'white' && color.class !== 'studip-lightblue'
+            return this.mixinColors.filter(
+                (color) => color.icon && color.class !== 'white' && color.class !== 'studip-lightblue'
             );
         },
         text() {
@@ -147,7 +149,7 @@ export default {
                 default:
                     return 'clickable';
             }
-        }
+        },
     },
     methods: {
         ...mapActions({
@@ -177,3 +179,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/keypoint.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareLinkBlock.vue b/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue
similarity index 94%
rename from resources/vue/components/courseware/CoursewareLinkBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue
index f2c8cf931497d6cb750fa01fee18dfb688dc76d2..532c97b1c649b8609c22b42cc85240d73f59acc3 100644
--- a/resources/vue/components/courseware/CoursewareLinkBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareLinkBlock.vue
@@ -62,16 +62,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-link-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -135,7 +133,7 @@ export default {
             attributes.payload.title = this.currentTitle;
             if (this.currentType === 'internal' && this.currentTarget === '') {
                 this.companionWarning({
-                    info: this.$gettext('Bitte wählen Sie eine Seite als Ziel aus.')
+                    info: this.$gettext('Bitte wählen Sie eine Seite als Ziel aus.'),
                 });
                 return false;
             } else {
@@ -145,8 +143,10 @@ export default {
                     containerId: this.block.relationships.container.data.id,
                 });
             }
-
         },
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/link.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareLtiBlock.vue b/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue
similarity index 75%
rename from resources/vue/components/courseware/CoursewareLtiBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue
index e96796250502d092cb0f7e38ef0b5514c2522308..626a1a020313db5bc2072396f17a8760e0050c16 100644
--- a/resources/vue/components/courseware/CoursewareLtiBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue
@@ -28,11 +28,7 @@
             </template>
             <template v-if="canEdit" #edit>
                 <courseware-tabs>
-                    <courseware-tab
-                        :index="0"
-                        :name="$gettext('Grunddaten')"
-                        :selected="true"
-                    >
+                    <courseware-tab :index="0" :name="$gettext('Grunddaten')" :selected="true">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Titel') }}
@@ -49,26 +45,49 @@
                             </label>
                             <label v-show="allowCustomUrl">
                                 {{ $gettext('URL der Anwendung (optional)') }}
-                                <studip-tooltip-icon :text="$gettext('Sie können direkt auf eine URL in der Anwendung verlinken.')"/>
+                                <studip-tooltip-icon
+                                    :text="$gettext('Sie können direkt auf eine URL in der Anwendung verlinken.')"
+                                />
                                 <input type="text" v-model="currentLaunchUrl" :placeholder="currentTool?.launch_url" />
                             </label>
 
                             <div v-show="customToolSelected">
                                 <label class="studiprequired">
                                     {{ $gettext('URL der Anwendung') }}
-                                    <span class="asterisk" :title="$gettext('Dies ist ein Pflichtfeld')" aria-hidden="true">*</span>
-                                    <studip-tooltip-icon :text="$gettext('Die Betreiber dieses Tools müssen Ihnen eine URL und Zugangsdaten (Consumer-Key und Consumer-Secret) mitteilen.')"/>
-                                    <input type="text" v-model="currentLaunchUrl" required>
+                                    <span
+                                        class="asterisk"
+                                        :title="$gettext('Dies ist ein Pflichtfeld')"
+                                        aria-hidden="true"
+                                        >*</span
+                                    >
+                                    <studip-tooltip-icon
+                                        :text="
+                                            $gettext(
+                                                'Die Betreiber dieses Tools müssen Ihnen eine URL und Zugangsdaten (Consumer-Key und Consumer-Secret) mitteilen.'
+                                            )
+                                        "
+                                    />
+                                    <input type="text" v-model="currentLaunchUrl" required />
                                 </label>
                                 <label class="studiprequired">
                                     {{ $gettext('Consumer-Key des LTI-Tools') }}
-                                    <span class="asterisk" :title="$gettext('Dies ist ein Pflichtfeld')" aria-hidden="true">*</span>
-                                    <input type="text" v-model="currentConsumerKey" required>
+                                    <span
+                                        class="asterisk"
+                                        :title="$gettext('Dies ist ein Pflichtfeld')"
+                                        aria-hidden="true"
+                                        >*</span
+                                    >
+                                    <input type="text" v-model="currentConsumerKey" required />
                                 </label>
                                 <label class="studiprequired">
                                     {{ $gettext('Consumer-Secret des LTI-Tools') }}
-                                    <span class="asterisk" :title="$gettext('Dies ist ein Pflichtfeld')" aria-hidden="true">*</span>
-                                    <input type="text" v-model="currentConsumerSecret" required>
+                                    <span
+                                        class="asterisk"
+                                        :title="$gettext('Dies ist ein Pflichtfeld')"
+                                        aria-hidden="true"
+                                        >*</span
+                                    >
+                                    <input type="text" v-model="currentConsumerSecret" required />
                                 </label>
                                 <label>
                                     {{ $gettext('OAuth Signatur Methode des LTI-Tools') }}
@@ -80,15 +99,18 @@
                                 <label>
                                     <input type="checkbox" v-model="currentSendLisPerson" />
                                     {{ $gettext('Nutzerdaten an LTI-Tool senden') }}
-                                    <studip-tooltip-icon :text="$gettext('Nutzerdaten dürfen nur an das externe Tool gesendet werden, wenn es keine Datenschutzbedenken gibt. Mit Setzen des Hakens bestätigen Sie, dass die Übermittlung der Daten zulässig ist.')"/>
+                                    <studip-tooltip-icon
+                                        :text="
+                                            $gettext(
+                                                'Nutzerdaten dürfen nur an das externe Tool gesendet werden, wenn es keine Datenschutzbedenken gibt. Mit Setzen des Hakens bestätigen Sie, dass die Übermittlung der Daten zulässig ist.'
+                                            )
+                                        "
+                                    />
                                 </label>
                             </div>
                         </form>
                     </courseware-tab>
-                    <courseware-tab
-                        :index="1"
-                        :name="$gettext('Zusätzliche Einstellungen')"
-                    >
+                    <courseware-tab :index="1" :name="$gettext('Zusätzliche Einstellungen')">
                         <form class="default" @submit.prevent="">
                             <label>
                                 {{ $gettext('Höhe') }}
@@ -96,7 +118,9 @@
                             </label>
                             <label>
                                 {{ $gettext('Zusätzliche LTI-Parameter') }}
-                                <studip-tooltip-icon :text="$gettext('Ein Wert pro Zeile, Beispiel: Review:Chapter=1.2.56')"/>
+                                <studip-tooltip-icon
+                                    :text="$gettext('Ein Wert pro Zeile, Beispiel: Review:Chapter=1.2.56')"
+                                />
                                 <textarea v-model="currentCustomParameters" />
                             </label>
                         </form>
@@ -111,20 +135,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from "./CoursewareDefaultBlock.vue";
-import {blockMixin} from "./block-mixin";
-import {mapActions, mapGetters} from "vuex";
-import CoursewareTabs from "./CoursewareTabs.vue";
-import CoursewareTab from "./CoursewareTab.vue";
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
+import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-lti-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareTab,
-        CoursewareTabs,
-        CoursewareDefaultBlock
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -141,7 +159,7 @@ export default {
             currentOauthSignatureMethod: '',
             currentSendLisPerson: false,
             currentCustomParameters: '',
-        }
+        };
     },
     computed: {
         ...mapGetters({
@@ -155,7 +173,7 @@ export default {
             return this.block?.attributes?.payload?.height;
         },
         tools() {
-            return this.ltiTools.map(tool => ({
+            return this.ltiTools.map((tool) => ({
                 id: tool.id,
                 name: tool.attributes.name,
                 launch_url: tool.attributes['launch-url'],
@@ -166,7 +184,7 @@ export default {
             return this.block?.attributes?.payload?.tool_id;
         },
         currentTool() {
-            return this.tools.find(tool => tool.id === this.currentToolId);
+            return this.tools.find((tool) => tool.id === this.currentToolId);
         },
         allowCustomUrl() {
             return this.currentTool?.allow_custom_url;
@@ -214,7 +232,7 @@ export default {
             this.currentConsumerKey = this.consumerKey;
             this.currentConsumerSecret = this.consumerSecret;
             this.currentOauthSignatureMethod = this.oauthSignatureMethod;
-            this.currentSendLisPerson = Boolean(this.sendLisPerson);  // prevent undefined value
+            this.currentSendLisPerson = Boolean(this.sendLisPerson); // prevent undefined value
             this.currentCustomParameters = this.customParameters;
         },
         storeBlock() {
@@ -222,19 +240,19 @@ export default {
             if (this.currentToolId === '0') {
                 if (!this.currentLaunchUrl) {
                     this.companionWarning({
-                        info: this.$gettext('Bitte geben Sie eine URL der Anwendung an.')
+                        info: this.$gettext('Bitte geben Sie eine URL der Anwendung an.'),
                     });
                     return false;
                 }
                 if (!this.currentConsumerKey) {
                     this.companionWarning({
-                        info: this.$gettext('Bitte geben Sie den Consumer-Key des LTI-Tools an.')
+                        info: this.$gettext('Bitte geben Sie den Consumer-Key des LTI-Tools an.'),
                     });
                     return false;
                 }
                 if (!this.currentConsumerSecret) {
                     this.companionWarning({
-                        info: this.$gettext('Bitte geben Sie den Consumer-Secret des LTI-Tools an.')
+                        info: this.$gettext('Bitte geben Sie den Consumer-Secret des LTI-Tools an.'),
                     });
                     return false;
                 }
@@ -273,7 +291,10 @@ export default {
                     this.currentToolId = '0';
                 }
             }
-        }
+        },
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/lti.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewarePDFTableOfContent.vue b/resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewarePDFTableOfContent.vue
rename to resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue
diff --git a/resources/vue/components/courseware/CoursewareTableOfContentsBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue
similarity index 74%
rename from resources/vue/components/courseware/CoursewareTableOfContentsBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue
index e495323787acdc8fd245593c415ad30e96169306..ef111bfa4a0f26e72757449ee21a67853c539541 100644
--- a/resources/vue/components/courseware/CoursewareTableOfContentsBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue
@@ -11,55 +11,69 @@
         >
             <template #content>
                 <div v-if="childElementsWithTasks.length > 0">
-                    <div v-if="currentStyle !== 'tiles' && currentTitle !== ''" class="cw-block-title">{{ currentTitle }}</div>
+                    <div v-if="currentStyle !== 'tiles' && currentTitle !== ''" class="cw-block-title">
+                        {{ currentTitle }}
+                    </div>
                     <ul
                         v-if="currentStyle === 'list-details' || currentStyle === 'list'"
                         :class="['cw-block-table-of-contents-' + currentStyle]"
                     >
                         <li v-for="child in childElementsWithTasks" :key="child.id">
                             <router-link :to="'/structural_element/' + child.id">
-                                <div class="cw-block-table-of-contents-title-box" :class="[child.attributes.payload.color]">
+                                <div
+                                    class="cw-block-table-of-contents-title-box"
+                                    :class="[child.attributes.payload.color]"
+                                >
                                     {{ child.attributes.title }}
                                     <span v-if="child.attributes.purpose === 'task'"> | {{ child.solverName }}</span>
-                                    <p v-if="currentStyle === 'list-details'">{{ child.attributes.payload.description }}</p>
+                                    <p v-if="currentStyle === 'list-details'">
+                                        {{ child.attributes.payload.description }}
+                                    </p>
                                 </div>
                             </router-link>
                         </li>
                     </ul>
-                    <ul
-                        v-if="currentStyle === 'tiles'" 
-                        class="cw-block-table-of-contents-tiles cw-tiles"
-                    >
+                    <ul v-if="currentStyle === 'tiles'" class="cw-block-table-of-contents-tiles cw-tiles">
                         <li
                             v-for="child in childElementsWithTasks"
                             :key="child.id"
                             class="tile"
                             :class="[child.attributes.payload.color]"
                         >
-                            <router-link :to="'/structural_element/' + child.id" :title="child.attributes.purpose === 'task' ? child.attributes.title + ' | ' + child.solverName : child.attributes.title"> 
+                            <router-link
+                                :to="'/structural_element/' + child.id"
+                                :title="
+                                    child.attributes.purpose === 'task'
+                                        ? child.attributes.title + ' | ' + child.solverName
+                                        : child.attributes.title
+                                "
+                            >
                                 <div
                                     class="preview-image"
                                     :class="[hasImage(child) ? '' : 'default-image']"
                                     :style="getChildStyle(child)"
                                 >
-                                    <div v-if="child.attributes.purpose === 'task'" class="overlay-text">{{ child.solverName }}</div>
+                                    <div v-if="child.attributes.purpose === 'task'" class="overlay-text">
+                                        {{ child.solverName }}
+                                    </div>
                                 </div>
                                 <div class="description">
                                     <header
-                                        :class="[child.attributes.purpose !== '' ? 'description-icon-' + child.attributes.purpose : '']"
+                                        :class="[
+                                            child.attributes.purpose !== ''
+                                                ? 'description-icon-' + child.attributes.purpose
+                                                : '',
+                                        ]"
                                     >
-                                        {{ child.attributes.title || "–"}}
+                                        {{ child.attributes.title || '–' }}
                                     </header>
                                     <div class="description-text-wrapper">
                                         <p>{{ child.attributes.payload.description }}</p>
                                     </div>
                                     <footer>
                                         {{ countChildChildren(child) }}
-                                        <translate
-                                            :translate-n="countChildChildren(child)"
-                                            translate-plural="Seiten"
-                                        >
-                                        Seite
+                                        <translate :translate-n="countChildChildren(child)" translate-plural="Seiten">
+                                            Seite
                                         </translate>
                                     </footer>
                                 </div>
@@ -69,8 +83,12 @@
                 </div>
                 <courseware-companion-box
                     v-if="viewMode === 'edit' && childElementsWithTasks.length === 0"
-                    :msgCompanion="$gettext('Es sind noch keine Unterseiten vorhanden. ' +
-                        'Sobald Sie weitere Unterseiten anlegen, erscheinen diese automatisch hier im Inhaltsverzeichnis.')"
+                    :msgCompanion="
+                        $gettext(
+                            'Es sind noch keine Unterseiten vorhanden. ' +
+                                'Sobald Sie weitere Unterseiten anlegen, erscheinen diese automatisch hier im Inhaltsverzeichnis.'
+                        )
+                    "
                     mood="pointing"
                 />
             </template>
@@ -96,18 +114,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-table-of-contents-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareCompanionBox,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -143,7 +157,7 @@ export default {
         },
         childElementsWithTasks() {
             let children = [];
-            this.childElements.forEach(element => {
+            this.childElements.forEach((element) => {
                 if (element.relationships.task.data) {
                     let solverName = this.getSolverName(element.relationships.task.data.id);
                     if (solverName) {
@@ -156,18 +170,18 @@ export default {
             });
 
             return children;
-        }
+        },
     },
     mounted() {
         this.initCurrentData();
-        this.childElements.forEach(element => {
+        this.childElements.forEach((element) => {
             if (element.relationships.task.data) {
                 const taskId = element.relationships.task.data.id;
                 try {
                     this.loadTask({
                         taskId: taskId,
                     });
-                } catch(error) {
+                } catch (error) {
                     // nothing to do here
                 }
             }
@@ -197,8 +211,8 @@ export default {
         getChildStyle(child) {
             let url = child.relationships?.image?.meta?.['download-url'];
 
-            if(url) {
-                return {'background-image': 'url(' + url + ')'};
+            if (url) {
+                return { 'background-image': 'url(' + url + ')' };
             } else {
                 return {};
             }
@@ -211,7 +225,7 @@ export default {
         },
 
         getSolverName(taskId) {
-            const task = this.taskById({ id: taskId});
+            const task = this.taskById({ id: taskId });
             if (task === undefined) {
                 return false;
             }
@@ -228,7 +242,10 @@ export default {
             }
 
             return false;
-        }
+        },
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/table-of-contents.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareTextBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTextBlock.vue
similarity index 82%
rename from resources/vue/components/courseware/CoursewareTextBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareTextBlock.vue
index df376c52fdf6df3863448961e2136817fb7979c7..f8f18bcd86d3bcd5fab416f8c03b1f233db4c6f2 100644
--- a/resources/vue/components/courseware/CoursewareTextBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareTextBlock.vue
@@ -22,17 +22,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
-import { ClassicEditor, BalloonEditor } from '@/assets/javascripts/chunks/wysiwyg'
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
+import { ClassicEditor, BalloonEditor } from '@/assets/javascripts/chunks/wysiwyg';
 import { mapActions } from 'vuex';
 
 export default {
     name: 'courseware-text-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -44,11 +42,11 @@ export default {
             editor: ClassicEditor,
             editorConfig: {
                 // The configuration of the editor.
-            }
+            },
         };
     },
     computed: {
-        text() {    
+        text() {
             return this.block?.attributes?.payload?.text;
         },
         ckeToolbarTop() {
@@ -60,7 +58,7 @@ export default {
             } else {
                 top += 85;
             }
-            
+
             return top;
         },
     },
@@ -75,7 +73,7 @@ export default {
             this.currentText = this.text;
             this.loadMathjax();
         },
-        onReady( editor )  {
+        onReady(editor) {
             editor.ui.viewportOffset = { top: this.ckeToolbarTop };
             editor.ui.update();
         },
@@ -100,14 +98,18 @@ export default {
                 mathjaxP = window.STUDIP.loadChunk('mathjax');
             }
 
-            mathjaxP && mathjaxP
-            .then(({ Hub }) => {
-                Hub.Queue(['Typeset', Hub, view.$refs.content]);
-            })
-            .catch(() => {
-                console.log('Warning: Could not load MathJax.');
-            });
+            mathjaxP &&
+                mathjaxP
+                    .then(({ Hub }) => {
+                        Hub.Queue(['Typeset', Hub, view.$refs.content]);
+                    })
+                    .catch(() => {
+                        console.log('Warning: Could not load MathJax.');
+                    });
         },
-    }
+    },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/text.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareTimelineBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareTimelineBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue
index 1cc5d4d9204f522545bab1dd42528eb5c0f948f4..4e93e70afbe8956552f9f33d876e3d2ff8407dda 100644
--- a/resources/vue/components/courseware/CoursewareTimelineBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue
@@ -143,24 +143,16 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { mapActions } from 'vuex';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
-import contentIcons from './content-icons.js';
-import StudipIcon from '../StudipIcon.vue';
+import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js';
+import { mapActions } from 'vuex';
 
 export default {
     name: 'courseware-timeline-block',
-    mixins: [blockMixin, colorMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareTabs,
-        CoursewareTab,
-        StudipIcon,
-    },
+    mixins: [blockMixin, colorMixin, contentIconsMixin],
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -186,7 +178,7 @@ export default {
             return this.block?.attributes?.payload?.dateformat;
         },
         icons() {
-            return contentIcons;
+            return this.contentIcons;
         },
         colors() {
             return this.mixinColors.filter(color => color.class !== 'white' && color.class !== 'studip-lightblue');
@@ -310,3 +302,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/timeline.scss';
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareTypewriterBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTypewriterBlock.vue
similarity index 94%
rename from resources/vue/components/courseware/CoursewareTypewriterBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareTypewriterBlock.vue
index 234f2aa5907cb96abe5189156f67f85b15c5be52..ab7f7c5dd63d7b39303f8ff156c2622f645eaf7f 100644
--- a/resources/vue/components/courseware/CoursewareTypewriterBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareTypewriterBlock.vue
@@ -67,18 +67,15 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { VueTyper } from 'vue-typer';
 import { mapActions } from 'vuex';
 
 export default {
     name: 'courseware-typewriter-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        VueTyper,
-    },
+    components: Object.assign(BlockComponents, { VueTyper }),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -154,3 +151,6 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+@import '../../../../assets/stylesheets/scss/courseware/blocks/typewriter.scss';
+</style>
diff --git a/resources/vue/components/courseware/CoursewareVideoBlock.vue b/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareVideoBlock.vue
rename to resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue
index 66c3cf289a1bd42ff60908cfcc9b993bb514ea96..2ed3074426222f17d14b4a7a9abcf9f83f4ea761 100644
--- a/resources/vue/components/courseware/CoursewareVideoBlock.vue
+++ b/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue
@@ -90,22 +90,14 @@
 </template>
 
 <script>
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import { blockMixin } from './block-mixin.js';
+import BlockComponents from './block-components.js';
+import blockMixin from '@/vue/mixins/courseware/block.js';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-video-block',
     mixins: [blockMixin],
-    components: {
-        CoursewareDefaultBlock,
-        CoursewareFileChooser,
-        CoursewareTabs,
-        CoursewareTab,
-    },
+    components: Object.assign(BlockComponents, {}),
     props: {
         block: Object,
         canEdit: Boolean,
@@ -240,3 +232,10 @@ export default {
     },
 };
 </script>
+<style scoped lang="scss">
+.cw-block-video {
+    video {
+        width: 100%;
+    }
+}
+</style>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/blocks/block-components.js b/resources/vue/components/courseware/blocks/block-components.js
new file mode 100644
index 0000000000000000000000000000000000000000..a79ed4a30493de0632b116253bab80a8c2969b5f
--- /dev/null
+++ b/resources/vue/components/courseware/blocks/block-components.js
@@ -0,0 +1,18 @@
+import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
+import CoursewareFileChooser from '../layouts/CoursewareFileChooser.vue';
+import CoursewareFolderChooser from '../layouts/CoursewareFolderChooser.vue';
+import CoursewareTabs from '../layouts/CoursewareTabs.vue';
+import CoursewareTab from '../layouts/CoursewareTab.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue'
+
+const BlockComponents = {
+    CoursewareDefaultBlock,
+    CoursewareFileChooser,
+    CoursewareFolderChooser,
+
+    CoursewareTabs,
+    CoursewareTab,
+    CoursewareCompanionBox,
+}
+
+export default BlockComponents;
\ No newline at end of file
diff --git a/resources/vue/components/courseware/container-components.js b/resources/vue/components/courseware/container-components.js
deleted file mode 100644
index 63e665887bd3fd44090345b22c7b17b728065c42..0000000000000000000000000000000000000000
--- a/resources/vue/components/courseware/container-components.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareDefaultContainer from './CoursewareDefaultContainer.vue';
-import CoursewareBlockAdderArea from './CoursewareBlockAdderArea.vue';
-// blocks
-import CoursewareAudioBlock from './CoursewareAudioBlock.vue';
-import CoursewareBeforeAfterBlock from './CoursewareBeforeAfterBlock.vue';
-import CoursewareCanvasBlock from './CoursewareCanvasBlock.vue';
-import CoursewareChartBlock from './CoursewareChartBlock.vue';
-import CoursewareCodeBlock from './CoursewareCodeBlock.vue';
-import CoursewareConfirmBlock from './CoursewareConfirmBlock.vue';
-import CoursewareDateBlock from './CoursewareDateBlock.vue';
-import CoursewareDialogCardsBlock from './CoursewareDialogCardsBlock.vue';
-import CoursewareDocumentBlock from './CoursewareDocumentBlock.vue';
-import CoursewareDownloadBlock from './CoursewareDownloadBlock.vue';
-import CoursewareEmbedBlock from './CoursewareEmbedBlock.vue';
-import CoursewareErrorBlock from './CoursewareErrorBlock.vue';
-import CoursewareFolderBlock from './CoursewareFolderBlock.vue';
-import CoursewareGalleryBlock from './CoursewareGalleryBlock.vue';
-import CoursewareHeadlineBlock from './CoursewareHeadlineBlock.vue';
-import CoursewareIframeBlock from './CoursewareIframeBlock.vue';
-import CoursewareImageMapBlock from './CoursewareImageMapBlock.vue';
-import CoursewareKeyPointBlock from './CoursewareKeyPointBlock.vue';
-import CoursewareLinkBlock from './CoursewareLinkBlock.vue';
-import CoursewareLtiBlock from "./CoursewareLtiBlock.vue";
-import CoursewareTableOfContentsBlock from './CoursewareTableOfContentsBlock.vue';
-import CoursewareTextBlock from './CoursewareTextBlock.vue';
-import CoursewareTimelineBlock from './CoursewareTimelineBlock.vue';
-import CoursewareTypewriterBlock from './CoursewareTypewriterBlock.vue';
-import CoursewareVideoBlock from './CoursewareVideoBlock.vue';
-import CoursewareBiographyAchievementsBlock from './CoursewareBiographyAchievementsBlock.vue';
-import CoursewareBiographyCareerBlock from './CoursewareBiographyCareerBlock.vue';
-import CoursewareBiographyGoalsBlock from './CoursewareBiographyGoalsBlock.vue';
-import CoursewareBiographyPersonalInformationBlock from './CoursewareBiographyPersonalInformationBlock.vue';
-
-
-const ContainerComponents = {
-    CoursewareDefaultBlock,
-    CoursewareDefaultContainer,
-    CoursewareBlockAdderArea,
-    // blocks
-    CoursewareAudioBlock,
-    CoursewareBeforeAfterBlock,
-    CoursewareCanvasBlock,
-    CoursewareChartBlock,
-    CoursewareCodeBlock,
-    CoursewareConfirmBlock,
-    CoursewareDateBlock,
-    CoursewareDialogCardsBlock,
-    CoursewareDocumentBlock,
-    CoursewareDownloadBlock,
-    CoursewareEmbedBlock,
-    CoursewareErrorBlock,
-    CoursewareFolderBlock,
-    CoursewareGalleryBlock,
-    CoursewareHeadlineBlock,
-    CoursewareIframeBlock,
-    CoursewareImageMapBlock,
-    CoursewareKeyPointBlock,
-    CoursewareLinkBlock,
-    CoursewareLtiBlock,
-    CoursewareTableOfContentsBlock,
-    CoursewareTextBlock,
-    CoursewareTimelineBlock,
-    CoursewareTypewriterBlock,
-    CoursewareVideoBlock,
-    CoursewareBiographyAchievementsBlock,
-    CoursewareBiographyCareerBlock,
-    CoursewareBiographyGoalsBlock,
-    CoursewareBiographyPersonalInformationBlock,
-};
-
-export default ContainerComponents;
diff --git a/resources/vue/components/courseware/CoursewareAccordionContainer.vue b/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareAccordionContainer.vue
rename to resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue
index f1ae440977d568af89fbae027605db39ce6d8b5f..33f515a5b2057eed65310638bd5bee724905105b 100644
--- a/resources/vue/components/courseware/CoursewareAccordionContainer.vue
+++ b/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue
@@ -118,19 +118,17 @@
 
 <script>
 import ContainerComponents from './container-components.js';
-import containerMixin from '../../mixins/courseware/container.js';
-import contentIcons from './content-icons.js';
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
-import StudipIcon from './../StudipIcon.vue';
+import CoursewareCollapsibleBox from '../layouts/CoursewareCollapsibleBox.vue';
+import containerMixin from '@/vue/mixins/courseware/container.js';
+import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js';
 
 import { mapGetters, mapActions } from 'vuex';
 
 export default {
     name: 'courseware-accordion-container',
-    mixins: [containerMixin],
+    mixins: [containerMixin, contentIconsMixin],
     components: Object.assign(ContainerComponents, {
         CoursewareCollapsibleBox,
-        StudipIcon,
     }),
     props: {
         container: Object,
@@ -175,7 +173,7 @@ export default {
             return this.container.relationships.blocks.data.map(({ id }) => this.blockById({ id })).filter((a) => a);
         },
         icons() {
-            return contentIcons;
+            return this.contentIcons;
         },
     },
     mounted() {
diff --git a/resources/vue/components/courseware/CoursewareBlockAdderArea.vue b/resources/vue/components/courseware/containers/CoursewareBlockAdderArea.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareBlockAdderArea.vue
rename to resources/vue/components/courseware/containers/CoursewareBlockAdderArea.vue
index fc9b41f6a564aeeec0419fb860b313234198c015..b81ee96c254a9f04fe8ea2f29ba637ffcb5df8e7 100644
--- a/resources/vue/components/courseware/CoursewareBlockAdderArea.vue
+++ b/resources/vue/components/courseware/containers/CoursewareBlockAdderArea.vue
@@ -13,7 +13,7 @@
 </template>
 
 <script>
-import StudipIcon from '../StudipIcon.vue';
+import StudipIcon from '../../StudipIcon.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareContainerActions.vue b/resources/vue/components/courseware/containers/CoursewareContainerActions.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareContainerActions.vue
rename to resources/vue/components/courseware/containers/CoursewareContainerActions.vue
diff --git a/resources/vue/components/courseware/CoursewareContainerAdderItem.vue b/resources/vue/components/courseware/containers/CoursewareContainerAdderItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareContainerAdderItem.vue
rename to resources/vue/components/courseware/containers/CoursewareContainerAdderItem.vue
diff --git a/resources/vue/components/courseware/CoursewareDefaultContainer.vue b/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareDefaultContainer.vue
rename to resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue
index 7e486d9a159e7c6b87c899b3b5e119605d0cf263..e8e2bb5a563c4471cbec6357e2a03cdd9a5d1452 100644
--- a/resources/vue/components/courseware/CoursewareDefaultContainer.vue
+++ b/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue
@@ -129,7 +129,7 @@
 
 <script>
 import CoursewareContainerActions from './CoursewareContainerActions.vue';
-import StudipDialog from '../StudipDialog.vue';
+import StudipDialog from '../../StudipDialog.vue';
 import { mapGetters, mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareListContainer.vue b/resources/vue/components/courseware/containers/CoursewareListContainer.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareListContainer.vue
rename to resources/vue/components/courseware/containers/CoursewareListContainer.vue
index 7ac036a11f91f5c6eb33fa855febbd5ba754dfbc..6d8089f61a0d1835275b99883fc606b64fa785c5 100644
--- a/resources/vue/components/courseware/CoursewareListContainer.vue
+++ b/resources/vue/components/courseware/containers/CoursewareListContainer.vue
@@ -69,8 +69,7 @@
 
 <script>
 import ContainerComponents from './container-components.js';
-import containerMixin from '../../mixins/courseware/container.js';
-import StudipProgressIndicator from '../StudipProgressIndicator.vue';
+import containerMixin from '@/vue/mixins/courseware/container.js';
 import draggable from 'vuedraggable';
 import { mapActions, mapGetters } from 'vuex';
 
@@ -79,7 +78,6 @@ export default {
     mixins: [containerMixin],
     components: Object.assign(ContainerComponents, {
         draggable,
-        StudipProgressIndicator
     }),
     props: {
         container: Object,
diff --git a/resources/vue/components/courseware/CoursewareTabsContainer.vue b/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareTabsContainer.vue
rename to resources/vue/components/courseware/containers/CoursewareTabsContainer.vue
index 5cb4ee7791253fd0ab5b520d53e42ce4c872a668..c6264c765acb8e75bf2cb4d87a33dadf932c0984 100644
--- a/resources/vue/components/courseware/CoursewareTabsContainer.vue
+++ b/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue
@@ -117,23 +117,19 @@
 
 <script>
 import ContainerComponents from './container-components.js';
-import containerMixin from '../../mixins/courseware/container.js';
-import contentIcons from './content-icons.js';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
-import StudipIcon from './../StudipIcon.vue';
+import CoursewareTabs from '../layouts/CoursewareTabs.vue';
+import CoursewareTab from '../layouts/CoursewareTab.vue';
+import containerMixin from '@/vue/mixins/courseware/container.js';
+import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js';
 
 import { mapGetters, mapActions } from 'vuex';
 
 export default {
     name: 'courseware-tabs-container',
-    mixins: [containerMixin],
+    mixins: [containerMixin, contentIconsMixin],
     components: Object.assign(ContainerComponents, {
         CoursewareTabs,
         CoursewareTab,
-        CoursewareCollapsibleBox,
-        StudipIcon,
     }),
     props: {
         container: Object,
@@ -180,7 +176,7 @@ export default {
             return this.container.relationships.blocks.data.map(({ id }) => this.blockById({ id })).filter((a) => a);
         },
         icons() {
-            return contentIcons;
+            return this.contentIcons;
         },
     },
     mounted() {
diff --git a/resources/vue/components/courseware/containers/container-components.js b/resources/vue/components/courseware/containers/container-components.js
new file mode 100644
index 0000000000000000000000000000000000000000..03c98b4359261531a88b701f14bbf7414ce09eee
--- /dev/null
+++ b/resources/vue/components/courseware/containers/container-components.js
@@ -0,0 +1,77 @@
+import CoursewareDefaultBlock from '../blocks/CoursewareDefaultBlock.vue';
+import CoursewareDefaultContainer from './CoursewareDefaultContainer.vue';
+import CoursewareBlockAdderArea from './CoursewareBlockAdderArea.vue';
+// blocks
+import CoursewareAudioBlock from '../blocks/CoursewareAudioBlock.vue';
+import CoursewareBeforeAfterBlock from '../blocks/CoursewareBeforeAfterBlock.vue';
+import CoursewareBiographyAchievementsBlock from '../blocks/CoursewareBiographyAchievementsBlock.vue';
+import CoursewareBiographyCareerBlock from '../blocks/CoursewareBiographyCareerBlock.vue';
+import CoursewareBiographyGoalsBlock from '../blocks/CoursewareBiographyGoalsBlock.vue';
+import CoursewareBiographyPersonalInformationBlock from '../blocks/CoursewareBiographyPersonalInformationBlock.vue';
+import CoursewareCanvasBlock from '../blocks/CoursewareCanvasBlock.vue';
+import CoursewareChartBlock from '../blocks/CoursewareChartBlock.vue';
+import CoursewareCodeBlock from '../blocks/CoursewareCodeBlock.vue';
+import CoursewareConfirmBlock from '../blocks/CoursewareConfirmBlock.vue';
+import CoursewareDateBlock from '../blocks/CoursewareDateBlock.vue';
+import CoursewareDialogCardsBlock from '../blocks/CoursewareDialogCardsBlock.vue';
+import CoursewareDocumentBlock from '../blocks/CoursewareDocumentBlock.vue';
+import CoursewareDownloadBlock from '../blocks/CoursewareDownloadBlock.vue';
+import CoursewareEmbedBlock from '../blocks/CoursewareEmbedBlock.vue';
+import CoursewareErrorBlock from '../blocks/CoursewareErrorBlock.vue';
+import CoursewareFolderBlock from '../blocks/CoursewareFolderBlock.vue';
+import CoursewareGalleryBlock from '../blocks/CoursewareGalleryBlock.vue';
+import CoursewareHeadlineBlock from '../blocks/CoursewareHeadlineBlock.vue';
+import CoursewareIframeBlock from '../blocks/CoursewareIframeBlock.vue';
+import CoursewareImageMapBlock from '../blocks/CoursewareImageMapBlock.vue';
+import CoursewareKeyPointBlock from '../blocks/CoursewareKeyPointBlock.vue';
+import CoursewareLinkBlock from '../blocks/CoursewareLinkBlock.vue';
+import CoursewareLtiBlock from '../blocks/CoursewareLtiBlock.vue';
+import CoursewareTableOfContentsBlock from '../blocks/CoursewareTableOfContentsBlock.vue';
+import CoursewareTextBlock from '../blocks/CoursewareTextBlock.vue';
+import CoursewareTimelineBlock from '../blocks/CoursewareTimelineBlock.vue';
+import CoursewareTypewriterBlock from '../blocks/CoursewareTypewriterBlock.vue';
+import CoursewareVideoBlock from '../blocks/CoursewareVideoBlock.vue';
+//layout
+import StudipIcon from '../../StudipIcon.vue';
+import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
+
+const ContainerComponents = {
+    CoursewareDefaultBlock,
+    CoursewareDefaultContainer,
+    CoursewareBlockAdderArea,
+    // blocks
+    CoursewareAudioBlock,
+    CoursewareBeforeAfterBlock,
+    CoursewareBiographyAchievementsBlock,
+    CoursewareBiographyCareerBlock,
+    CoursewareBiographyGoalsBlock,
+    CoursewareBiographyPersonalInformationBlock,
+    CoursewareCanvasBlock,
+    CoursewareChartBlock,
+    CoursewareCodeBlock,
+    CoursewareConfirmBlock,
+    CoursewareDateBlock,
+    CoursewareDialogCardsBlock,
+    CoursewareDocumentBlock,
+    CoursewareDownloadBlock,
+    CoursewareEmbedBlock,
+    CoursewareErrorBlock,
+    CoursewareFolderBlock,
+    CoursewareGalleryBlock,
+    CoursewareHeadlineBlock,
+    CoursewareIframeBlock,
+    CoursewareImageMapBlock,
+    CoursewareKeyPointBlock,
+    CoursewareLinkBlock,
+    CoursewareLtiBlock,
+    CoursewareTableOfContentsBlock,
+    CoursewareTextBlock,
+    CoursewareTimelineBlock,
+    CoursewareTypewriterBlock,
+    CoursewareVideoBlock,
+    //layout
+    StudipIcon,
+    StudipProgressIndicator,
+};
+
+export default ContainerComponents;
diff --git a/resources/vue/components/courseware/content-icons.js b/resources/vue/components/courseware/content-icons.js
deleted file mode 100644
index ce5464cfb0ee8a121fd03575f95e8e5b8d72c38f..0000000000000000000000000000000000000000
--- a/resources/vue/components/courseware/content-icons.js
+++ /dev/null
@@ -1,114 +0,0 @@
-const contentIcons = [
-    'accept',
-    'add',
-    'add-circle',
-    'admin',
-    'aladdin',
-    'arr_1down',
-    'arr_1left',
-    'arr_1right',
-    'arr_1up',
-    'arr_2down',
-    'arr_2left',
-    'arr_2right',
-    'arr_2up',
-    'audio',
-    'audio3',
-    'billboard',
-    'block-canvas',
-    'block-comparison',
-    'block-eyecatcher',
-    'block-gallery',
-    'block-gallery2',
-    'block-imagemap',
-    'brainstorm',
-    'campusnavi',
-    'chat2',
-    'code',
-    'community2',
-    'computer',
-    'consultation',
-    'content',
-    'courseware',
-    'crown',
-    'date-single',
-    'decline',
-    'decline-circle',
-    'doctoral_cap',
-    'download',
-    'dropbox',
-    'edit',
-    'exclaim',
-    'exclaim-circle',
-    'export',
-    'favorite',
-    'filter',
-    'globe',
-    'graph',
-    'group2',
-    'group3',
-    'group4',
-    'home2',
-    'info',
-    'info-circle',
-    'install',
-    'institute',
-    'key',
-    'knife',
-    'learnmodule',
-    'lightbulb',
-    'lightbulb2',
-    'link2',
-    'link3',
-    'link-extern',
-    'link-intern',
-    'literature',
-    'lock-locked',
-    'lock-unlocked',
-    'mail2',
-    'medal',
-    'metro',
-    'microphone',
-    'module',
-    'network',
-    'notification',
-    'notification2',
-    'opencast',
-    'outer-space',
-    'permalink',
-    'person',
-    'phone',
-    'picture',
-    'place',
-    'plugin',
-    'question',
-    'question-circle',
-    'ranking',
-    'remove',
-    'remove-circle',
-    'resources',
-    'roles',
-    'schedule2',
-    'search',
-    'settings',
-    'span-empty',
-    'span-1quarter',
-    'span-2quarter',
-    'span-3quarter',
-    'span-full',
-    'spiral',
-    'sport',
-    'staple',
-    'star',
-    'star-empty',
-    'star-halffull',
-    'test',
-    'tools',
-    'topic',
-    'ufo',
-    'video2',
-    'visibility-visible',
-    'wizard'
-];
-
-export default contentIcons;
diff --git a/resources/vue/components/courseware/CoursewareCollapsibleBox.vue b/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareCollapsibleBox.vue
rename to resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue
index c4f9233140cee087c64d2a2d4b3dd956406d9b28..7415478383d85682fd5300a9116491ff36c28a02 100644
--- a/resources/vue/components/courseware/CoursewareCollapsibleBox.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue
@@ -12,7 +12,7 @@
 </template>
 
 <script>
-import StudipIcon from './../StudipIcon.vue';
+import StudipIcon from '../../StudipIcon.vue';
 
 export default {
     name: 'courseware-collapsible-box',
@@ -54,4 +54,4 @@ export default {
         }
     }
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareCompanionBox.vue b/resources/vue/components/courseware/layouts/CoursewareCompanionBox.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareCompanionBox.vue
rename to resources/vue/components/courseware/layouts/CoursewareCompanionBox.vue
index 2e826956106f1070f93b9ecae52e52bd8bcf9525..f617e5ad2575b5945503bf0b0921b09ff753f5b0 100644
--- a/resources/vue/components/courseware/CoursewareCompanionBox.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareCompanionBox.vue
@@ -21,4 +21,4 @@ export default {
         }
     },
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareCompanionOverlay.vue b/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareCompanionOverlay.vue
rename to resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue
index 9cce904e758657fe1487259b39846f3d361f27a4..23fbf17ef96dadf1af4966cfc663c332d4a3642b 100644
--- a/resources/vue/components/courseware/CoursewareCompanionOverlay.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue
@@ -46,4 +46,4 @@ export default {
         }
     },
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareDateInput.vue b/resources/vue/components/courseware/layouts/CoursewareDateInput.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareDateInput.vue
rename to resources/vue/components/courseware/layouts/CoursewareDateInput.vue
diff --git a/resources/vue/components/courseware/CoursewareFileChooser.vue b/resources/vue/components/courseware/layouts/CoursewareFileChooser.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareFileChooser.vue
rename to resources/vue/components/courseware/layouts/CoursewareFileChooser.vue
diff --git a/resources/vue/components/courseware/CoursewareFolderChooser.vue b/resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareFolderChooser.vue
rename to resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue
diff --git a/resources/vue/components/courseware/CoursewareTab.vue b/resources/vue/components/courseware/layouts/CoursewareTab.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareTab.vue
rename to resources/vue/components/courseware/layouts/CoursewareTab.vue
index 191f552f9d922e25455f838d1222aa93a7a62943..8d2e9bd39c13f18116025839eb0cb028dac57a1a 100644
--- a/resources/vue/components/courseware/CoursewareTab.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareTab.vue
@@ -48,4 +48,4 @@ export default {
         }
     }
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareTabs.vue b/resources/vue/components/courseware/layouts/CoursewareTabs.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareTabs.vue
rename to resources/vue/components/courseware/layouts/CoursewareTabs.vue
index f38ae6576c2473afd5faf07a0582028d3c1c306e..5bdcc47cfb9580f7aed6077369d0692587fc245b 100644
--- a/resources/vue/components/courseware/CoursewareTabs.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareTabs.vue
@@ -130,4 +130,4 @@ export default {
         },
     },
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareTalkBubble.vue b/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareTalkBubble.vue
rename to resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue
index 72a240a47881a3970924be100c3adb3b32df2e2e..cd76aaa1a9b4d5fa699bdbb71da7672b3a5ef812 100644
--- a/resources/vue/components/courseware/CoursewareTalkBubble.vue
+++ b/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue
@@ -23,4 +23,4 @@ export default {
         payload: Object,
     },
 };
-</script>
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareTile.vue b/resources/vue/components/courseware/layouts/CoursewareTile.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareTile.vue
rename to resources/vue/components/courseware/layouts/CoursewareTile.vue
diff --git a/resources/vue/components/courseware/IsoDate.vue b/resources/vue/components/courseware/layouts/IsoDate.vue
similarity index 100%
rename from resources/vue/components/courseware/IsoDate.vue
rename to resources/vue/components/courseware/layouts/IsoDate.vue
diff --git a/resources/vue/components/courseware/plugin-components.js b/resources/vue/components/courseware/plugin-components.js
index e3f236ee2ca23c5582692abf89745c8c34186298..b0e371b95aefb10cfd8af2b50761a1fe928d86e8 100644
--- a/resources/vue/components/courseware/plugin-components.js
+++ b/resources/vue/components/courseware/plugin-components.js
@@ -1,11 +1,11 @@
-import CoursewareBlockAdderArea from './CoursewareBlockAdderArea.vue';
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
-import CoursewareDefaultContainer from './CoursewareDefaultContainer.vue';
-import CoursewareFileChooser from './CoursewareFileChooser.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import CoursewareBlockAdderArea from './containers/CoursewareBlockAdderArea.vue';
+import CoursewareCollapsibleBox from './layouts/CoursewareCollapsibleBox.vue';
+import CoursewareCompanionBox from './layouts/CoursewareCompanionBox.vue';
+import CoursewareDefaultBlock from './blocks/CoursewareDefaultBlock.vue';
+import CoursewareDefaultContainer from './containers/CoursewareDefaultContainer.vue';
+import CoursewareFileChooser from './layouts/CoursewareFileChooser.vue';
+import CoursewareTabs from './layouts/CoursewareTabs.vue';
+import CoursewareTab from './layouts/CoursewareTab.vue';
 
 const CoursewarePluginComponents = {
     CoursewareBlockAdderArea,
diff --git a/resources/vue/components/courseware/CoursewareBlockadderItem.vue b/resources/vue/components/courseware/structural-element/CoursewareBlockadderItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareBlockadderItem.vue
rename to resources/vue/components/courseware/structural-element/CoursewareBlockadderItem.vue
diff --git a/resources/vue/components/courseware/CoursewareClipboardItem.vue b/resources/vue/components/courseware/structural-element/CoursewareClipboardItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareClipboardItem.vue
rename to resources/vue/components/courseware/structural-element/CoursewareClipboardItem.vue
diff --git a/resources/vue/components/courseware/CoursewareEmptyElementBox.vue b/resources/vue/components/courseware/structural-element/CoursewareEmptyElementBox.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareEmptyElementBox.vue
rename to resources/vue/components/courseware/structural-element/CoursewareEmptyElementBox.vue
index 4934e05b87507753d06bf955ea0710df5aa4d0c1..062fa572bcd42075fca3ff5bca7ebeba5a9b69ab 100644
--- a/resources/vue/components/courseware/CoursewareEmptyElementBox.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareEmptyElementBox.vue
@@ -10,8 +10,8 @@
 </template>
 
 <script>
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import { mapActions, mapGetters } from 'vuex';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
 
 export default {
     name: 'courseware-empty-element-box',
diff --git a/resources/vue/components/courseware/CoursewareRibbon.vue b/resources/vue/components/courseware/structural-element/CoursewareRibbon.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareRibbon.vue
rename to resources/vue/components/courseware/structural-element/CoursewareRibbon.vue
diff --git a/resources/vue/components/courseware/CoursewareRibbonToolbar.vue b/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareRibbonToolbar.vue
rename to resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue
index 795b6fadf98544f3b49fc9bd6c94f3e2fab2c56a..164dcaef85f13f7093be890731938fddb2206e83 100644
--- a/resources/vue/components/courseware/CoursewareRibbonToolbar.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue
@@ -50,8 +50,8 @@
     </focus-trap>
 </template>
 <script>
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import CoursewareTabs from '../layouts/CoursewareTabs.vue';
+import CoursewareTab from '../layouts/CoursewareTab.vue';
 import CoursewareToolsBlockadder from './CoursewareToolsBlockadder.vue';
 import CoursewareToolsContents from './CoursewareToolsContents.vue';
 import { FocusTrap } from 'focus-trap-vue';
diff --git a/resources/vue/components/courseware/CoursewareSearchResults.vue b/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareSearchResults.vue
rename to resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue
index 9c9740db67f341bce865cc718745ee7a14899d76..6efbca260e2e82b396bdfe6ee6e1281da37431e0 100644
--- a/resources/vue/components/courseware/CoursewareSearchResults.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue
@@ -50,8 +50,8 @@
 
 <script>
 import CoursewareRibbon from './CoursewareRibbon.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import StudipIcon from '../StudipIcon.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import StudipIcon from '../../StudipIcon.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareStructuralElement.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareStructuralElement.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue
index eab4c6a54c2e0dcb777dc5e4b12f8005b2adfe4a..dba1917eea9e0c1fc28b7caf02621e196b2c7f0d 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue
@@ -648,39 +648,30 @@
 </template>
 
 <script>
-import ContainerComponents from './container-components.js';
-import CoursewarePluginComponents from './plugin-components.js';
+import ContainerComponents from '../containers/container-components.js';
+import StructuralElementComponents from './structural-element-components.js';
+import CoursewarePluginComponents from '../plugin-components.js';
 import CoursewareStructuralElementDialogAdd from './CoursewareStructuralElementDialogAdd.vue';
 import CoursewareStructuralElementDialogCopy from './CoursewareStructuralElementDialogCopy.vue';
 import CoursewareStructuralElementDialogImport from './CoursewareStructuralElementDialogImport.vue';
 import CoursewareStructuralElementDialogLink from './CoursewareStructuralElementDialogLink.vue';
 import CoursewareStructuralElementDiscussion from './CoursewareStructuralElementDiscussion.vue';
 import CoursewareStructuralElementPermissions from './CoursewareStructuralElementPermissions.vue';
-import CoursewareContentPermissions from './CoursewareContentPermissions.vue';
-import CoursewareAccordionContainer from './CoursewareAccordionContainer.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareContentPermissions from '../CoursewareContentPermissions.vue';
 import CoursewareWelcomeScreen from './CoursewareWelcomeScreen.vue';
-import CoursewareEmptyElementBox from './CoursewareEmptyElementBox.vue';
-import CoursewareListContainer from './CoursewareListContainer.vue';
-import CoursewareTabsContainer from './CoursewareTabsContainer.vue';
-import CoursewareRibbon from './CoursewareRibbon.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
 import CoursewareExport from '@/vue/mixins/courseware/export.js';
 import CoursewareOerMessage from '@/vue/mixins/courseware/oermessage.js';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
 import wizardMixin from '@/vue/mixins/courseware/wizard.js';
-import CoursewareDateInput from './CoursewareDateInput.vue';
-import { FocusTrap } from 'focus-trap-vue';
-import IsoDate from './IsoDate.vue';
-import StockImageSelector from '../stock-images/SelectorDialog.vue';
-import StudipDialog from '../StudipDialog.vue';
+import CoursewareDateInput from '../layouts/CoursewareDateInput.vue';
+import StockImageSelector from '../../stock-images/SelectorDialog.vue';
+import StudipDialog from '../../StudipDialog.vue';
 import draggable from 'vuedraggable';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'courseware-structural-element',
-    components: {
+    components: Object.assign(StructuralElementComponents, {
         CoursewareStructuralElementDialogAdd,
         CoursewareStructuralElementDialogCopy,
         CoursewareStructuralElementDialogImport,
@@ -688,22 +679,12 @@ export default {
         CoursewareStructuralElementDiscussion,
         CoursewareStructuralElementPermissions,
         CoursewareContentPermissions,
-        CoursewareRibbon,
-        CoursewareListContainer,
-        CoursewareAccordionContainer,
-        CoursewareTabsContainer,
-        CoursewareCompanionBox,
         CoursewareWelcomeScreen,
-        CoursewareEmptyElementBox,
-        CoursewareTabs,
-        CoursewareTab,
         CoursewareDateInput,
-        FocusTrap,
-        IsoDate,
         StockImageSelector,
         StudipDialog,
         draggable,
-    },
+    }),
     props: ['canVisit', 'orderedStructuralElements', 'structuralElement'],
 
     mixins: [CoursewareExport, CoursewareOerMessage, colorMixin, wizardMixin],
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementComments.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareStructuralElementComments.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue
index d1f48b5939b86879e4d8c6d53b08b1274161dcff..42c7f5f670770329aee14791a167250193413db5 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementComments.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue
@@ -19,7 +19,7 @@
 </template>
 
 <script>
-import CoursewareTalkBubble from './CoursewareTalkBubble.vue';
+import CoursewareTalkBubble from '../layouts/CoursewareTalkBubble.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementDialogAdd.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareStructuralElementDialogAdd.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue
index d1824956c8ac2bccfc998ebb718ba2658fb5c6b0..9ba6c775bab4b5b761106159956d8f38ad0f331a 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementDialogAdd.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue
@@ -146,9 +146,9 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import StudipSelect from './../StudipSelect.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import StudipSelect from '../../StudipSelect.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
 import wizardMixin from '@/vue/mixins/courseware/wizard.js';
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementDialogCopy.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareStructuralElementDialogCopy.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue
index 76d84c891db3a720b5a26bdd8048c642006cbdf5..82539ece70fe29c3d5afb0ecb7b1b9d2a98ded17 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementDialogCopy.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue
@@ -181,11 +181,11 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareStructuralElementSelector from './CoursewareStructuralElementSelector.vue';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
-import StudipSelect from './../StudipSelect.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import StudipSelect from '../../StudipSelect.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
 
 import { mapActions, mapGetters } from 'vuex'
 
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementDialogImport.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogImport.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareStructuralElementDialogImport.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogImport.vue
index 3c3974dbe5c9c09b19ee50af9b00788ae249bc57..ba940a6dbca069dc039900aa187df3f0d92c0abe 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementDialogImport.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogImport.vue
@@ -74,7 +74,7 @@
     </studip-dialog>
 </template>
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareImport from '@/vue/mixins/courseware/import.js';
 
 import { mapActions, mapGetters } from 'vuex'
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementDialogLink.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareStructuralElementDialogLink.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue
index 78c6725255fa4573827ee20827fe371bac33e3cd..1405e39c37329b4dfbf9e011665bca0674ea76d1 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementDialogLink.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue
@@ -57,10 +57,10 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareStructuralElementSelector from './CoursewareStructuralElementSelector.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
-import StudipProgressIndicator from '../StudipProgressIndicator.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
+import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex'
 
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementDiscussion.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDiscussion.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareStructuralElementDiscussion.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementDiscussion.vue
index fcd275c1b2f3a39c0045e53f95115ab08b8dee29..3428d83af748206eed955e81c1a7c4d2fdd26598 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementDiscussion.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDiscussion.vue
@@ -25,7 +25,7 @@
 </template>
 
 <script>
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
+import CoursewareCollapsibleBox from '../layouts/CoursewareCollapsibleBox.vue';
 import CoursewareStructuralElementComments from './CoursewareStructuralElementComments.vue';
 import CoursewareStructuralElementFeedback from './CoursewareStructuralElementFeedback.vue';
 import { mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementFeedback.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareStructuralElementFeedback.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue
index 3fa2c3c1160e16f7ae950a2d591313a13965f310..fd950bc16258046286f952e203985e15f8923a54 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementFeedback.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue
@@ -25,8 +25,8 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareTalkBubble from './CoursewareTalkBubble.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import CoursewareTalkBubble from '../layouts/CoursewareTalkBubble.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementPermissions.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareStructuralElementPermissions.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue
index 473b82f530ceb5a338602edc69a167899c7aaeb3..f09ed5496767a2e276fa1f7115743e48473c0399 100644
--- a/resources/vue/components/courseware/CoursewareStructuralElementPermissions.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue
@@ -163,7 +163,7 @@
     </div>
 </template>
 <script>
-import StudipPagination from './../StudipPagination.vue';
+import StudipPagination from '../../StudipPagination.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementSelector.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareStructuralElementSelector.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue
diff --git a/resources/vue/components/courseware/CoursewareStructuralElementSelectorItem.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareStructuralElementSelectorItem.vue
rename to resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue
diff --git a/resources/vue/components/courseware/CoursewareToolsBlockadder.vue b/resources/vue/components/courseware/structural-element/CoursewareToolsBlockadder.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareToolsBlockadder.vue
rename to resources/vue/components/courseware/structural-element/CoursewareToolsBlockadder.vue
index 36348a38f171fc1d76818df909234b81e5e1686c..86b42467fdf123520c2bf9dde4e0e5d437b7bc3b 100644
--- a/resources/vue/components/courseware/CoursewareToolsBlockadder.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareToolsBlockadder.vue
@@ -154,17 +154,16 @@
 </template>
 
 <script>
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import CoursewareTabs from '../layouts/CoursewareTabs.vue';
+import CoursewareTab from '../layouts/CoursewareTab.vue';
 import CoursewareBlockadderItem from './CoursewareBlockadderItem.vue';
 import CoursewareClipboardItem from './CoursewareClipboardItem.vue';
-import CoursewareContainerAdderItem from './CoursewareContainerAdderItem.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
+import CoursewareContainerAdderItem from '../containers/CoursewareContainerAdderItem.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import CoursewareCollapsibleBox from '../layouts/CoursewareCollapsibleBox.vue';
+import StudipDialog from '../../StudipDialog.vue';
 import { mapActions, mapGetters } from 'vuex';
 
-import StudipDialog from '../StudipDialog.vue';
-
 export default {
     name: 'cw-tools-blockadder',
     components: {
diff --git a/resources/vue/components/courseware/CoursewareToolsContents.vue b/resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareToolsContents.vue
rename to resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue
diff --git a/resources/vue/components/courseware/CoursewareTree.vue b/resources/vue/components/courseware/structural-element/CoursewareTree.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareTree.vue
rename to resources/vue/components/courseware/structural-element/CoursewareTree.vue
index 1832372be9eba7f7bd082ee3f581c9d3b2e787e2..4103c1bbe5c7f5c13b3b2ce26b5d363c116c2344 100644
--- a/resources/vue/components/courseware/CoursewareTree.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareTree.vue
@@ -28,7 +28,7 @@
 
 <script>
 import CoursewareTreeItem from './CoursewareTreeItem.vue';
-import StudipProgressIndicator from '../StudipProgressIndicator.vue';
+import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareTreeItem.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareTreeItem.vue
rename to resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue
diff --git a/resources/vue/components/courseware/CoursewareWelcomeScreen.vue b/resources/vue/components/courseware/structural-element/CoursewareWelcomeScreen.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareWelcomeScreen.vue
rename to resources/vue/components/courseware/structural-element/CoursewareWelcomeScreen.vue
diff --git a/resources/vue/components/courseware/PublicCoursewareStructuralElement.vue b/resources/vue/components/courseware/structural-element/PublicCoursewareStructuralElement.vue
similarity index 88%
rename from resources/vue/components/courseware/PublicCoursewareStructuralElement.vue
rename to resources/vue/components/courseware/structural-element/PublicCoursewareStructuralElement.vue
index f6956d3cead1a31057b13e363d5c00dd500948f8..565117198b9357b71945ef8f3f0e4db40a2b583c 100644
--- a/resources/vue/components/courseware/PublicCoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/structural-element/PublicCoursewareStructuralElement.vue
@@ -73,39 +73,19 @@
 </template>
 
 <script>
-import ContainerComponents from './container-components.js';
-import CoursewarePluginComponents from './plugin-components.js';
-import CoursewareAccordionContainer from './CoursewareAccordionContainer.vue';
-import CoursewareListContainer from './CoursewareListContainer.vue';
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
-import CoursewareEmptyElementBox from './CoursewareEmptyElementBox.vue';
-import CoursewareTabsContainer from './CoursewareTabsContainer.vue';
-import CoursewareRibbon from './CoursewareRibbon.vue';
-import CoursewareTabs from './CoursewareTabs.vue';
-import CoursewareTab from './CoursewareTab.vue';
+import ContainerComponents from '../containers/container-components.js';
+import StructuralElementComponents from './structural-element-components.js';
+import CoursewarePluginComponents from '../plugin-components.js';
+import CoursewareCompanionOverlay from '../layouts/CoursewareCompanionOverlay.vue';
 
-import IsoDate from './IsoDate.vue';
-import { FocusTrap } from 'focus-trap-vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
     name: 'public-courseware-structural-element',
 
-    components: {
-        ContainerComponents,
-        CoursewareRibbon,
-        CoursewareListContainer,
-        CoursewareAccordionContainer,
-        CoursewareTabsContainer,
-        CoursewareCompanionBox,
+    components: Object.assign(StructuralElementComponents, {
         CoursewareCompanionOverlay,
-        CoursewareEmptyElementBox,
-        CoursewareTabs,
-        CoursewareTab,
-        FocusTrap,
-        IsoDate,
-    },
+    }),
 
     props: ['orderedStructuralElements', 'structuralElement'],
 
diff --git a/resources/vue/components/courseware/structural-element/structural-element-components.js b/resources/vue/components/courseware/structural-element/structural-element-components.js
new file mode 100644
index 0000000000000000000000000000000000000000..fdba4b41e1d703876a1f9ebb877fcee55b9cc4d4
--- /dev/null
+++ b/resources/vue/components/courseware/structural-element/structural-element-components.js
@@ -0,0 +1,31 @@
+// contentbar
+import CoursewareRibbon from './CoursewareRibbon.vue';
+import CoursewareTabs from '../layouts/CoursewareTabs.vue';
+import CoursewareTab from '../layouts/CoursewareTab.vue';
+import { FocusTrap } from 'focus-trap-vue';
+//layout
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import CoursewareEmptyElementBox from './CoursewareEmptyElementBox.vue';
+import IsoDate from '../layouts/IsoDate.vue';
+// containers
+import CoursewareAccordionContainer from '../containers/CoursewareAccordionContainer.vue';
+import CoursewareListContainer from '../containers/CoursewareListContainer.vue';
+import CoursewareTabsContainer from '../containers/CoursewareTabsContainer.vue';
+
+const StructuralElementComponents = {
+    //contentbar
+    CoursewareRibbon,
+    CoursewareTabs,
+    CoursewareTab,
+    FocusTrap,
+    //layout
+    CoursewareCompanionBox,
+    CoursewareEmptyElementBox,
+    IsoDate,
+    // containers
+    CoursewareAccordionContainer,
+    CoursewareListContainer,
+    CoursewareTabsContainer
+}
+
+export default StructuralElementComponents;
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareProgressCircle.vue b/resources/vue/components/courseware/unit/CoursewareProgressCircle.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareProgressCircle.vue
rename to resources/vue/components/courseware/unit/CoursewareProgressCircle.vue
diff --git a/resources/vue/components/courseware/CoursewareSharedItems.vue b/resources/vue/components/courseware/unit/CoursewareSharedItems.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareSharedItems.vue
rename to resources/vue/components/courseware/unit/CoursewareSharedItems.vue
diff --git a/resources/vue/components/courseware/CoursewareShelfDialogAdd.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareShelfDialogAdd.vue
rename to resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue
index 39bc47a325b11086e0e292191c354f4c9183c486..65465527fcc87853f7e5138f80ac4adaac7902e5 100644
--- a/resources/vue/components/courseware/CoursewareShelfDialogAdd.vue
+++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue
@@ -132,11 +132,11 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
-import StockImageSelectableImageCard from '../stock-images/SelectableImageCard.vue';
-import StockImageSelector from '../stock-images/SelectorDialog.vue';
-import StudipSelect from './../StudipSelect.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
+import StockImageSelectableImageCard from '../../stock-images/SelectableImageCard.vue';
+import StockImageSelector from '../../stock-images/SelectorDialog.vue';
+import StudipSelect from '../../StudipSelect.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareShelfDialogCopy.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareShelfDialogCopy.vue
rename to resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue
index d9ab4ffc8d1daf4584f5b9b2b94249a2c4c910d2..d68ffa54f8c8b5c1c076db8b8cd8a64c078759a3 100644
--- a/resources/vue/components/courseware/CoursewareShelfDialogCopy.vue
+++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue
@@ -167,10 +167,10 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
-import StudipSelect from './../StudipSelect.vue';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import StudipSelect from '../../StudipSelect.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
 
 import { mapActions, mapGetters } from 'vuex'
 
diff --git a/resources/vue/components/courseware/CoursewareShelfDialogImport.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareShelfDialogImport.vue
rename to resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue
index cc8e1001f2848033a5295354ee96ab0a3c2dc9f4..8717aabf00de68735586926d19a3618321e9c813 100644
--- a/resources/vue/components/courseware/CoursewareShelfDialogImport.vue
+++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue
@@ -130,10 +130,10 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareImport from '@/vue/mixins/courseware/import.js';
 import colorMixin from '@/vue/mixins/courseware/colors.js';
-import StudipWizardDialog from './../StudipWizardDialog.vue';
+import StudipWizardDialog from '../../StudipWizardDialog.vue';
 
 import { mapActions, mapGetters } from 'vuex'
 import JSZip from 'jszip';
diff --git a/resources/vue/components/courseware/CoursewareUnitItem.vue b/resources/vue/components/courseware/unit/CoursewareUnitItem.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareUnitItem.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitItem.vue
index 91b94a2e6b1508d69d0973344f3d5011631cd95f..74366d33806d5b4881feda92ce98f56fdef171ab 100644
--- a/resources/vue/components/courseware/CoursewareUnitItem.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitItem.vue
@@ -61,7 +61,7 @@
 </template>
 
 <script>
-import CoursewareTile from './CoursewareTile.vue';
+import CoursewareTile from '../layouts/CoursewareTile.vue';
 import CoursewareUnitItemDialogExport from './CoursewareUnitItemDialogExport.vue';
 import CoursewareUnitItemDialogSettings from './CoursewareUnitItemDialogSettings.vue';
 import CoursewareUnitItemDialogLayout from './CoursewareUnitItemDialogLayout.vue';
diff --git a/resources/vue/components/courseware/CoursewareUnitItemDialogExport.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareUnitItemDialogExport.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue
index a9c43766d75b7ee39ad3661d39c547a9e1a03d61..08f0a21fbedd687da9fdf4a0f67fa4ad578f37c4 100644
--- a/resources/vue/components/courseware/CoursewareUnitItemDialogExport.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue
@@ -41,7 +41,7 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareExport from '@/vue/mixins/courseware/export.js';
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareUnitItemDialogLayout.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue
similarity index 99%
rename from resources/vue/components/courseware/CoursewareUnitItemDialogLayout.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue
index cfe9099500cf1e575e13eca7f38e2b397b50dcdc..f06f7fde0e601be77cbaecd38b76fedaa9ce75b7 100644
--- a/resources/vue/components/courseware/CoursewareUnitItemDialogLayout.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue
@@ -83,7 +83,7 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 
 import colorMixin from '@/vue/mixins/courseware/colors.js';
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareUnitItemDialogSettings.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareUnitItemDialogSettings.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue
index 8438df308b3d1c9cd09090b786feb377504bb11a..34718fd9c1310b0326fbf9412ef6d398a5310ff2 100644
--- a/resources/vue/components/courseware/CoursewareUnitItemDialogSettings.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue
@@ -177,8 +177,8 @@
 </template>
 
 <script>
-import CoursewareFileChooser from "./CoursewareFileChooser.vue";
-import StudipProgressIndicator from '../StudipProgressIndicator.vue';
+import CoursewareFileChooser from '../layouts/CoursewareFileChooser.vue';
+import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareUnitItems.vue b/resources/vue/components/courseware/unit/CoursewareUnitItems.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareUnitItems.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitItems.vue
index 8fd7c0f1798d162080eb225246a1ba3b15054a0e..9d07e26ff05a2993578542f62ab829319e066196 100644
--- a/resources/vue/components/courseware/CoursewareUnitItems.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitItems.vue
@@ -44,7 +44,7 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareUnitItem from './CoursewareUnitItem.vue';
 
 import { mapActions, mapGetters } from 'vuex';
diff --git a/resources/vue/components/courseware/CoursewareUnitProgress.vue b/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareUnitProgress.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitProgress.vue
index 6c7528ff2813601d1e066459fe73be0548980f90..7c9de011ea16100c81921a7bd3cbe32121ddb71d 100644
--- a/resources/vue/components/courseware/CoursewareUnitProgress.vue
+++ b/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue
@@ -52,10 +52,10 @@
 </template>
 
 <script>
-import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
 import CoursewareUnitProgressItem from './CoursewareUnitProgressItem.vue';
 import CoursewareProgressCircle from './CoursewareProgressCircle.vue';
-import StudipIcon from '../StudipIcon.vue';
+import StudipIcon from '../../StudipIcon.vue';
 
 import { mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareUnitProgressItem.vue b/resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareUnitProgressItem.vue
rename to resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue
diff --git a/resources/vue/components/courseware/CoursewareActionWidget.vue b/resources/vue/components/courseware/widgets/CoursewareActionWidget.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareActionWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareActionWidget.vue
index 08348b9f5a2251bc1ba7b3df0f35913bb890ce79..6543594a02ecfb906bac6c1529defce847645507 100644
--- a/resources/vue/components/courseware/CoursewareActionWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareActionWidget.vue
@@ -13,7 +13,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareActivitiesWidgetFilterType.vue b/resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterType.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareActivitiesWidgetFilterType.vue
rename to resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterType.vue
index 0c57271b6441d96d27d031c9471d600f8aa055b4..eb2c05f5184ff7645e41ab90d1d49826da1f09a6 100644
--- a/resources/vue/components/courseware/CoursewareActivitiesWidgetFilterType.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterType.vue
@@ -30,7 +30,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 
 import { mapActions } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareActivitiesWidgetFilterUnit.vue b/resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterUnit.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareActivitiesWidgetFilterUnit.vue
rename to resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterUnit.vue
index d0142ea0077ad3e331bf86363b8cf8c1ef1225b8..dc10e17a0726cb35b36543826293bb7696b5736e 100644
--- a/resources/vue/components/courseware/CoursewareActivitiesWidgetFilterUnit.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareActivitiesWidgetFilterUnit.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareAdminActionWidget.vue b/resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareAdminActionWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue
diff --git a/resources/vue/components/courseware/CoursewareAdminViewWidget.vue b/resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue
similarity index 100%
rename from resources/vue/components/courseware/CoursewareAdminViewWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue
diff --git a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterCreated.vue b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterCreated.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterCreated.vue
rename to resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterCreated.vue
index 96074cde9a9ff9da453fce432cc56048801f251a..5b0d5af88720da91bf17111f279a195b47588508 100644
--- a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterCreated.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterCreated.vue
@@ -21,7 +21,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterType.vue b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterType.vue
similarity index 96%
rename from resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterType.vue
rename to resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterType.vue
index 9aaf61748e169a77dc9af5cfc08494f64f63c42d..4d92294b77ada17b88a15f015c0b585afd1dfc84 100644
--- a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterType.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterType.vue
@@ -21,7 +21,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterUnit.vue b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterUnit.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterUnit.vue
rename to resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterUnit.vue
index 4d0afd15bf68608baaa2cd55554c600577f9dbdf..9e01f2edea701084b2ca0487d6a99d1d9e8cb56c 100644
--- a/resources/vue/components/courseware/CoursewareCommentsOverviewWidgetFilterUnit.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareCommentsOverviewWidgetFilterUnit.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareExportWidget.vue b/resources/vue/components/courseware/widgets/CoursewareExportWidget.vue
similarity index 98%
rename from resources/vue/components/courseware/CoursewareExportWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareExportWidget.vue
index a6473ca4687460cef282fee60b1f4f69dfe31aae..b31ee20b4a024f7e10e0357dac241cf5f9c6c46a 100644
--- a/resources/vue/components/courseware/CoursewareExportWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareExportWidget.vue
@@ -26,7 +26,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import CoursewareExport from '@/vue/mixins/courseware/export.js';
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareImportWidget.vue b/resources/vue/components/courseware/widgets/CoursewareImportWidget.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareImportWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareImportWidget.vue
index e57f325b69f5e6d45e99d7fb723537d588a36613..c0bfd5ba9e00719848aa012ba7d286a29a871e0a 100644
--- a/resources/vue/components/courseware/CoursewareImportWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareImportWidget.vue
@@ -23,7 +23,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareSearchWidget.vue b/resources/vue/components/courseware/widgets/CoursewareSearchWidget.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareSearchWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareSearchWidget.vue
index b8ebf0fde56cde3df0aedd845083d2c7ce7b6821..aed84b578f045ad11670a23cd2be92883f625f88 100644
--- a/resources/vue/components/courseware/CoursewareSearchWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareSearchWidget.vue
@@ -32,8 +32,8 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
-import StudipIcon from '../StudipIcon.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
+import StudipIcon from '../../StudipIcon.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 import axios from 'axios';
diff --git a/resources/vue/components/courseware/CoursewareShelfActionWidget.vue b/resources/vue/components/courseware/widgets/CoursewareShelfActionWidget.vue
similarity index 93%
rename from resources/vue/components/courseware/CoursewareShelfActionWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareShelfActionWidget.vue
index 27b4ab21fc2757a73b850e8d83f17b26f90ce560..c7232c38078f923fb29a2515b41bf058354c0ceb 100644
--- a/resources/vue/components/courseware/CoursewareShelfActionWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareShelfActionWidget.vue
@@ -13,7 +13,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions } from 'vuex';
 
 export default {
diff --git a/resources/vue/components/courseware/CoursewareShelfImportWidget.vue b/resources/vue/components/courseware/widgets/CoursewareShelfImportWidget.vue
similarity index 95%
rename from resources/vue/components/courseware/CoursewareShelfImportWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareShelfImportWidget.vue
index 2c946e2a0bb6b55e686e0a9c3f437c5b8ffbbda9..2270437a69f761a61ff1c82470bbfde31cd3b369 100644
--- a/resources/vue/components/courseware/CoursewareShelfImportWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareShelfImportWidget.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareTasksActionWidget.vue b/resources/vue/components/courseware/widgets/CoursewareTasksActionWidget.vue
similarity index 93%
rename from resources/vue/components/courseware/CoursewareTasksActionWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareTasksActionWidget.vue
index e428cbe6e888e4199b32c576c6ac2ead9ed9c821..c2f54e9171daca7b0658070ba4bf0d4e0435f1a7 100644
--- a/resources/vue/components/courseware/CoursewareTasksActionWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareTasksActionWidget.vue
@@ -13,7 +13,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 
 import { mapActions } from 'vuex';
 
diff --git a/resources/vue/components/courseware/CoursewareViewWidget.vue b/resources/vue/components/courseware/widgets/CoursewareViewWidget.vue
similarity index 97%
rename from resources/vue/components/courseware/CoursewareViewWidget.vue
rename to resources/vue/components/courseware/widgets/CoursewareViewWidget.vue
index f6ab44c21e5736cb41f65d1345f4321786008aa5..5202abd7638e18cd9660acea9762f2f42b88c877 100644
--- a/resources/vue/components/courseware/CoursewareViewWidget.vue
+++ b/resources/vue/components/courseware/widgets/CoursewareViewWidget.vue
@@ -29,7 +29,7 @@
 </template>
 
 <script>
-import SidebarWidget from '../SidebarWidget.vue';
+import SidebarWidget from '../../SidebarWidget.vue';
 import { mapActions, mapGetters } from 'vuex';
 
 export default {
diff --git a/resources/vue/courseware-index-app.js b/resources/vue/courseware-index-app.js
index 5e2ea1ff9a33dcaead0efe1c5f0033de2b915184..3309b55ce47f16e98983da45e904cab1d112523e 100644
--- a/resources/vue/courseware-index-app.js
+++ b/resources/vue/courseware-index-app.js
@@ -1,6 +1,6 @@
 import CoursewareModule from './store/courseware/courseware.module';
 import CoursewareStructureModule from './store/courseware/structure.module';
-import CoursewareStructuralElement from './components/courseware/CoursewareStructuralElement.vue';
+import CoursewareStructuralElement from './components/courseware/structural-element/CoursewareStructuralElement.vue';
 import IndexApp from './components/courseware/IndexApp.vue';
 import PluginManager from './components/courseware/plugin-manager.js';
 import Vue from 'vue';
diff --git a/resources/vue/courseware-public-app.js b/resources/vue/courseware-public-app.js
index ae706055b89790206ba67c052f7481e25bc71a4a..1d50b8ace89ccb393f50845904b645ff71b4c592 100644
--- a/resources/vue/courseware-public-app.js
+++ b/resources/vue/courseware-public-app.js
@@ -1,6 +1,6 @@
 import PublicApp from './components/courseware/PublicApp.vue';
 import CoursewarePublicModule from './store/courseware/courseware-public.module';
-import PublicCoursewareStructuralElement from './components/courseware/PublicCoursewareStructuralElement.vue';
+import PublicCoursewareStructuralElement from './components/courseware/structural-element/PublicCoursewareStructuralElement.vue';
 import CoursewarePublicStructureModule from './store/courseware/public-structure.module';
 import PluginManager from './components/courseware/plugin-manager.js';
 import VueRouter from 'vue-router';
diff --git a/resources/vue/components/courseware/block-mixin.js b/resources/vue/mixins/courseware/block.js
similarity index 95%
rename from resources/vue/components/courseware/block-mixin.js
rename to resources/vue/mixins/courseware/block.js
index 4e2dc77da591c643e323fdee40a143929094a08f..0a83906e742831004a01894866fe4a89c08de885 100644
--- a/resources/vue/components/courseware/block-mixin.js
+++ b/resources/vue/mixins/courseware/block.js
@@ -1,6 +1,6 @@
 import { mapActions, mapGetters } from 'vuex';
 
-export const blockMixin = {
+const blockMixin = {
     computed: {
         ...mapGetters({
             getUserProgress: 'courseware-user-progresses/related',
@@ -33,3 +33,5 @@ export const blockMixin = {
         },
     },
 };
+
+export default blockMixin;
\ No newline at end of file
diff --git a/resources/vue/mixins/courseware/content-icons.js b/resources/vue/mixins/courseware/content-icons.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f86edfaaca5e189fcec61268c80f9e27236cbe6
--- /dev/null
+++ b/resources/vue/mixins/courseware/content-icons.js
@@ -0,0 +1,122 @@
+const contentIconsMixin = {
+    computed: {
+        contentIcons() {
+            return [
+                'accept',
+                'add',
+                'add-circle',
+                'admin',
+                'aladdin',
+                'arr_1down',
+                'arr_1left',
+                'arr_1right',
+                'arr_1up',
+                'arr_2down',
+                'arr_2left',
+                'arr_2right',
+                'arr_2up',
+                'audio',
+                'audio3',
+                'billboard',
+                'block-canvas',
+                'block-comparison',
+                'block-eyecatcher',
+                'block-gallery',
+                'block-gallery2',
+                'block-imagemap',
+                'brainstorm',
+                'campusnavi',
+                'chat2',
+                'code',
+                'community2',
+                'computer',
+                'consultation',
+                'content',
+                'courseware',
+                'crown',
+                'date-single',
+                'decline',
+                'decline-circle',
+                'doctoral_cap',
+                'download',
+                'dropbox',
+                'edit',
+                'exclaim',
+                'exclaim-circle',
+                'export',
+                'favorite',
+                'filter',
+                'globe',
+                'graph',
+                'group2',
+                'group3',
+                'group4',
+                'home',
+                'home2',
+                'info',
+                'info-circle',
+                'install',
+                'institute',
+                'key',
+                'knife',
+                'learnmodule',
+                'lightbulb',
+                'lightbulb2',
+                'link2',
+                'link3',
+                'link-extern',
+                'link-intern',
+                'literature',
+                'lock-locked',
+                'lock-unlocked',
+                'mail2',
+                'medal',
+                'metro',
+                'microphone',
+                'module',
+                'network',
+                'network2',
+                'notification',
+                'notification2',
+                'opencast',
+                'outer-space',
+                'permalink',
+                'person',
+                'phone',
+                'picture',
+                'place',
+                'plugin',
+                'question',
+                'question-circle',
+                'ranking',
+                'remove',
+                'remove-circle',
+                'resources',
+                'roles',
+                'schedule2',
+                'search',
+                'settings',
+                'span-empty',
+                'span-1quarter',
+                'span-2quarter',
+                'span-3quarter',
+                'span-full',
+                'spiral',
+                'sport',
+                'staple',
+                'star',
+                'star-empty',
+                'star-halffull',
+                'test',
+                'tools',
+                'topic',
+                'ufo',
+                'video2',
+                'visibility-visible',
+                'wizard',
+            ];
+        },
+    },
+};
+
+export default contentIconsMixin;