Plugin Directory

Changeset 3446627


Ignore:
Timestamp:
01/25/2026 05:51:32 PM (2 months ago)
Author:
akritsingha
Message:

Update version to 2.2.5

Location:
modular-blocks-core/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • modular-blocks-core/trunk/assets/css/admin.css

    r3430633 r3446627  
    22
    33:root {
    4     --mbcore-bg: #fdfdfd;
    5     /* Pure Paper White */
    6     --mbcore-card-bg: rgba(255, 255, 255, 0.85);
    7     /* Glass Base */
    8     --mbcore-primary: #2563eb;
    9     /* Royal Blue */
    10     --mbcore-primary-soft: #eff6ff;
    11     --mbcore-accent: #8b5cf6;
    12     /* Regal Violet */
    13     --mbcore-border: #e2e8f0;
    14     /* Soft Silver */
    15     --mbcore-text-head: #1e293b;
    16     /* Slate 800 */
    17     --mbcore-text-body: #475569;
    18     /* Slate 600 */
    19 
    20     --mbcore-radius-lg: 16px;
    21     --mbcore-radius-md: 10px;
    22     --mbcore-radius-sm: 6px;
    23 
    24     --mbcore-shadow-glass:
    25         0 4px 6px -1px rgba(0, 0, 0, 0.02),
    26         0 2px 4px -1px rgba(0, 0, 0, 0.02),
    27         inset 0 0 0 1px rgba(255, 255, 255, 0.9);
    28 
    29     --mbcore-shadow-hover:
    30         0 20px 25px -5px rgba(0, 0, 0, 0.05),
    31         0 10px 10px -5px rgba(0, 0, 0, 0.02);
    32 
    33     --mbcore-font-head: 'Outfit', 'Inter', sans-serif;
    34     /* Modern Aesthetic */
     4    --mbcore-bg: #fdfdfd;
     5    /* Pure Paper White */
     6    --mbcore-card-bg: rgba(255, 255, 255, 0.85);
     7    /* Glass Base */
     8    --mbcore-primary: #2563eb;
     9    /* Royal Blue */
     10    --mbcore-primary-soft: #eff6ff;
     11    --mbcore-accent: #8b5cf6;
     12    /* Regal Violet */
     13    --mbcore-border: #e2e8f0;
     14    /* Soft Silver */
     15    --mbcore-text-head: #1e293b;
     16    /* Slate 800 */
     17    --mbcore-text-body: #475569;
     18    /* Slate 600 */
     19
     20    --mbcore-radius-lg: 16px;
     21    --mbcore-radius-md: 10px;
     22    --mbcore-radius-sm: 6px;
     23
     24    --mbcore-shadow-glass:
     25        0 4px 6px -1px rgba(0, 0, 0, 0.02),
     26        0 2px 4px -1px rgba(0, 0, 0, 0.02),
     27        inset 0 0 0 1px rgba(255, 255, 255, 0.9);
     28
     29    --mbcore-shadow-hover:
     30        0 20px 25px -5px rgba(0, 0, 0, 0.05),
     31        0 10px 10px -5px rgba(0, 0, 0, 0.02);
     32
     33    --mbcore-font-head: 'Outfit', 'Inter', sans-serif;
     34    /* Modern Aesthetic */
    3535}
    3636
    3737/* Glassmorphism Sections */
    3838.mbcore-editor-section {
    39     background: var(--mbcore-card-bg);
    40     border: 1px solid rgba(255, 255, 255, 0.6);
    41     border-radius: var(--mbcore-radius-lg);
    42     box-shadow: var(--mbcore-shadow-glass);
    43     margin-bottom: 24px;
    44     overflow: hidden;
    45     backdrop-filter: blur(12px);
    46     transition: transform 0.3s ease, box-shadow 0.3s ease;
     39    background: var(--mbcore-card-bg);
     40    border: 1px solid rgba(255, 255, 255, 0.6);
     41    border-radius: var(--mbcore-radius-lg);
     42    box-shadow: var(--mbcore-shadow-glass);
     43    margin-bottom: 24px;
     44    overflow: hidden;
     45    backdrop-filter: blur(12px);
     46    transition: transform 0.3s ease, box-shadow 0.3s ease;
    4747}
    4848
    4949.mbcore-editor-section:hover {
    50     box-shadow: var(--mbcore-shadow-hover);
    51     transform: translateY(-2px);
     50    box-shadow: var(--mbcore-shadow-hover);
     51    transform: translateY(-2px);
    5252}
    5353
    5454.mbcore-editor-section h3 {
    55     margin: 0;
    56     padding: 18px 24px;
    57     background: linear-gradient(to bottom, #ffffff, #fafafa);
    58     border-bottom: 1px solid var(--mbcore-border);
    59     font-family: var(--mbcore-font-head);
    60     font-size: 14px;
    61     font-weight: 700;
    62     letter-spacing: 0.5px;
    63     color: var(--mbcore-text-head);
    64     text-transform: uppercase;
    65     display: flex;
    66     align-items: center;
     55    margin: 0;
     56    padding: 18px 24px;
     57    background: linear-gradient(to bottom, #ffffff, #fafafa);
     58    border-bottom: 1px solid var(--mbcore-border);
     59    font-family: var(--mbcore-font-head);
     60    font-size: 14px;
     61    font-weight: 700;
     62    letter-spacing: 0.5px;
     63    color: var(--mbcore-text-head);
     64    text-transform: uppercase;
     65    display: flex;
     66    align-items: center;
    6767}
    6868
    6969.mbcore-editor-section h3::before {
    70     content: '';
    71     display: inline-block;
    72     width: 6px;
    73     height: 6px;
    74     background: var(--mbcore-primary);
    75     border-radius: 50%;
    76     margin-right: 12px;
    77     box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
     70    content: '';
     71    display: inline-block;
     72    width: 6px;
     73    height: 6px;
     74    background: var(--mbcore-primary);
     75    border-radius: 50%;
     76    margin-right: 12px;
     77    box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
    7878}
    7979
    8080/* Compact Forms */
    8181.mbcore-form-row {
    82     padding: 16px 24px;
    83     /* Tighter padding */
    84     border-bottom: 1px solid #f1f5f9;
     82    padding: 16px 24px;
     83    /* Tighter padding */
     84    border-bottom: 1px solid #f1f5f9;
    8585}
    8686
    8787.mbcore-form-row:last-child {
    88     border-bottom: none;
     88    border-bottom: none;
    8989}
    9090
    9191.mbcore-form-row label {
    92     display: block;
    93     color: var(--mbcore-text-body);
    94     font-size: 12px;
    95     font-weight: 600;
    96     margin-bottom: 6px;
    97     letter-spacing: 0.02em;
     92    display: block;
     93    color: var(--mbcore-text-body);
     94    font-size: 12px;
     95    font-weight: 600;
     96    margin-bottom: 6px;
     97    letter-spacing: 0.02em;
    9898}
    9999
    100100.mbcore-form-row input[type="text"],
    101101.mbcore-form-row select {
    102     width: 100%;
    103     background: #ffffff;
    104     border: 1px solid var(--mbcore-border);
    105     border-radius: var(--mbcore-radius-sm);
    106     padding: 8px 12px;
    107     font-size: 13px;
    108     color: #334155;
    109     transition: all 0.2s ease;
    110     box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
     102    width: 100%;
     103    background: #ffffff;
     104    border: 1px solid var(--mbcore-border);
     105    border-radius: var(--mbcore-radius-sm);
     106    padding: 8px 12px;
     107    font-size: 13px;
     108    color: #334155;
     109    transition: all 0.2s ease;
     110    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
    111111}
    112112
    113113.mbcore-form-row input[type="text"]:focus,
    114114.mbcore-form-row select:focus {
    115     border-color: var(--mbcore-primary);
    116     box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
    117     outline: none;
     115    border-color: var(--mbcore-primary);
     116    box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
     117    outline: none;
    118118}
    119119
    120120/* Intelligent Code Editors */
    121121.mbcore-editor-section textarea.mbcore-code-editor {
    122     font-family: 'Fira Code', 'Menlo', monospace;
    123     font-size: 13px;
    124     line-height: 1.6;
    125     padding: 20px 24px;
    126     border: none;
    127     width: 100%;
    128     min-height: 400px;
    129     background: #fafafa;
    130     color: #24292e;
     122    font-family: 'Fira Code', 'Menlo', monospace;
     123    font-size: 13px;
     124    line-height: 1.6;
     125    padding: 20px 24px;
     126    border: none;
     127    width: 100%;
     128    min-height: 400px;
     129    background: #fafafa;
     130    color: #24292e;
    131131}
    132132
    133133/* CodeMirror Resizing */
    134134.mbcore-tab-content .CodeMirror {
    135     height: 500px;
    136     min-height: 200px;
    137     border-radius: var(--mbcore-radius-md);
    138     font-family: 'Fira Code', 'Menlo', monospace;
    139     font-size: 14px;
    140     resize: vertical;
    141     overflow: hidden !important;
     135    height: 500px;
     136    min-height: 200px;
     137    border-radius: var(--mbcore-radius-md);
     138    font-family: 'Fira Code', 'Menlo', monospace;
     139    font-size: 14px;
     140    resize: vertical;
     141    overflow: hidden !important;
    142142}
    143143
    144144.mbcore-tab-content .CodeMirror-scroll {
    145     min-height: inherit;
     145    min-height: inherit;
    146146}
    147147
    148148/* Resize Handle Indicator */
    149149.mbcore-tab-content .CodeMirror::after {
    150     content: "";
    151     position: absolute;
    152     bottom: 0;
    153     right: 0;
    154     width: 15px;
    155     height: 15px;
    156     background: linear-gradient(135deg, transparent 50%, #ccd0d4 50%, #ccd0d4 60%, transparent 60%, transparent 70%, #ccd0d4 70%);
    157     cursor: nwse-resize;
    158     pointer-events: none;
    159     z-index: 20;
    160     opacity: 0.6;
     150    content: "";
     151    position: absolute;
     152    bottom: 0;
     153    right: 0;
     154    width: 15px;
     155    height: 15px;
     156    background: linear-gradient(135deg, transparent 50%, #ccd0d4 50%, #ccd0d4 60%, transparent 60%, transparent 70%, #ccd0d4 70%);
     157    cursor: nwse-resize;
     158    pointer-events: none;
     159    z-index: 20;
     160    opacity: 0.6;
    161161}
    162162
    163163.mbcore-tab-content .CodeMirror:hover::after {
    164     opacity: 1;
     164    opacity: 1;
    165165}
    166166
    167167/* Differentiate Editors visually via border strip */
    168168.mbcore-tab-content#mbcore-code-css .CodeMirror {
    169     border-left: 4px solid #2965f1;
    170     background: linear-gradient(to right, #f8faff, #ffffff);
     169    border-left: 4px solid #2965f1;
     170    background: linear-gradient(to right, #f8faff, #ffffff);
    171171}
    172172
    173173.mbcore-tab-content#mbcore-code-js .CodeMirror {
    174     border-left: 4px solid #f7df1e;
    175     background: linear-gradient(to right, #fffff0, #ffffff);
     174    border-left: 4px solid #f7df1e;
     175    background: linear-gradient(to right, #fffff0, #ffffff);
    176176}
    177177
    178178.mbcore-tab-content#mbcore-code-php .CodeMirror {
    179     border-left: 4px solid #8993be;
    180     background: linear-gradient(to right, #f9f9ff, #ffffff);
     179    border-left: 4px solid #8993be;
     180    background: linear-gradient(to right, #f9f9ff, #ffffff);
    181181}
    182182
    183183.CodeMirror-focused {
    184     box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
    185     border-color: var(--mbcore-primary);
     184    box-shadow: 0 0 0 3px var(--mbcore-primary-soft);
     185    border-color: var(--mbcore-primary);
    186186}
    187187
    188188/* Full-width field */
    189189.field.full-width {
    190     flex: 1 1 100%;
     190    flex: 1 1 100%;
    191191}
    192192
    193193.field.full-width .description {
    194     font-size: 12px;
    195     color: #666;
    196     font-style: italic;
    197     margin-top: 4px;
     194    font-size: 12px;
     195    color: #666;
     196    font-style: italic;
     197    margin-top: 4px;
    198198}
    199199
    200200/* Control Item - Lazy Blocks Style */
    201201.mbcore-controls-wrapper {
    202     background: transparent;
    203     padding: 0;
    204     display: flex;
    205     flex-direction: column;
    206     gap: 12px;
     202    background: transparent;
     203    padding: 0;
     204    display: flex;
     205    flex-direction: column;
     206    gap: 12px;
    207207}
    208208
    209209.mbcore-control-item {
    210     background: #ffffff;
    211     border: 1px solid #c3c4c7;
    212     border-radius: 4px;
    213     padding: 0;
    214     position: relative;
    215     box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
     210    background: #ffffff;
     211    border: 1px solid #c3c4c7;
     212    border-radius: 4px;
     213    padding: 0;
     214    position: relative;
     215    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
    216216}
    217217
    218218.mbcore-control-item.open {
    219     border-color: #8c8f94;
    220     box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
     219    border-color: #8c8f94;
     220    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
    221221}
    222222
    223223.mbcore-control-header {
    224     display: flex;
    225     align-items: center;
    226     padding: 10px 15px;
    227     background: #f6f7f7;
    228     cursor: pointer;
    229     border-bottom: 1px solid transparent;
    230     user-select: none;
     224    display: flex;
     225    align-items: center;
     226    padding: 10px 15px;
     227    background: #f6f7f7;
     228    cursor: pointer;
     229    border-bottom: 1px solid transparent;
     230    user-select: none;
    231231}
    232232
    233233.mbcore-control-item.open .mbcore-control-header {
    234     background: #f0f0f1;
    235     border-bottom-color: #dcdcde;
     234    background: #f0f0f1;
     235    border-bottom-color: #dcdcde;
    236236}
    237237
    238238.mbcore-control-handle {
    239     color: #a7aaad;
    240     margin-right: 10px;
    241     cursor: move;
     239    color: #a7aaad;
     240    margin-right: 10px;
     241    cursor: move;
    242242}
    243243
    244244.mbcore-control-handle:hover {
    245     color: #1d2327;
     245    color: #1d2327;
    246246}
    247247
    248248.mbcore-control-title {
    249     flex-grow: 1;
    250     font-weight: 600;
    251     font-size: 14px;
    252     color: #1d2327;
     249    flex-grow: 1;
     250    font-weight: 600;
     251    font-size: 14px;
     252    color: #1d2327;
    253253}
    254254
    255255.mbcore-control-type-badge {
    256     background: #dcdcde;
    257     color: #50575e;
    258     font-size: 11px;
    259     padding: 2px 6px;
    260     border-radius: 3px;
    261     margin-right: 10px;
    262     text-transform: uppercase;
     256    background: #dcdcde;
     257    color: #50575e;
     258    font-size: 11px;
     259    padding: 2px 6px;
     260    border-radius: 3px;
     261    margin-right: 10px;
     262    text-transform: uppercase;
    263263}
    264264
    265265.mbcore-control-toggle-icon {
    266     color: #a7aaad;
     266    color: #a7aaad;
    267267}
    268268
    269269.mbcore-control-item.open .mbcore-control-toggle-icon {
    270     transform: rotate(180deg);
     270    transform: rotate(180deg);
    271271}
    272272
    273273.mbcore-control-body {
    274     display: none;
    275     padding: 15px;
    276     background: #fff;
    277     border-bottom-left-radius: 4px;
    278     border-bottom-right-radius: 4px;
     274    display: none;
     275    padding: 15px;
     276    background: #fff;
     277    border-bottom-left-radius: 4px;
     278    border-bottom-right-radius: 4px;
    279279}
    280280
    281281.mbcore-control-item.open .mbcore-control-body {
    282     display: block;
     282    display: block;
    283283}
    284284
    285285.mbcore-control-row {
    286     display: flex;
    287     gap: 20px;
    288     margin-bottom: 15px;
     286    display: flex;
     287    gap: 20px;
     288    margin-bottom: 15px;
    289289}
    290290
    291291.mbcore-control-row .field {
    292     flex: 1;
     292    flex: 1;
    293293}
    294294
    295295.mbcore-control-row:last-child {
    296     margin-bottom: 0;
     296    margin-bottom: 0;
    297297}
    298298
    299299.mbcore-control-actions {
    300     margin-top: 15px;
    301     padding-top: 15px;
    302     border-top: 1px solid #f0f0f1;
    303     display: flex;
    304     justify-content: flex-end;
     300    margin-top: 15px;
     301    padding-top: 15px;
     302    border-top: 1px solid #f0f0f1;
     303    display: flex;
     304    justify-content: flex-end;
    305305}
    306306
    307307.mbcore-control-item label {
    308     display: block;
    309     margin-bottom: 5px;
    310     font-weight: 600;
    311     font-size: 13px;
    312     color: #1d2327;
     308    display: block;
     309    margin-bottom: 5px;
     310    font-weight: 600;
     311    font-size: 13px;
     312    color: #1d2327;
    313313}
    314314
     
    316316.mbcore-control-item select,
    317317.mbcore-control-item textarea {
    318     width: 100%;
    319     border: 1px solid #8c8f94;
    320     border-radius: 4px;
    321     padding: 6px 10px;
    322     font-size: 14px;
    323     color: #2c3338;
     318    width: 100%;
     319    border: 1px solid #8c8f94;
     320    border-radius: 4px;
     321    padding: 6px 10px;
     322    font-size: 14px;
     323    color: #2c3338;
    324324}
    325325
    326326.mbcore-control-item .btn-remove {
    327     color: #b32d2e;
    328     text-decoration: none;
    329     font-size: 13px;
    330     background: transparent;
    331     border: none;
    332     padding: 0;
    333     cursor: pointer;
     327    color: #b32d2e;
     328    text-decoration: none;
     329    font-size: 13px;
     330    background: transparent;
     331    border: none;
     332    padding: 0;
     333    cursor: pointer;
    334334}
    335335
    336336.mbcore-control-item .btn-remove:hover {
    337     color: #d63638;
    338     text-decoration: underline;
     337    color: #d63638;
     338    text-decoration: underline;
    339339}
    340340
    341341/* Hide legacy strip */
    342342.mbcore-control-item::before {
    343     display: none;
     343    display: none;
    344344}
    345345
    346346.mbcore-control-card-body {
    347     margin-left: 0;
    348     padding: 0;
     347    margin-left: 0;
     348    padding: 0;
    349349}
    350350
    351351/* Import Page */
    352352#mbcore-import-page {
    353     background: #fff;
    354     border: 1px solid var(--mbcore-border);
    355     border-radius: var(--mbcore-radius-lg);
    356     padding: 40px;
    357     margin-top: 30px;
    358     box-shadow: var(--mbcore-shadow-glass);
     353    background: #fff;
     354    border: 1px solid var(--mbcore-border);
     355    border-radius: var(--mbcore-radius-lg);
     356    padding: 40px;
     357    margin-top: 30px;
     358    box-shadow: var(--mbcore-shadow-glass);
    359359}
    360360
    361361#mbcore-import-page h1 {
    362     font-family: var(--mbcore-font-head);
    363     color: var(--mbcore-text-head);
    364     font-weight: 800;
    365     letter-spacing: -0.5px;
     362    font-family: var(--mbcore-font-head);
     363    color: var(--mbcore-text-head);
     364    font-weight: 800;
     365    letter-spacing: -0.5px;
    366366}
    367367
    368368/* Repeater Sub Controls */
    369369.mbcore-sub-controls-wrapper {
    370     background: #f9f9f9;
    371     padding: 15px;
    372     border: 1px dashed #ccc;
    373     border-radius: 4px;
     370    background: #f9f9f9;
     371    padding: 15px;
     372    border: 1px dashed #ccc;
     373    border-radius: 4px;
    374374}
    375375
    376376.mbcore-sub-controls-list {
    377     margin-bottom: 10px;
     377    margin-bottom: 10px;
    378378}
    379379
    380380.mbcore-sub-control-item {
    381     background: #fff;
    382     border: 1px solid #ddd;
    383     padding: 8px;
    384     margin-bottom: 5px;
    385     border-radius: 4px;
     381    background: #fff;
     382    border: 1px solid #ddd;
     383    padding: 8px;
     384    margin-bottom: 5px;
     385    border-radius: 4px;
    386386}
    387387
    388388.mbcore-sub-control-row {
    389     display: flex;
    390     gap: 10px;
    391     align-items: center;
     389    display: flex;
     390    gap: 10px;
     391    align-items: center;
    392392}
    393393
    394394.mbcore-sub-control-handle {
    395     cursor: move;
    396     color: #a7aaad;
    397     flex: 0 0 20px;
     395    cursor: move;
     396    color: #a7aaad;
     397    flex: 0 0 20px;
    398398}
    399399
    400400.mbcore-sub-control-handle:hover {
    401     color: #1d2327;
     401    color: #1d2327;
    402402}
    403403
    404404.mbcore-sub-control-row input,
    405405.mbcore-sub-control-row select {
    406     flex: 1;
    407     font-size: 12px !important;
    408     padding: 4px 8px !important;
     406    flex: 1;
     407    font-size: 12px !important;
     408    padding: 4px 8px !important;
    409409}
    410410
    411411.mbcore-sub-control-row .btn-remove-sub {
    412     flex: 0 0 30px;
    413     height: 30px;
    414     padding: 0;
    415     line-height: 28px;
    416     text-align: center;
     412    flex: 0 0 30px;
     413    height: 30px;
     414    padding: 0;
     415    line-height: 28px;
     416    text-align: center;
    417417}
    418418
    419419/* Code Editor Tabs */
    420420.mbcore-code-tabs {
    421     display: flex;
    422     background: #f0f0f1;
    423     border: 1px solid #dcdcde;
    424     border-bottom: none;
    425     border-top-left-radius: 4px;
    426     border-top-right-radius: 4px;
     421    display: flex;
     422    background: #f0f0f1;
     423    border: 1px solid #dcdcde;
     424    border-bottom: none;
     425    border-top-left-radius: 4px;
     426    border-top-right-radius: 4px;
    427427}
    428428
    429429.mbcore-tab-link {
    430     padding: 10px 20px;
    431     border: none;
    432     background: transparent;
    433     cursor: pointer;
    434     font-weight: 600;
    435     color: #50575e;
    436     border-right: 1px solid #dcdcde;
    437     transition: all 0.2s ease;
     430    padding: 10px 20px;
     431    border: none;
     432    background: transparent;
     433    cursor: pointer;
     434    font-weight: 600;
     435    color: #50575e;
     436    border-right: 1px solid #dcdcde;
     437    transition: all 0.2s ease;
    438438}
    439439
    440440.mbcore-tab-link:hover {
    441     background: #fff;
    442     color: var(--mbcore-primary);
     441    background: #fff;
     442    color: var(--mbcore-primary);
    443443}
    444444
    445445.mbcore-tab-link.active {
    446     background: #fff;
    447     color: var(--mbcore-primary);
    448     border-bottom: 2px solid var(--mbcore-primary);
     446    background: #fff;
     447    color: var(--mbcore-primary);
     448    border-bottom: 2px solid var(--mbcore-primary);
    449449}
    450450
    451451.mbcore-tab-content {
    452     display: none;
    453     border: 1px solid #dcdcde;
    454     padding: 15px;
    455     background: #fff;
    456     border-bottom-left-radius: 4px;
    457     border-bottom-right-radius: 4px;
     452    display: none;
     453    border: 1px solid #dcdcde;
     454    padding: 15px;
     455    background: #fff;
     456    border-bottom-left-radius: 4px;
     457    border-bottom-right-radius: 4px;
    458458}
    459459
    460460.mbcore-tab-content.active {
    461     display: block;
    462 }
     461    display: block;
     462}
  • modular-blocks-core/trunk/assets/css/editor.css

    r3430633 r3446627  
    55
    66/* ============================================
    7    BLOCK WRAPPER ENHANCEMENTS
    8    ============================================ */
     7    BLOCK WRAPPER ENHANCEMENTS
     8    ============================================ */
    99
    1010/* Main block container - Two column layout */
    1111.wp-block[data-type^="modular-blocks/"] {
    12     max-width: 100% !important;
     12    max-width: 100% !important;
    1313}
    1414
    1515/* Main content controls wrapper - Two column layout (default) */
    1616.mbcore-content-controls {
    17     display: grid;
    18     grid-template-columns: 400px 1fr;
    19     gap: 24px;
    20     background: transparent;
    21     border: none;
    22     padding: 0;
    23     margin: 60px 0 20px 0;
    24     position: relative;
     17    display: grid;
     18    grid-template-columns: 400px 1fr;
     19    gap: 24px;
     20    background: transparent;
     21    border: none;
     22    padding: 0;
     23    margin: 60px 0 20px 0;
     24    position: relative;
    2525}
    2626
    2727/* Layout Toggle Buttons */
    2828.mbcore-layout-toggle {
    29     position: absolute;
    30     top: -50px;
    31     right: 0;
    32     display: flex;
    33     gap: 8px;
    34     background: #ffffff;
    35     border: 1px solid #e0e0e0;
    36     border-radius: 6px;
    37     padding: 4px;
    38     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
     29    position: absolute;
     30    top: -50px;
     31    right: 0;
     32    display: flex;
     33    gap: 8px;
     34    background: #ffffff;
     35    border: 1px solid #e0e0e0;
     36    border-radius: 6px;
     37    padding: 4px;
     38    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
    3939}
    4040
    4141.mbcore-layout-toggle button {
    42     padding: 6px 12px;
    43     border: none;
    44     background: transparent;
    45     border-radius: 4px;
    46     cursor: pointer;
    47     font-size: 12px;
    48     font-weight: 600;
    49     color: #757575;
    50     transition: all 0.2s ease;
    51     display: flex;
    52     align-items: center;
    53     gap: 6px;
     42    padding: 6px 12px;
     43    border: none;
     44    background: transparent;
     45    border-radius: 4px;
     46    cursor: pointer;
     47    font-size: 12px;
     48    font-weight: 600;
     49    color: #757575;
     50    transition: all 0.2s ease;
     51    display: flex;
     52    align-items: center;
     53    gap: 6px;
    5454}
    5555
    5656.mbcore-layout-toggle button:hover {
    57     background: #f0f0f1;
    58     color: #1e1e1e;
     57    background: #f0f0f1;
     58    color: #1e1e1e;
    5959}
    6060
    6161.mbcore-layout-toggle button.active {
    62     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    63     color: #ffffff;
    64     box-shadow: 0 2px 8px rgba(91, 108, 242, 0.3);
     62    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     63    color: #ffffff;
     64    box-shadow: 0 2px 8px rgba(91, 108, 242, 0.3);
    6565}
    6666
    6767.mbcore-layout-toggle button::before {
    68     font-size: 14px;
     68    font-size: 14px;
    6969}
    7070
    7171.mbcore-layout-toggle button[data-layout="side-by-side"]::before {
    72     content: "⚏";
     72    content: "⚏";
    7373}
    7474
    7575.mbcore-layout-toggle button[data-layout="stacked"]::before {
    76     content: "☰";
     76    content: "☰";
    7777}
    7878
    7979/* Stacked Layout Mode */
    8080.mbcore-content-controls.layout-stacked {
    81     grid-template-columns: 1fr;
    82     max-width: 800px;
    83     margin-left: auto;
    84     margin-right: auto;
     81    grid-template-columns: 1fr;
     82    max-width: 800px;
     83    margin-left: auto;
     84    margin-right: auto;
    8585}
    8686
    8787.mbcore-content-controls.layout-stacked .mbcore-controls-section {
    88     position: relative;
    89     top: 0;
    90     max-height: none;
     88    position: relative;
     89    top: 0;
     90    max-height: none;
    9191}
    9292
    9393.mbcore-content-controls.layout-stacked .mbcore-preview-wrapper {
    94     min-height: 500px;
     94    min-height: 500px;
    9595}
    9696
    9797/* Controls section - Left column */
    9898.mbcore-controls-section {
    99     background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
    100     border: 1px solid #e0e0e0;
    101     border-radius: 16px;
    102     padding: 28px;
    103     box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
    104     transition: all 0.3s ease;
    105     position: sticky;
    106     top: 80px;
    107     max-height: calc(100vh - 120px);
    108     overflow-y: auto;
    109     overflow-x: hidden;
     99    background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
     100    border: 1px solid #e0e0e0;
     101    border-radius: 16px;
     102    padding: 28px;
     103    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
     104    transition: all 0.3s ease;
     105    position: sticky;
     106    top: 80px;
     107    max-height: calc(100vh - 120px);
     108    overflow-y: auto;
     109    overflow-x: hidden;
    110110}
    111111
    112112.mbcore-controls-section:hover {
    113     border-color: #5b6cf2;
    114     box-shadow: 0 6px 20px rgba(91, 108, 242, 0.12);
    115     transform: translateY(-2px);
     113    border-color: #5b6cf2;
     114    box-shadow: 0 6px 20px rgba(91, 108, 242, 0.12);
     115    transform: translateY(-2px);
    116116}
    117117
    118118/* Custom scrollbar for controls section */
    119119.mbcore-controls-section::-webkit-scrollbar {
    120     width: 8px;
     120    width: 8px;
    121121}
    122122
    123123.mbcore-controls-section::-webkit-scrollbar-track {
    124     background: #f0f0f1;
    125     border-radius: 4px;
     124    background: #f0f0f1;
     125    border-radius: 4px;
    126126}
    127127
    128128.mbcore-controls-section::-webkit-scrollbar-thumb {
    129     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    130     border-radius: 4px;
     129    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     130    border-radius: 4px;
    131131}
    132132
    133133.mbcore-controls-section::-webkit-scrollbar-thumb:hover {
    134     background: linear-gradient(135deg, #4f5bd5 0%, #3d4ab8 100%);
     134    background: linear-gradient(135deg, #4f5bd5 0%, #3d4ab8 100%);
    135135}
    136136
    137137/* Controls header with tabs */
    138138.mbcore-controls-header {
    139     margin-bottom: 0;
    140     padding: 0;
    141     border-bottom: none;
    142     position: relative;
     139    margin-bottom: 0;
     140    padding: 0;
     141    border-bottom: none;
     142    position: relative;
    143143}
    144144
     
    146146.mbcore-controls-header::before,
    147147.mbcore-controls-header::after {
    148     content: '';
    149     position: absolute;
    150     top: 0;
    151     bottom: 0;
    152     width: 60px;
    153     pointer-events: none;
    154     z-index: 1;
    155     transition: opacity 0.3s ease;
     148    content: '';
     149    position: absolute;
     150    top: 0;
     151    bottom: 0;
     152    width: 60px;
     153    pointer-events: none;
     154    z-index: 1;
     155    transition: opacity 0.3s ease;
    156156}
    157157
    158158.mbcore-controls-header::before {
    159     left: 0;
    160     background: linear-gradient(to right, rgba(248, 249, 250, 1) 0%, rgba(248, 249, 250, 0) 100%);
    161     opacity: 0;
     159    left: 0;
     160    background: linear-gradient(to right, rgba(248, 249, 250, 1) 0%, rgba(248, 249, 250, 0) 100%);
     161    opacity: 0;
    162162}
    163163
    164164.mbcore-controls-header::after {
    165     right: 0;
    166     background: linear-gradient(to left, rgba(248, 249, 250, 1) 0%, rgba(248, 249, 250, 0) 100%);
    167     opacity: 1;
     165    right: 0;
     166    background: linear-gradient(to left, rgba(248, 249, 250, 1) 0%, rgba(248, 249, 250, 0) 100%);
     167    opacity: 1;
    168168}
    169169
    170170.mbcore-controls-header.has-scroll-left::before {
    171     opacity: 1;
     171    opacity: 1;
    172172}
    173173
    174174.mbcore-controls-header.at-scroll-end::after {
    175     opacity: 0;
     175    opacity: 0;
    176176}
    177177
    178178/* Tabs navigation */
    179179.mbcore-controls-tabs {
    180     display: flex;
    181     gap: 8px;
    182     margin-bottom: 20px;
    183     border-bottom: 2px solid #f0f0f1;
    184     padding: 0 20px 16px 20px;
    185     overflow-x: auto;
    186     overflow-y: hidden;
    187     flex-wrap: nowrap;
    188     scrollbar-width: thin;
    189     scrollbar-color: #5b6cf2 #f0f0f1;
    190     position: relative;
     180    display: flex;
     181    gap: 8px;
     182    margin-bottom: 20px;
     183    border-bottom: 2px solid #f0f0f1;
     184    padding: 0 20px 16px 20px;
     185    overflow-x: auto;
     186    overflow-y: hidden;
     187    flex-wrap: nowrap;
     188    scrollbar-width: thin;
     189    scrollbar-color: #5b6cf2 #f0f0f1;
     190    position: relative;
    191191}
    192192
     
    194194
    195195.mbcore-controls-tabs::-webkit-scrollbar {
    196     display: none;
     196    display: none;
    197197}
    198198
    199199.mbcore-controls-tabs {
    200     scrollbar-width: none;
    201     -ms-overflow-style: none;
     200    scrollbar-width: none;
     201    -ms-overflow-style: none;
    202202}
    203203
    204204.mbcore-controls-tab {
    205     padding: 8px 16px;
    206     border: none;
    207     background: transparent;
    208     border-radius: 8px 8px 0 0;
    209     cursor: pointer;
    210     font-size: 13px;
    211     font-weight: 600;
    212     color: #757575;
    213     transition: all 0.2s ease;
    214     position: relative;
    215     display: flex;
    216     align-items: center;
    217     gap: 6px;
    218     white-space: nowrap;
    219     flex-shrink: 0;
    220     z-index: 2;
     205    padding: 8px 16px;
     206    border: none;
     207    background: transparent;
     208    border-radius: 8px 8px 0 0;
     209    cursor: pointer;
     210    font-size: 13px;
     211    font-weight: 600;
     212    color: #757575;
     213    transition: all 0.2s ease;
     214    position: relative;
     215    display: flex;
     216    align-items: center;
     217    gap: 6px;
     218    white-space: nowrap;
     219    flex-shrink: 0;
     220    z-index: 2;
    221221}
    222222
    223223.mbcore-controls-tab:hover {
    224     background: #f8f9fa;
    225     color: #1e1e1e;
     224    background: #f8f9fa;
     225    color: #1e1e1e;
    226226}
    227227
    228228.mbcore-controls-tab.active {
    229     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    230     color: #ffffff;
    231     box-shadow: 0 2px 8px rgba(91, 108, 242, 0.3);
     229    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     230    color: #ffffff;
     231    box-shadow: 0 2px 8px rgba(91, 108, 242, 0.3);
    232232}
    233233
    234234.mbcore-controls-tab.active::after {
    235     content: '';
    236     position: absolute;
    237     bottom: -10px;
    238     left: 50%;
    239     transform: translateX(-50%);
    240     width: 6px;
    241     height: 6px;
    242     background: #5b6cf2;
    243     border-radius: 50%;
     235    content: '';
     236    position: absolute;
     237    bottom: -10px;
     238    left: 50%;
     239    transform: translateX(-50%);
     240    width: 6px;
     241    height: 6px;
     242    background: #5b6cf2;
     243    border-radius: 50%;
    244244}
    245245
    246246/* Tab indicator dot */
    247247.mbcore-controls-tab::before {
    248     content: '';
    249     width: 6px;
    250     height: 6px;
    251     background: currentColor;
    252     border-radius: 50%;
    253     opacity: 0;
    254     transition: opacity 0.2s ease;
     248    content: '';
     249    width: 6px;
     250    height: 6px;
     251    background: currentColor;
     252    border-radius: 50%;
     253    opacity: 0;
     254    transition: opacity 0.2s ease;
    255255}
    256256
    257257.mbcore-controls-tab.active::before {
    258     opacity: 1;
     258    opacity: 1;
    259259}
    260260
    261261/* Tab content */
    262262.mbcore-tab-content {
    263     display: none;
     263    display: none;
    264264}
    265265
    266266.mbcore-tab-content.active {
    267     display: block;
     267    display: block;
    268268}
    269269
    270270.mbcore-controls-title {
    271     font-size: 14px;
    272     font-weight: 700;
    273     color: #1e1e1e;
    274     text-transform: uppercase;
    275     letter-spacing: 0.5px;
    276     display: flex;
    277     align-items: center;
    278     gap: 8px;
    279     margin-bottom: 16px;
     271    font-size: 14px;
     272    font-weight: 700;
     273    color: #1e1e1e;
     274    text-transform: uppercase;
     275    letter-spacing: 0.5px;
     276    display: flex;
     277    align-items: center;
     278    gap: 8px;
     279    margin-bottom: 16px;
    280280}
    281281
    282282.mbcore-controls-title::before {
    283     content: "⚙️";
    284     font-size: 16px;
    285 }
    286 
    287 /* ============================================
    288    CONTROL SECTIONS
    289    ============================================ */
     283    content: "⚙️";
     284    font-size: 16px;
     285}
     286
     287/* ============================================
     288    CONTROL SECTIONS
     289    ============================================ */
    290290
    291291/* Control groups with labels */
    292292.mbcore-control-group {
    293     margin-bottom: 20px;
    294     padding-bottom: 20px;
    295     border-bottom: 1px solid #f0f0f1;
     293    margin-bottom: 20px;
     294    padding-bottom: 20px;
     295    border-bottom: 1px solid #f0f0f1;
    296296}
    297297
    298298.mbcore-control-group:last-child {
    299     margin-bottom: 0;
    300     padding-bottom: 0;
    301     border-bottom: none;
     299    margin-bottom: 0;
     300    padding-bottom: 0;
     301    border-bottom: none;
    302302}
    303303
    304304.mbcore-control-group-label {
    305     font-size: 11px;
    306     font-weight: 600;
    307     text-transform: uppercase;
    308     color: #757575;
    309     margin-bottom: 12px;
    310     letter-spacing: 0.5px;
    311 }
    312 
    313 /* ============================================
    314    ENHANCED INPUT CONTROLS - Light Theme
    315    ============================================ */
     305    font-size: 11px;
     306    font-weight: 600;
     307    text-transform: uppercase;
     308    color: #757575;
     309    margin-bottom: 12px;
     310    letter-spacing: 0.5px;
     311}
     312
     313/* ============================================
     314    ENHANCED INPUT CONTROLS - Light Theme
     315    ============================================ */
    316316
    317317/* Text inputs - Light and clean */
     
    320320.mbcore-controls-section .components-text-control__input,
    321321.mbcore-controls-section .components-textarea-control__input {
    322     border: 2px solid #e8eaed;
    323     border-radius: 8px;
    324     padding: 12px 16px;
    325     font-size: 14px;
    326     transition: all 0.3s ease;
    327     background: #ffffff;
    328     color: #1e1e1e;
    329     box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
     322    border: 2px solid #e8eaed;
     323    border-radius: 8px;
     324    padding: 12px 16px;
     325    font-size: 14px;
     326    transition: all 0.3s ease;
     327    background: #ffffff;
     328    color: #1e1e1e;
     329    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
    330330}
    331331
     
    334334.mbcore-controls-section .components-text-control__input:hover,
    335335.mbcore-controls-section .components-textarea-control__input:hover {
    336     border-color: #c8cef5;
    337     box-shadow: 0 2px 6px rgba(91, 108, 242, 0.08);
     336    border-color: #c8cef5;
     337    box-shadow: 0 2px 6px rgba(91, 108, 242, 0.08);
    338338}
    339339
     
    342342.mbcore-controls-section .components-text-control__input:focus,
    343343.mbcore-controls-section .components-textarea-control__input:focus {
    344     background: #ffffff;
    345     border-color: #5b6cf2;
    346     box-shadow: 0 0 0 3px rgba(91, 108, 242, 0.1), 0 2px 8px rgba(91, 108, 242, 0.15);
    347     outline: none;
    348     transform: translateY(-1px);
     344    background: #ffffff;
     345    border-color: #5b6cf2;
     346    box-shadow: 0 0 0 3px rgba(91, 108, 242, 0.1), 0 2px 8px rgba(91, 108, 242, 0.15);
     347    outline: none;
     348    transform: translateY(-1px);
    349349}
    350350
     
    352352.mbcore-content-controls .components-base-control__label,
    353353.mbcore-controls-section .components-base-control__label {
    354     font-weight: 700;
    355     font-size: 13px;
    356     color: #1e1e1e;
    357     margin-bottom: 10px;
    358     display: block;
    359     letter-spacing: 0.3px;
     354    font-weight: 700;
     355    font-size: 13px;
     356    color: #1e1e1e;
     357    margin-bottom: 10px;
     358    display: block;
     359    letter-spacing: 0.3px;
    360360}
    361361
     
    363363.mbcore-content-controls .components-base-control__help,
    364364.mbcore-controls-section .components-base-control__help {
    365     font-size: 12px;
    366     color: #757575;
    367     margin-top: 8px;
    368     font-style: normal;
    369     line-height: 1.5;
     365    font-size: 12px;
     366    color: #757575;
     367    margin-top: 8px;
     368    font-style: normal;
     369    line-height: 1.5;
    370370}
    371371
    372372/* Individual control spacing */
    373373.mbcore-controls-section .components-base-control {
    374     margin-bottom: 24px;
    375     padding: 16px;
    376     background: rgba(255, 255, 255, 0.6);
    377     border-radius: 10px;
    378     transition: all 0.2s ease;
     374    margin-bottom: 24px;
     375    padding: 16px;
     376    background: rgba(255, 255, 255, 0.6);
     377    border-radius: 10px;
     378    transition: all 0.2s ease;
    379379}
    380380
    381381.mbcore-controls-section .components-base-control:hover {
    382     background: rgba(255, 255, 255, 0.9);
    383     box-shadow: 0 2px 8px rgba(91, 108, 242, 0.06);
     382    background: rgba(255, 255, 255, 0.9);
     383    box-shadow: 0 2px 8px rgba(91, 108, 242, 0.06);
    384384}
    385385
    386386.mbcore-controls-section .components-base-control:last-child {
    387     margin-bottom: 0;
    388 }
    389 
    390 /* ============================================
    391    RANGE CONTROLS (SLIDERS)
    392    ============================================ */
     387    margin-bottom: 0;
     388}
     389
     390/* ============================================
     391    RANGE CONTROLS (SLIDERS)
     392    ============================================ */
    393393
    394394.mbcore-content-controls .components-range-control__wrapper {
    395     background: #f8f9fa;
    396     padding: 12px;
    397     border-radius: 6px;
    398     margin-top: 8px;
     395    background: #f8f9fa;
     396    padding: 12px;
     397    border-radius: 6px;
     398    margin-top: 8px;
    399399}
    400400
    401401.mbcore-content-controls .components-range-control__slider {
    402     background: linear-gradient(to right, #2271b1 0%, #2271b1 50%, #ddd 50%, #ddd 100%);
    403     height: 4px;
    404     border-radius: 2px;
     402    background: linear-gradient(to right, #2271b1 0%, #2271b1 50%, #ddd 50%, #ddd 100%);
     403    height: 4px;
     404    border-radius: 2px;
    405405}
    406406
    407407.mbcore-content-controls .components-range-control__thumb {
    408     background: #2271b1;
    409     border: 2px solid #ffffff;
    410     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    411     width: 16px;
    412     height: 16px;
     408    background: #2271b1;
     409    border: 2px solid #ffffff;
     410    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
     411    width: 16px;
     412    height: 16px;
    413413}
    414414
    415415.mbcore-content-controls .components-range-control__number {
    416     background: #ffffff;
    417     border: 1px solid #ddd;
    418     border-radius: 4px;
    419     padding: 4px 8px;
    420     min-width: 50px;
    421     text-align: center;
    422 }
    423 
    424 /* ============================================
    425    TOGGLE CONTROLS
    426    ============================================ */
     416    background: #ffffff;
     417    border: 1px solid #ddd;
     418    border-radius: 4px;
     419    padding: 4px 8px;
     420    min-width: 50px;
     421    text-align: center;
     422}
     423
     424/* ============================================
     425    TOGGLE CONTROLS
     426    ============================================ */
    427427
    428428.mbcore-content-controls .components-toggle-control {
    429     background: #f8f9fa;
    430     padding: 12px;
    431     border-radius: 6px;
    432     margin-bottom: 12px;
     429    background: #f8f9fa;
     430    padding: 12px;
     431    border-radius: 6px;
     432    margin-bottom: 12px;
    433433}
    434434
    435435.mbcore-content-controls .components-toggle-control .components-base-control__field {
    436     display: flex;
    437     align-items: center;
    438     justify-content: space-between;
     436    display: flex;
     437    align-items: center;
     438    justify-content: space-between;
    439439}
    440440
    441441.mbcore-content-controls .components-form-toggle {
    442     margin: 0;
     442    margin: 0;
    443443}
    444444
    445445.mbcore-content-controls .components-form-toggle.is-checked .components-form-toggle__track {
    446     background-color: #2271b1;
    447 }
    448 
    449 /* ============================================
    450    SELECT & RADIO CONTROLS
    451    ============================================ */
     446    background-color: #2271b1;
     447}
     448
     449/* ============================================
     450    SELECT & RADIO CONTROLS
     451    ============================================ */
    452452
    453453.mbcore-content-controls .components-select-control__input {
    454     border: 1px solid #ddd;
    455     border-radius: 4px;
    456     padding: 8px 32px 8px 12px;
    457     font-size: 14px;
    458     background: #fafafa url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="5"><path fill="%23555" d="M0 0l5 5 5-5z"/></svg>') no-repeat right 12px center;
    459     appearance: none;
     454    border: 1px solid #ddd;
     455    border-radius: 4px;
     456    padding: 8px 32px 8px 12px;
     457    font-size: 14px;
     458    background: #fafafa url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="5"><path fill="%23555" d="M0 0l5 5 5-5z"/></svg>') no-repeat right 12px center;
     459    appearance: none;
    460460}
    461461
    462462.mbcore-content-controls .components-select-control__input:focus {
    463     background-color: #ffffff;
    464     border-color: #2271b1;
    465     box-shadow: 0 0 0 1px #2271b1;
     463    background-color: #ffffff;
     464    border-color: #2271b1;
     465    box-shadow: 0 0 0 1px #2271b1;
    466466}
    467467
    468468.mbcore-content-controls .components-radio-control__option {
    469     background: #f8f9fa;
    470     padding: 10px 12px;
    471     border-radius: 4px;
    472     margin-bottom: 8px;
    473     transition: all 0.2s ease;
     469    background: #f8f9fa;
     470    padding: 10px 12px;
     471    border-radius: 4px;
     472    margin-bottom: 8px;
     473    transition: all 0.2s ease;
    474474}
    475475
    476476.mbcore-content-controls .components-radio-control__option:hover {
    477     background: #e8eaed;
     477    background: #e8eaed;
    478478}
    479479
    480480.mbcore-content-controls .components-radio-control__input:checked+.components-radio-control__label {
    481     font-weight: 600;
    482     color: #2271b1;
    483 }
    484 
    485 /* ============================================
    486    COLOR PICKER
    487    ============================================ */
     481    font-weight: 600;
     482    color: #2271b1;
     483}
     484
     485/* ============================================
     486    COLOR PICKER
     487    ============================================ */
    488488
    489489.mbcore-content-controls .components-color-palette {
    490     padding: 12px;
    491     background: #f8f9fa;
    492     border-radius: 6px;
     490    padding: 12px;
     491    background: #f8f9fa;
     492    border-radius: 6px;
    493493}
    494494
    495495.mbcore-content-controls .components-color-palette__item {
    496     border-radius: 4px;
    497     transition: transform 0.2s ease;
     496    border-radius: 4px;
     497    transition: transform 0.2s ease;
    498498}
    499499
    500500.mbcore-content-controls .components-color-palette__item:hover {
    501     transform: scale(1.1);
     501    transform: scale(1.1);
    502502}
    503503
    504504.mbcore-content-controls .components-color-palette__custom-color {
    505     border: 2px dashed #ddd;
    506     border-radius: 4px;
    507 }
    508 
    509 /* ============================================
    510    PREVIEW SECTION - Right Column
    511    ============================================ */
     505    border: 2px dashed #ddd;
     506    border-radius: 4px;
     507}
     508
     509/* ============================================
     510    PREVIEW SECTION - Right Column
     511    ============================================ */
    512512
    513513.mbcore-preview-wrapper {
    514     background: #f8f9fa;
    515     border: 1px solid #e0e0e0;
    516     border-radius: 12px;
    517     padding: 0;
    518     overflow: hidden;
    519     box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
    520     display: flex;
    521     flex-direction: column;
    522     min-height: 400px;
     514    background: #f8f9fa;
     515    border: 1px solid #e0e0e0;
     516    border-radius: 12px;
     517    padding: 0;
     518    overflow: hidden;
     519    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
     520    display: flex;
     521    flex-direction: column;
     522    min-height: 400px;
    523523}
    524524
    525525.mbcore-preview-label {
    526     font-size: 12px;
    527     font-weight: 700;
    528     text-transform: uppercase;
    529     color: #ffffff;
    530     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    531     padding: 16px 20px;
    532     letter-spacing: 0.5px;
    533     display: flex;
    534     align-items: center;
    535     gap: 8px;
    536     border-bottom: 3px solid #4f5bd5;
     526    font-size: 12px;
     527    font-weight: 700;
     528    text-transform: uppercase;
     529    color: #ffffff;
     530    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     531    padding: 16px 20px;
     532    letter-spacing: 0.5px;
     533    display: flex;
     534    align-items: center;
     535    gap: 8px;
     536    border-bottom: 3px solid #4f5bd5;
    537537}
    538538
    539539.mbcore-preview-label::before {
    540     content: "👁";
    541     font-size: 16px;
     540    content: "👁";
     541    font-size: 16px;
    542542}
    543543
    544544.mbcore-preview-content {
    545     background: #ffffff;
    546     padding: 24px;
    547     flex: 1;
    548     overflow: auto;
     545    background: #ffffff;
     546    padding: 24px;
     547    flex: 1;
     548    overflow: auto;
    549549}
    550550
    551551/* Block Details Section */
    552552.mbcore-block-details {
    553     background: #f8f9fa;
    554     border: 1px solid #e0e0e0;
    555     border-radius: 12px;
    556     padding: 0;
    557     overflow: hidden;
    558     box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
    559     margin-top: 24px;
     553    background: #f8f9fa;
     554    border: 1px solid #e0e0e0;
     555    border-radius: 12px;
     556    padding: 0;
     557    overflow: hidden;
     558    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
     559    margin-top: 24px;
    560560}
    561561
    562562.mbcore-block-details-header {
    563     font-size: 12px;
    564     font-weight: 700;
    565     text-transform: uppercase;
    566     color: #ffffff;
    567     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    568     padding: 16px 20px;
    569     letter-spacing: 0.5px;
    570     border-bottom: 3px solid #4f5bd5;
     563    font-size: 12px;
     564    font-weight: 700;
     565    text-transform: uppercase;
     566    color: #ffffff;
     567    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     568    padding: 16px 20px;
     569    letter-spacing: 0.5px;
     570    border-bottom: 3px solid #4f5bd5;
    571571}
    572572
    573573.mbcore-block-details-content {
    574     background: #ffffff;
    575     padding: 20px;
     574    background: #ffffff;
     575    padding: 20px;
    576576}
    577577
    578578.detail-item {
    579     display: flex;
    580     justify-content: space-between;
    581     align-items: center;
    582     padding: 12px 0;
    583     border-bottom: 1px solid #f0f0f1;
     579    display: flex;
     580    justify-content: space-between;
     581    align-items: center;
     582    padding: 12px 0;
     583    border-bottom: 1px solid #f0f0f1;
    584584}
    585585
    586586.detail-item:last-child {
    587     border-bottom: none;
     587    border-bottom: none;
    588588}
    589589
    590590.detail-label {
    591     font-weight: 600;
    592     font-size: 13px;
    593     color: #1e1e1e;
     591    font-weight: 600;
     592    font-size: 13px;
     593    color: #1e1e1e;
    594594}
    595595
    596596.detail-value {
    597     font-size: 13px;
    598     color: #757575;
     597    font-size: 13px;
     598    color: #757575;
    599599}
    600600
    601601.detail-value.detail-code {
    602     font-family: 'Courier New', monospace;
    603     background: #f0f0f1;
    604     padding: 4px 8px;
    605     border-radius: 4px;
    606     font-size: 12px;
    607     color: #5b6cf2;
     602    font-family: 'Courier New', monospace;
     603    background: #f0f0f1;
     604    padding: 4px 8px;
     605    border-radius: 4px;
     606    font-size: 12px;
     607    color: #5b6cf2;
    608608}
    609609
    610610.detail-value.detail-number {
    611     background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
    612     color: #ffffff;
    613     padding: 4px 12px;
    614     border-radius: 12px;
    615     font-weight: 700;
    616     font-size: 12px;
     611    background: linear-gradient(135deg, #5b6cf2 0%, #4f5bd5 100%);
     612    color: #ffffff;
     613    padding: 4px 12px;
     614    border-radius: 12px;
     615    font-weight: 700;
     616    font-size: 12px;
    617617}
    618618
     
    620620/* Loading state */
    621621.mbcore-preview-content.is-loading {
    622     display: flex;
    623     align-items: center;
    624     justify-content: center;
    625     color: #757575;
    626     font-size: 14px;
     622    display: flex;
     623    align-items: center;
     624    justify-content: center;
     625    color: #757575;
     626    font-size: 14px;
    627627}
    628628
    629629.mbcore-preview-content.is-loading::before {
    630     content: "⏳";
    631     margin-right: 8px;
    632     animation: spin 1s linear infinite;
     630    content: "⏳";
     631    margin-right: 8px;
     632    animation: spin 1s linear infinite;
    633633}
    634634
    635635@keyframes spin {
    636     from {
    637         transform: rotate(0deg);
    638     }
    639 
    640     to {
    641         transform: rotate(360deg);
    642     }
     636    from {
     637        transform: rotate(0deg);
     638    }
     639
     640    to {
     641        transform: rotate(360deg);
     642    }
    643643}
    644644
    645645/* Responsive - Stack on smaller screens */
    646646@media (max-width: 1280px) {
    647     .mbcore-content-controls {
    648         grid-template-columns: 1fr;
    649     }
    650 
    651     .mbcore-controls-section {
    652         position: relative;
    653         top: 0;
    654         max-height: none;
    655     }
    656 
    657     .mbcore-preview-wrapper {
    658         min-height: 300px;
    659     }
    660 }
    661 
    662 /* ============================================
    663    INSPECTOR (SIDEBAR) ENHANCEMENTS
    664    ============================================ */
     647    .mbcore-content-controls {
     648        grid-template-columns: 1fr;
     649    }
     650
     651    .mbcore-controls-section {
     652        position: relative;
     653        top: 0;
     654        max-height: none;
     655    }
     656
     657    .mbcore-preview-wrapper {
     658        min-height: 300px;
     659    }
     660}
     661
     662/* ============================================
     663    INSPECTOR (SIDEBAR) ENHANCEMENTS
     664    ============================================ */
    665665
    666666.components-panel__body.is-opened .mbcore-inspector-control {
    667     padding: 12px 0;
    668     border-bottom: 1px solid #f0f0f1;
     667    padding: 12px 0;
     668    border-bottom: 1px solid #f0f0f1;
    669669}
    670670
    671671.components-panel__body.is-opened .mbcore-inspector-control:last-child {
    672     border-bottom: none;
    673 }
    674 
    675 /* ============================================
    676    RESPONSIVE HELPERS
    677    ============================================ */
     672    border-bottom: none;
     673}
     674
     675/* ============================================
     676    RESPONSIVE HELPERS
     677    ============================================ */
    678678
    679679.mbcore-responsive-preview {
    680     display: flex;
    681     gap: 8px;
    682     margin-bottom: 12px;
     680    display: flex;
     681    gap: 8px;
     682    margin-bottom: 12px;
    683683}
    684684
    685685.mbcore-responsive-preview button {
    686     flex: 1;
    687     padding: 6px 12px;
    688     border: 1px solid #ddd;
    689     background: #ffffff;
    690     border-radius: 4px;
    691     font-size: 12px;
    692     cursor: pointer;
    693     transition: all 0.2s ease;
     686    flex: 1;
     687    padding: 6px 12px;
     688    border: 1px solid #ddd;
     689    background: #ffffff;
     690    border-radius: 4px;
     691    font-size: 12px;
     692    cursor: pointer;
     693    transition: all 0.2s ease;
    694694}
    695695
    696696.mbcore-responsive-preview button:hover {
    697     background: #f8f9fa;
    698     border-color: #2271b1;
     697    background: #f8f9fa;
     698    border-color: #2271b1;
    699699}
    700700
    701701.mbcore-responsive-preview button.is-active {
    702     background: #2271b1;
    703     color: #ffffff;
    704     border-color: #2271b1;
    705 }
    706 
    707 /* ============================================
    708    EMPTY STATE
    709    ============================================ */
     702    background: #2271b1;
     703    color: #ffffff;
     704    border-color: #2271b1;
     705}
     706
     707/* ============================================
     708    EMPTY STATE
     709    ============================================ */
    710710
    711711.mbcore-empty-state {
    712     text-align: center;
    713     padding: 40px 20px;
    714     color: #757575;
     712    text-align: center;
     713    padding: 40px 20px;
     714    color: #757575;
    715715}
    716716
    717717.mbcore-empty-state-icon {
    718     font-size: 48px;
    719     margin-bottom: 16px;
    720     opacity: 0.5;
     718    font-size: 48px;
     719    margin-bottom: 16px;
     720    opacity: 0.5;
    721721}
    722722
    723723.mbcore-empty-state-title {
    724     font-size: 16px;
    725     font-weight: 600;
    726     color: #1e1e1e;
    727     margin-bottom: 8px;
     724    font-size: 16px;
     725    font-weight: 600;
     726    color: #1e1e1e;
     727    margin-bottom: 8px;
    728728}
    729729
    730730.mbcore-empty-state-description {
    731     font-size: 13px;
    732     color: #757575;
    733 }
    734 
    735 /* ============================================
    736    ANIMATIONS
    737    ============================================ */
     731    font-size: 13px;
     732    color: #757575;
     733}
     734
     735/* ============================================
     736    ANIMATIONS
     737    ============================================ */
    738738
    739739.mbcore-content-controls>* {
    740     animation: fadeInUp 0.3s ease;
     740    animation: fadeInUp 0.3s ease;
    741741}
    742742
    743743@keyframes fadeInUp {
    744     from {
    745         opacity: 0;
    746         transform: translateY(10px);
    747     }
    748 
    749     to {
    750         opacity: 1;
    751         transform: translateY(0);
    752     }
    753 }
    754 
    755 /* ============================================
    756    ACCESSIBILITY ENHANCEMENTS
    757    ============================================ */
     744    from {
     745        opacity: 0;
     746        transform: translateY(10px);
     747    }
     748
     749    to {
     750        opacity: 1;
     751        transform: translateY(0);
     752    }
     753}
     754
     755/* ============================================
     756    ACCESSIBILITY ENHANCEMENTS
     757    ============================================ */
    758758
    759759.mbcore-content-controls *:focus-visible {
    760     outline: 2px solid #2271b1;
    761     outline-offset: 2px;
     760    outline: 2px solid #2271b1;
     761    outline-offset: 2px;
    762762}
    763763
    764764/* High contrast mode support */
    765765@media (prefers-contrast: high) {
    766     .mbcore-content-controls {
    767         border-width: 2px;
    768     }
    769 
    770     .mbcore-content-controls .components-text-control__input,
    771     .mbcore-content-controls .components-select-control__input {
    772         border-width: 2px;
    773     }
     766    .mbcore-content-controls {
     767        border-width: 2px;
     768    }
     769
     770    .mbcore-content-controls .components-text-control__input,
     771    .mbcore-content-controls .components-select-control__input {
     772        border-width: 2px;
     773    }
    774774}
    775775
     
    777777@media (prefers-reduced-motion: reduce) {
    778778
    779     .mbcore-content-controls,
    780     .mbcore-content-controls *,
    781     .mbcore-preview-content.is-loading::before {
    782         animation: none !important;
    783         transition: none !important;
    784     }
    785 }
    786 
    787 /* ============================================
    788    MEDIA CONTROL STYLES
    789    ============================================ */
     779    .mbcore-content-controls,
     780    .mbcore-content-controls *,
     781    .mbcore-preview-content.is-loading::before {
     782        animation: none !important;
     783        transition: none !important;
     784    }
     785}
     786
     787/* ============================================
     788    MEDIA CONTROL STYLES
     789    ============================================ */
    790790.mbcore-media-control {
    791     background: transparent;
     791    background: transparent;
    792792}
    793793
    794794.mbcore-media-upload-wrapper {
    795     margin-top: 10px;
     795    margin-top: 10px;
    796796}
    797797
    798798.mbcore-media-preview img {
    799     border: 2px solid #e0e0e0;
    800     transition: all 0.2s ease;
    801     box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    802     display: block;
     799    border: 2px solid #e0e0e0;
     800    transition: all 0.2s ease;
     801    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
     802    display: block;
    803803}
    804804
    805805.mbcore-media-preview img:hover {
    806     border-color: #5b6cf2;
     806    border-color: #5b6cf2;
    807807}
    808808
    809809.mbcore-media-actions {
    810     margin-bottom: 15px;
    811 }
     810    margin-bottom: 15px;
     811}
  • modular-blocks-core/trunk/assets/js/admin.js

    r3435947 r3446627  
    11document.addEventListener('DOMContentLoaded', function () {
    2     // Initialize Code Editors
    3     const editors = {};
    4     if (typeof wp !== 'undefined' && wp.codeEditor && typeof mbcore_editor_settings !== 'undefined') {
    5         const phpArea = document.querySelector('textarea[name="mbcore_render_php"]');
    6         if (phpArea && mbcore_editor_settings.php) {
    7             editors.php = wp.codeEditor.initialize(phpArea, mbcore_editor_settings.php);
    8         }
    9 
    10         const cssArea = document.querySelector('textarea[name="mbcore_style_css"]');
    11         if (cssArea && mbcore_editor_settings.css) {
    12             editors.css = wp.codeEditor.initialize(cssArea, mbcore_editor_settings.css);
    13         }
    14 
    15         const jsArea = document.querySelector('textarea[name="mbcore_script_js"]');
    16         if (jsArea && mbcore_editor_settings.js) {
    17             editors.js = wp.codeEditor.initialize(jsArea, mbcore_editor_settings.js);
    18         }
    19 
    20         // Add Resize Support for CodeMirror
    21         if (window.ResizeObserver) {
    22             Object.values(editors).forEach(editor => {
    23                 if (editor && editor.codemirror) {
    24                     const cm = editor.codemirror;
    25                     const wrapper = cm.getWrapperElement();
    26                     const observer = new ResizeObserver(() => {
    27                         cm.refresh();
    28                     });
    29                     observer.observe(wrapper);
    30                 }
    31             });
    32         }
    33     }
    34 
    35     // Code Editor Tabs
    36     const tabs = document.querySelectorAll('.mbcore-tab-link');
    37     tabs.forEach(tab => {
    38         tab.addEventListener('click', function () {
    39             const target = this.getAttribute('data-tab');
    40 
    41             // Update buttons
    42             tabs.forEach(t => t.classList.remove('active'));
    43             this.classList.add('active');
    44 
    45             // Update content
    46             document.querySelectorAll('.mbcore-tab-content').forEach(content => {
    47                 content.classList.remove('active');
    48             });
    49             const activeContent = document.getElementById('mbcore-code-' + target);
    50             if (activeContent) {
    51                 activeContent.classList.add('active');
    52                 // Refresh CodeMirror instance
    53                 if (editors[target] && editors[target].codemirror) {
    54                     editors[target].codemirror.refresh();
    55                 }
    56             }
    57         });
    58     });
    59 
    60     // Refresh on window resize
    61     window.addEventListener('resize', function () {
    62         for (const key in editors) {
    63             if (editors[key] && editors[key].codemirror) {
    64                 editors[key].codemirror.refresh();
    65             }
    66         }
    67     });
    68 
    69     const container = document.getElementById('mbcore-controls-container');
    70     const addButton = document.getElementById('mbcore-add-control');
    71 
    72     if (!container || !addButton) return;
    73 
    74     // Initialize Sortable
    75     if (jQuery && jQuery.fn.sortable) {
    76         jQuery(container).sortable({
    77             handle: '.mbcore-control-header',
    78             placeholder: 'sortable-placeholder',
    79             forcePlaceholderSize: true,
    80             start: function (e, ui) {
    81                 ui.placeholder.height(ui.item.height());
    82             }
    83         });
    84 
    85         // Initialize Sub-Controls Sortable
    86         jQuery('.mbcore-sub-controls-list').sortable({
    87             handle: '.mbcore-sub-control-handle',
    88             placeholder: 'sortable-placeholder',
    89             forcePlaceholderSize: true
    90         });
    91     }
    92 
    93     let controlIndex = container.querySelectorAll('.mbcore-control-item').length;
    94 
    95     addButton.addEventListener('click', function (e) {
    96         e.preventDefault();
    97 
    98         const template = document.getElementById('mbcore-control-template');
    99         if (!template) return;
    100 
    101         let html = template.innerHTML;
    102         html = html.replace(/{{INDEX}}/g, controlIndex);
    103 
    104         const temp = document.createElement('div');
    105         temp.innerHTML = html.trim();
    106         const item = temp.firstChild;
    107 
    108         container.appendChild(item);
    109         controlIndex++;
    110 
    111         // Trigger change to set initial visibility of options
    112         const sel = item.querySelector('.mbcore-type-select');
    113         if (sel) {
    114             sel.dispatchEvent(new Event('change', { bubbles: true }));
    115         }
    116     });
    117 
    118     // Delegated event for Type Change to toggle Options field AND Update Badge
    119     container.addEventListener('change', function (e) {
    120         if (e.target.classList.contains('mbcore-type-select')) {
    121             const row = e.target.closest('.mbcore-control-body');
    122             const card = e.target.closest('.mbcore-control-item');
    123             const optionsWrapper = row.querySelector('.mbcore-options-wrapper');
    124             const badge = card.querySelector('.mbcore-control-type-badge');
    125             const val = e.target.value;
    126 
    127             // Update Badge
    128             if (badge) badge.textContent = val;
    129 
    130             // Toggle Options
    131             if (['select', 'radio', 'range', 'checkbox'].includes(val)) {
    132                 optionsWrapper.style.display = 'block';
    133             } else {
    134                 optionsWrapper.style.display = 'none';
    135             }
    136 
    137             // Toggle Repeater Sub Controls
    138             const subWrapper = row.querySelector('.mbcore-sub-controls-wrapper');
    139             if (subWrapper) {
    140                 if (val === 'repeater') {
    141                     subWrapper.style.display = 'block';
    142                 } else {
    143                     subWrapper.style.display = 'none';
    144                 }
    145             }
    146         }
    147     });
    148 
    149     // Handle Sub-Control Adding
    150     container.addEventListener('click', function (e) {
    151         if (e.target.classList.contains('mbcore-add-sub-control')) {
    152             e.preventDefault();
    153             const list = e.target.previousElementSibling;
    154             const parentIndex = list.getAttribute('data-parent-index');
    155             const subIndex = list.querySelectorAll('.mbcore-sub-control-item').length;
    156 
    157             const subItem = document.createElement('div');
    158             subItem.className = 'mbcore-sub-control-item';
    159             subItem.innerHTML = `
    160                 <div class="mbcore-sub-control-row">
    161                     <span class="mbcore-sub-control-handle dashicons dashicons-move"></span>
    162                     <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][label]" placeholder="Label" />
    163                     <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][name]" placeholder="Name" />
    164                     <select name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][type]">
    165                         <option value="string">Text</option>
    166                         <option value="textarea">Text Area</option>
    167                         <option value="image">Image</option>
    168                         <option value="url">URL</option>
    169                         <option value="color">Color</option>
    170                     </select>
    171                     <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][default]" placeholder="Default" />
    172                     <button type="button" class="button button-link-delete btn-remove-sub">×</button>
    173                 </div>
    174             `;
    175             list.appendChild(subItem);
    176         }
    177 
    178         // Handle Sub-Control Removing
    179         if (e.target.classList.contains('btn-remove-sub')) {
    180             e.preventDefault();
    181             e.target.closest('.mbcore-sub-control-item').remove();
    182         }
    183     });
    184 
    185     // Live Title Update
    186     container.addEventListener('input', function (e) {
    187         if (e.target.classList.contains('mbcore-update-title')) {
    188             const card = e.target.closest('.mbcore-control-item');
    189             const titleSpan = card.querySelector('.mbcore-control-title');
    190             if (titleSpan) titleSpan.textContent = e.target.value || 'New Control';
    191         }
    192     });
    193 
    194     // Accordion Toggle and Delete
    195     container.addEventListener('click', function (e) {
    196         // Toggle if clicked header (but not if clicked actions inside header if any)
    197         if (e.target.closest('.mbcore-control-header') && !e.target.closest('.mbcore-control-actions')) {
    198             const card = e.target.closest('.mbcore-control-item');
    199             card.classList.toggle('open');
    200         }
    201 
    202         // Delete
    203         if (e.target.classList.contains('btn-remove')) {
    204             e.preventDefault();
    205             if (confirm('Are you sure you want to delete this control?')) {
    206                 e.target.closest('.mbcore-control-item').remove();
    207             }
    208         }
    209     });
    210 
    211     // Trigger change on all existing selects on load to set initial state
    212     const existingSelects = container.querySelectorAll('.mbcore-type-select');
    213     existingSelects.forEach(sel => {
    214         sel.dispatchEvent(new Event('change', { bubbles: true }));
    215     });
    216 
    217     // Bypassing ModSecurity 406 Errors (Base64 Encode on Submit)
    218     const postForm = document.getElementById('post');
    219     if (postForm) {
    220         postForm.addEventListener('submit', function () {
    221             // Helper to encode Unicode correctly
    222             const encodeBase64 = (str) => {
    223                 try {
    224                     return 'base64:' + btoa(unescape(encodeURIComponent(str)));
    225                 } catch (e) {
    226                     return str;
    227                 }
    228             };
    229 
    230             const phpArea = document.querySelector('textarea[name="mbcore_render_php"]');
    231             const cssArea = document.querySelector('textarea[name="mbcore_style_css"]');
    232             const jsArea = document.querySelector('textarea[name="mbcore_script_js"]');
    233 
    234             if (phpArea && phpArea.value) {
    235                 phpArea.value = encodeBase64(phpArea.value);
    236             }
    237             if (cssArea && cssArea.value) {
    238                 cssArea.value = encodeBase64(cssArea.value);
    239             }
    240             if (jsArea && jsArea.value) {
    241                 jsArea.value = encodeBase64(jsArea.value);
    242             }
    243         });
    244     }
     2    // Initialize Code Editors
     3    const editors = {};
     4    if (typeof wp !== 'undefined' && wp.codeEditor && typeof mbcore_editor_settings !== 'undefined') {
     5        const phpArea = document.querySelector('textarea[name="mbcore_render_php"]');
     6        if (phpArea && mbcore_editor_settings.php) {
     7            editors.php = wp.codeEditor.initialize(phpArea, mbcore_editor_settings.php);
     8        }
     9
     10        const cssArea = document.querySelector('textarea[name="mbcore_style_css"]');
     11        if (cssArea && mbcore_editor_settings.css) {
     12            editors.css = wp.codeEditor.initialize(cssArea, mbcore_editor_settings.css);
     13        }
     14
     15        const jsArea = document.querySelector('textarea[name="mbcore_script_js"]');
     16        if (jsArea && mbcore_editor_settings.js) {
     17            editors.js = wp.codeEditor.initialize(jsArea, mbcore_editor_settings.js);
     18        }
     19
     20        // Add Resize Support for CodeMirror
     21        if (window.ResizeObserver) {
     22            Object.values(editors).forEach(editor => {
     23                if (editor && editor.codemirror) {
     24                    const cm = editor.codemirror;
     25                    const wrapper = cm.getWrapperElement();
     26                    const observer = new ResizeObserver(() => {
     27                        cm.refresh();
     28                    });
     29                    observer.observe(wrapper);
     30                }
     31            });
     32        }
     33    }
     34
     35    // Code Editor Tabs
     36    const tabs = document.querySelectorAll('.mbcore-tab-link');
     37    tabs.forEach(tab => {
     38        tab.addEventListener('click', function () {
     39            const target = this.getAttribute('data-tab');
     40
     41            // Update buttons
     42            tabs.forEach(t => t.classList.remove('active'));
     43            this.classList.add('active');
     44
     45            // Update content
     46            document.querySelectorAll('.mbcore-tab-content').forEach(content => {
     47                content.classList.remove('active');
     48            });
     49            const activeContent = document.getElementById('mbcore-code-' + target);
     50            if (activeContent) {
     51                activeContent.classList.add('active');
     52                // Refresh CodeMirror instance
     53                if (editors[target] && editors[target].codemirror) {
     54                    editors[target].codemirror.refresh();
     55                }
     56            }
     57        });
     58    });
     59
     60    // Refresh on window resize
     61    window.addEventListener('resize', function () {
     62        for (const key in editors) {
     63            if (editors[key] && editors[key].codemirror) {
     64                editors[key].codemirror.refresh();
     65            }
     66        }
     67    });
     68
     69    const container = document.getElementById('mbcore-controls-container');
     70    const addButton = document.getElementById('mbcore-add-control');
     71
     72    if (!container || !addButton) return;
     73
     74    // Initialize Sortable
     75    if (jQuery && jQuery.fn.sortable) {
     76        jQuery(container).sortable({
     77            handle: '.mbcore-control-header',
     78            placeholder: 'sortable-placeholder',
     79            forcePlaceholderSize: true,
     80            start: function (e, ui) {
     81                ui.placeholder.height(ui.item.height());
     82            }
     83        });
     84
     85        // Initialize Sub-Controls Sortable
     86        jQuery('.mbcore-sub-controls-list').sortable({
     87            handle: '.mbcore-sub-control-handle',
     88            placeholder: 'sortable-placeholder',
     89            forcePlaceholderSize: true
     90        });
     91    }
     92
     93    let controlIndex = container.querySelectorAll('.mbcore-control-item').length;
     94
     95    addButton.addEventListener('click', function (e) {
     96        e.preventDefault();
     97
     98        const template = document.getElementById('mbcore-control-template');
     99        if (!template) return;
     100
     101        let html = template.innerHTML;
     102        html = html.replace(/{{INDEX}}/g, controlIndex);
     103
     104        const temp = document.createElement('div');
     105        temp.innerHTML = html.trim();
     106        const item = temp.firstChild;
     107
     108        container.appendChild(item);
     109        controlIndex++;
     110
     111        // Trigger change to set initial visibility of options
     112        const sel = item.querySelector('.mbcore-type-select');
     113        if (sel) {
     114            sel.dispatchEvent(new Event('change', { bubbles: true }));
     115        }
     116    });
     117
     118    // Delegated event for Type Change to toggle Options field AND Update Badge
     119    container.addEventListener('change', function (e) {
     120        if (e.target.classList.contains('mbcore-type-select')) {
     121            const row = e.target.closest('.mbcore-control-body');
     122            const card = e.target.closest('.mbcore-control-item');
     123            const optionsWrapper = row.querySelector('.mbcore-options-wrapper');
     124            const badge = card.querySelector('.mbcore-control-type-badge');
     125            const val = e.target.value;
     126
     127            // Update Badge
     128            if (badge) badge.textContent = val;
     129
     130            // Toggle Options
     131            if (['select', 'radio', 'range', 'checkbox'].includes(val)) {
     132                optionsWrapper.style.display = 'block';
     133            } else {
     134                optionsWrapper.style.display = 'none';
     135            }
     136
     137            // Toggle Repeater Sub Controls
     138            const subWrapper = row.querySelector('.mbcore-sub-controls-wrapper');
     139            if (subWrapper) {
     140                if (val === 'repeater') {
     141                    subWrapper.style.display = 'block';
     142                } else {
     143                    subWrapper.style.display = 'none';
     144                }
     145            }
     146        }
     147    });
     148
     149    // Handle Sub-Control Adding
     150    container.addEventListener('click', function (e) {
     151        if (e.target.classList.contains('mbcore-add-sub-control')) {
     152            e.preventDefault();
     153            const list = e.target.previousElementSibling;
     154            const parentIndex = list.getAttribute('data-parent-index');
     155            const subIndex = list.querySelectorAll('.mbcore-sub-control-item').length;
     156
     157            const subItem = document.createElement('div');
     158            subItem.className = 'mbcore-sub-control-item';
     159            subItem.innerHTML = `
     160                <div class="mbcore-sub-control-row">
     161                    <span class="mbcore-sub-control-handle dashicons dashicons-move"></span>
     162                    <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][label]" placeholder="Label" />
     163                    <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][name]" placeholder="Name" />
     164                    <select name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][type]">
     165                        <option value="string">Text</option>
     166                        <option value="textarea">Text Area</option>
     167                        <option value="image">Image</option>
     168                        <option value="url">URL</option>
     169                        <option value="color">Color</option>
     170                    </select>
     171                    <input type="text" name="mbcore_controls[${parentIndex}][sub_controls][${subIndex}][default]" placeholder="Default" />
     172                    <button type="button" class="button button-link-delete btn-remove-sub">×</button>
     173                </div>
     174            `;
     175            list.appendChild(subItem);
     176        }
     177
     178        // Handle Sub-Control Removing
     179        if (e.target.classList.contains('btn-remove-sub')) {
     180            e.preventDefault();
     181            e.target.closest('.mbcore-sub-control-item').remove();
     182        }
     183    });
     184
     185    // Live Title Update
     186    container.addEventListener('input', function (e) {
     187        if (e.target.classList.contains('mbcore-update-title')) {
     188            const card = e.target.closest('.mbcore-control-item');
     189            const titleSpan = card.querySelector('.mbcore-control-title');
     190            if (titleSpan) titleSpan.textContent = e.target.value || 'New Control';
     191        }
     192    });
     193
     194    // Accordion Toggle and Delete
     195    container.addEventListener('click', function (e) {
     196        // Toggle if clicked header (but not if clicked actions inside header if any)
     197        if (e.target.closest('.mbcore-control-header') && !e.target.closest('.mbcore-control-actions')) {
     198            const card = e.target.closest('.mbcore-control-item');
     199            card.classList.toggle('open');
     200        }
     201
     202        // Delete
     203        if (e.target.classList.contains('btn-remove')) {
     204            e.preventDefault();
     205            if (confirm('Are you sure you want to delete this control?')) {
     206                e.target.closest('.mbcore-control-item').remove();
     207            }
     208        }
     209    });
     210
     211    // Trigger change on all existing selects on load to set initial state
     212    const existingSelects = container.querySelectorAll('.mbcore-type-select');
     213    existingSelects.forEach(sel => {
     214        sel.dispatchEvent(new Event('change', { bubbles: true }));
     215    });
     216
     217    // Bypassing ModSecurity 406 Errors (Base64 Encode on Submit)
     218    const postForm = document.getElementById('post');
     219    if (postForm) {
     220        postForm.addEventListener('submit', function () {
     221            // Helper to encode Unicode correctly
     222            const encodeBase64 = (str) => {
     223                try {
     224                    return 'base64:' + btoa(unescape(encodeURIComponent(str)));
     225                } catch (e) {
     226                    return str;
     227                }
     228            };
     229
     230            const phpArea = document.querySelector('textarea[name="mbcore_render_php"]');
     231            const cssArea = document.querySelector('textarea[name="mbcore_style_css"]');
     232            const jsArea = document.querySelector('textarea[name="mbcore_script_js"]');
     233
     234            if (phpArea && phpArea.value) {
     235                phpArea.value = encodeBase64(phpArea.value);
     236            }
     237            if (cssArea && cssArea.value) {
     238                cssArea.value = encodeBase64(cssArea.value);
     239            }
     240            if (jsArea && jsArea.value) {
     241                jsArea.value = encodeBase64(jsArea.value);
     242            }
     243        });
     244    }
    245245});
  • modular-blocks-core/trunk/modular-blocks-core.php

    r3446531 r3446627  
    33 * Plugin Name: Modular Blocks Core
    44 * Description: A lightweight, custom framework for building dynamic, reusable Gutenberg blocks with minimal overhead.
    5  * Version: 2.2.4
     5 * Version: 2.2.5
    66 * Author: Akrit Singha
    77 * Author URI: https://github.com/akritsingha
     
    2525
    2626// Autoloader or Includes.
    27 require_once MBCORE_PATH . 'includes/class-block-registry.php';
    28 require_once MBCORE_PATH . 'includes/class-cpt-manager.php';
    29 require_once MBCORE_PATH . 'includes/class-admin-ui.php';
     27require_once MBCORE_PATH . 'includes/class-blockregistry.php';
     28require_once MBCORE_PATH . 'includes/class-cptmanager.php';
     29require_once MBCORE_PATH . 'includes/class-adminui.php';
    3030require_once MBCORE_PATH . 'includes/class-compiler.php';
    31 require_once MBCORE_PATH . 'includes/class-import-export.php';
    32 require_once MBCORE_PATH . 'includes/class-block-inheritance.php';
     31require_once MBCORE_PATH . 'includes/class-importexport.php';
     32require_once MBCORE_PATH . 'includes/class-blockinheritance.php';
    3333require_once MBCORE_PATH . 'includes/migration-fix-defaults.php';
    3434
  • modular-blocks-core/trunk/readme.txt

    r3446531 r3446627  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.2.4
     7Stable tag: 2.2.5
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset for help on using the changeset viewer.