Make WordPress Themes

Changeset 357015


Ignore:
Timestamp:
11/03/2026 06:49:35 PM (4 hours ago)
Author:
themedropbox
Message:

New version of Blogger Mag - 0.8

Location:
blogger-mag/0.8
Files:
23 added
1 deleted
15 edited
1 copied

Legend:

Unmodified
Added
Removed
  • blogger-mag/0.8/admin/blogger-mag-admin-plugin-install.php

    r329712 r357015  
    3939                        <?php
    4040                            echo wp_kses_post( sprintf(
     41                                /* translators: 1: Theme Name, 2: Ansar Import link, 3: Theme Name */
    4142                                __(
    42                                     'Thank you for choosing %1$s theme. To take full advantage of the complete features of the theme, click Get Started and install and activate the %2$s & %3$s plugins, then use the demo importer and install the %4$s demo according to your need.',
     43                                    'Thank you for choosing %1$s theme. To take full advantage of the complete features of the theme, click Get Started to install and activate the %2$s plugin, then use the demo importer to import your favorite %3$s starter site (required plugins are handled automatically by Ansar Import).',
    4344                                    'blogger-mag'
    4445                                ),
    45                                 esc_html($theme_info->Name),
    46                                 '<a href="https://wordpress.org/plugins/ansar-import" target="_blank">' . esc_html__('Ansar Import', 'blogger-mag') . '</a>',
    47                                 '<a href="https://wordpress.org/plugins/ansar-elements" target="_blank">' . esc_html__('Ansar Elements', 'blogger-mag') . '</a>',
    48                                 esc_html($theme_info->Name)
     46                                esc_html( $theme_info->Name ),
     47                                '<a href="https://wordpress.org/plugins/ansar-import/" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Ansar Import', 'blogger-mag' ) . '</a>',
     48                                esc_html( $theme_info->Name )
    4949                            ) );
    5050                            ?>
    … …  
    5353                        <div class="panel-column-6">
    5454                            <div class="blogger-mag-notice-buttons">
    55                                 <a class="blogger-mag-btn-get-started button button-primary button-hero blogger-mag-button-padding" href="#" data-name="" data-slug=""><span aria-hidden="true" class="dashicons dashicons-external"></span><?php esc_html_e( 'Get Started', 'blogger-mag' ) ?></a>
    56                                 <a class="blogger-mag-btn-demos button button-secondary button-hero blogger-mag-button-padding" href="<?php echo esc_url('https://themeansar.com/ansar-elements/starter-sites/')?>" data-name="" data-slug=""><span aria-hidden="true" class="dashicons dashicons-images-alt"></span><?php esc_html_e( 'View Demos', 'blogger-mag' ) ?></a>
     55                                <?php if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'ansar-import/ansar-import.php' ) ) : ?>
     56                                    <a class="button button-primary button-hero blogger-mag-button-padding" href="<?php echo esc_url( admin_url( 'admin.php?page=blogger_mag_admin_menu&tab=starter-sites' ) ); ?>"><span aria-hidden="true" class="dashicons dashicons-images-alt"></span><?php esc_html_e( 'Get Started', 'blogger-mag' ); ?></a>
     57                                <?php else : ?>
     58                                    <a class="blogger-mag-btn-get-started button button-primary button-hero blogger-mag-button-padding" href="#" data-name="ansar-import" data-slug="ansar-import"><span aria-hidden="true" class="dashicons dashicons-external"></span><?php esc_html_e( 'Get Started', 'blogger-mag' ); ?></a>
     59                                <?php endif; ?>
     60                                <a class="blogger-mag-btn-demos button button-secondary button-hero blogger-mag-button-padding" href="<?php echo esc_url( admin_url( 'admin.php?page=blogger_mag_admin_menu' ) ); ?>"><span aria-hidden="true" class="dashicons dashicons-dashboard"></span><?php esc_html_e( 'Theme Dashboard', 'blogger-mag' ); ?></a>
    5761                            </div>
    5862                            <div class="blogger-mag-notice-links">
    … …  
    7478                    <div class="blogger-mag-notice_image">
    7579                    <?php
    76                     $image_url = get_theme_file_uri( '/images/notice-img.png' );
     80                    $image_url = get_theme_file_uri( '/images/notice-img.webp' );
    7781                    // Check if the file exists
    78                     if ( file_exists( get_theme_file_path( '/images/notice-img.png' ) ) ) { ?>
     82                    if ( file_exists( get_theme_file_path( '/images/notice-img.webp' ) ) ) { ?>
    7983                        <img class="blogger-mag-screenshot" src="<?php echo esc_url( $image_url ); ?>" alt="<?php esc_attr_e( 'Blogger Mag', 'blogger-mag' ); ?>" />
    8084                    <?php } ?>
    … …  
    106110    include_once ABSPATH . 'wp-admin/includes/plugin.php';
    107111
    108     // List of plugins to install and activate
     112    // Only install and activate ansar-import; demo-specific required plugins are handled by ansar-import.
    109113    $plugins = array(
    110         'elementor' => 'elementor/elementor.php',
    111         'ansar-elements' => 'ansar-elements/ansar-elements.php',
    112114        'ansar-import' => 'ansar-import/ansar-import.php',
    113115    );
    … …  
    138140        if ( current_user_can( 'activate_plugins' ) ) {
    139141            activate_plugin( $main_file );
    140 
    141             // Elementor redirect skip (only once)
    142             if ( 'elementor' === $slug ) {
    143 
    144                 if ( get_option( 'elementor_onboarded' ) ) {
    145                     delete_option( 'elementor_onboarded' );
    146                 }
    147 
    148                 if ( ! get_option( 'blogger_mag_elementor_skip_done', false ) ) {
    149                     delete_transient( 'elementor_activation_redirect' );
    150                     update_option( 'blogger_mag_elementor_skip_done', true );
    151                 }
    152             }
    153142        }
    154143    }
    155144
    156     wp_send_json_success( array( 'message' => __( 'All plugins installed and activated successfully.', 'blogger-mag' ) ) );
     145    wp_send_json_success( array( 'message' => __( 'Ansar Import installed and activated successfully.', 'blogger-mag' ) ) );
    157146}
  • blogger-mag/0.8/admin/css/admin.css

    r330504 r357015  
     1/* ==========================================================================
     2   1. Admin Notice & Customizer Section Styles (Existing)
     3   ========================================================================== */
    14.blogger-mag-notice {
    25  position: relative;
    … …  
    2528  position: relative;
    2629}
    27 .blogger-mag-notice-links>.blogger-mag-videos {
    28     display: none;
     30.blogger-mag-notice-links > .blogger-mag-videos {
     31  display: none;
    2932}
    3033.blogger-mag-notice-content .blogger-mag-notice_image .blogger-mag-screenshot {
    … …  
    3841  line-height: 1.4;
    3942}
    40 .blogger-mag-notice_text .panel-column-6{
     43.blogger-mag-notice_text .panel-column-6 {
    4144  display: flex;
    4245  align-items: center;
    … …  
    4750  margin-top: 16px;
    4851}
    49 .panel-column-6 .blogger-mag-notice-buttons{
     52.panel-column-6 .blogger-mag-notice-buttons {
    5053  display: flex;
    5154  gap: 10px;
    52   /* margin-top: 10px; */
    5355  flex-wrap: wrap;
    5456}
    … …  
    5961  flex-wrap: wrap;
    6062}
    61 .blogger-mag-notice_text .notice p, .notice-title, div.updated p, div.error p, .form-table td .notice p  {padding-right: 25px; font-size: 15px;}
    62 .blogger-mag-notice-link{
    63   display:inline;
     63.blogger-mag-notice_text .notice p,
     64.notice-title,
     65div.updated p,
     66div.error p,
     67.form-table td .notice p {
     68  padding-right: 25px;
     69  font-size: 15px;
     70}
     71.blogger-mag-notice-link {
     72  display: inline;
    6473  color: var(--wp-admin-theme-color);
    6574}
    66 .admin-bar .blogger-mag-btn-get-started, .admin-bar .blogger-mag-btn-demos, .admin-bar .blogger-mag-btn-demos{
     75.admin-bar .blogger-mag-btn-get-started,
     76.admin-bar .blogger-mag-btn-demos {
    6777  display: flex;
    6878  align-items: center;
    … …  
    7080  gap: 5px;
    7181}
    72 .admin-bar .blogger-mag-notice-buttons :is( .blogger-mag-btn-get-started, .blogger-mag-btn-demos) .dashicons{
     82.admin-bar .blogger-mag-notice-buttons :is(.blogger-mag-btn-get-started, .blogger-mag-btn-demos) .dashicons {
    7383  line-height: 1.2;
    7484  color: inherit !important;
    7585}
    7686
    77 #accordion-section-theme_info_section{
     87#accordion-section-theme_info_section {
    7888  display: inherit !important;
    7989}
    80 #accordion-section-theme_info_section button.accordion-trigger{
     90#accordion-section-theme_info_section button.accordion-trigger {
    8191  padding-right: 14px;
    8292}
    83 #accordion-section-theme_info_section .accordion-section-title::after{
     93#accordion-section-theme_info_section .accordion-section-title::after {
    8494  display: none;
    8595}
    86 #accordion-section-theme_info_section .accordion-section-title{
     96#accordion-section-theme_info_section .accordion-section-title {
    8797  border-left-color: var(--wp-admin-theme-color);
    8898  color: var(--wp-admin-theme-color);
    89   pointer-events: none
    90 }
     99  pointer-events: none;
     100}
     101
     102/* ==========================================================================
     103   2. Theme Admin Menu & Dashboard — Timeless Modern Design System
     104   ========================================================================== */
     105:root {
     106  --bm-accent: #2563eb;
     107  --bm-accent-hover: #1d4ed8;
     108  --bm-accent-soft: #eff6ff;
     109  --bm-accent-border: #bfdbfe;
     110  --bm-pro-amber: #d97706;
     111  --bm-pro-soft: #fffbeb;
     112  --bm-heading: #0f172a;
     113  --bm-text: #334155;
     114  --bm-muted: #64748b;
     115  --bm-bg-canvas: #f8fafc;
     116  --bm-bg-surface: #ffffff;
     117  --bm-bg-subtle: #f1f5f9;
     118  --bm-border: #e2e8f0;
     119  --bm-border-hover: #cbd5e1;
     120  --bm-shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.04);
     121  --bm-shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.04), 0 4px 12px rgba(15, 23, 42, 0.03);
     122  --bm-shadow-md: 0 4px 6px -1px rgba(15, 23, 42, 0.05), 0 12px 24px -4px rgba(15, 23, 42, 0.08);
     123  --bm-radius-sm: 8px;
     124  --bm-radius-md: 12px;
     125  --bm-radius-lg: 16px;
     126}
     127
     128#bm-upgrade-menu-item {
     129  color: #fbbf24;
     130  font-weight: 600;
     131}
     132
     133#adminmenu [class*="toplevel_page_"][class*="_admin_menu"] .wp-menu-image.dashicons-before img,
     134#adminmenu [class*="toplevel_page_"][class*="_admin_menu"] .wp-menu-image img {
     135  padding-top: 6px;
     136  width: 20px;
     137  height: 20px;
     138  max-width: 20px;
     139  object-fit: contain;
     140  opacity: 0.95;
     141}
     142
     143/* Full-bleed modern slate canvas on the Theme Dashboard screen */
     144body[class*="toplevel_page_"][class*="_admin_menu"] {
     145  background: var(--bm-bg-canvas);
     146}
     147
     148body[class*="toplevel_page_"][class*="_admin_menu"] #wpcontent {
     149  padding-inline-start: 0;
     150}
     151
     152body[class*="toplevel_page_"][class*="_admin_menu"] #wpbody-content {
     153  padding-bottom: 48px;
     154}
     155
     156#bm-dashboard {
     157  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
     158  font-size: 14.5px;
     159  color: var(--bm-text);
     160  -webkit-font-smoothing: antialiased;
     161  -moz-osx-font-smoothing: grayscale;
     162  box-sizing: border-box;
     163}
     164
     165#bm-dashboard *,
     166#bm-dashboard *::before,
     167#bm-dashboard *::after {
     168  box-sizing: border-box;
     169}
     170
     171#bm-dashboard h1,
     172#bm-dashboard h2,
     173#bm-dashboard h3,
     174#bm-dashboard h4,
     175#bm-dashboard h5,
     176#bm-dashboard h6 {
     177  color: var(--bm-heading);
     178  margin: 0 0 10px 0;
     179  font-weight: 600;
     180  letter-spacing: -0.015em;
     181  line-height: 1.3;
     182}
     183
     184#bm-dashboard p {
     185  font-size: 13.75px;
     186  line-height: 1.65;
     187  color: var(--bm-muted);
     188  margin: 0;
     189}
     190
     191/* --------------------------------------------------------------------------
     192   Buttons
     193   -------------------------------------------------------------------------- */
     194.bm-button {
     195  display: inline-flex;
     196  align-items: center;
     197  justify-content: center;
     198  gap: 8px;
     199  min-height: 38px;
     200  padding: 7px 16px;
     201  font-family: inherit;
     202  font-size: 13px;
     203  font-weight: 500;
     204  line-height: 1.2;
     205  color: var(--bm-heading);
     206  background: #ffffff;
     207  border: 1px solid var(--bm-border);
     208  border-radius: var(--bm-radius-sm);
     209  box-shadow: var(--bm-shadow-xs);
     210  cursor: pointer;
     211  text-decoration: none;
     212  transition: all 0.16s cubic-bezier(0.16, 1, 0.3, 1);
     213}
     214
     215.bm-button:hover,
     216.bm-button:focus {
     217  color: var(--bm-heading);
     218  background: #f8fafc;
     219  border-color: var(--bm-border-hover);
     220  box-shadow: 0 2px 5px rgba(15, 23, 42, 0.06);
     221  outline: none;
     222}
     223
     224.bm-button-primary {
     225  color: #ffffff;
     226  background: var(--bm-accent);
     227  border-color: var(--bm-accent);
     228  box-shadow: 0 1px 2px rgba(37, 99, 235, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.15);
     229}
     230
     231.bm-button-primary:hover,
     232.bm-button-primary:focus {
     233  color: #ffffff;
     234  background: var(--bm-accent-hover);
     235  border-color: var(--bm-accent-hover);
     236  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.28);
     237  transform: translateY(-1px);
     238}
     239
     240.bm-button-pro {
     241  width: 100%;
     242  color: #0f172a;
     243  background: linear-gradient(180deg, #fcd34d 0%, #fbbf24 100%);
     244  border-color: #f59e0b;
     245  font-weight: 600;
     246  min-height: 42px;
     247  box-shadow: 0 2px 8px rgba(245, 158, 11, 0.25);
     248}
     249
     250.bm-button-pro:hover,
     251.bm-button-pro:focus {
     252  color: #0f172a;
     253  background: linear-gradient(180deg, #fbbf24 0%, #f59e0b 100%);
     254  border-color: #d97706;
     255  transform: translateY(-1px);
     256}
     257
     258.bm-button-sm {
     259  min-height: 34px;
     260  padding: 5px 13px;
     261  font-size: 12.5px;
     262}
     263
     264.bm-button-lg {
     265  min-height: 42px;
     266  padding: 9px 20px;
     267  font-size: 13.75px;
     268  font-weight: 600;
     269}
     270
     271.bm-button[disabled],
     272.bm-button.btn-disabled {
     273  opacity: 0.65;
     274  pointer-events: none;
     275  background: #f1f5f9;
     276  color: #64748b;
     277  border-color: #e2e8f0;
     278  box-shadow: none;
     279  transform: none;
     280}
     281
     282/* --------------------------------------------------------------------------
     283   Compact Sticky Single-Bar Header (`.bm-dashboard-header`)
     284   -------------------------------------------------------------------------- */
     285.bm-dashboard-header {
     286  position: sticky;
     287  top: 32px;
     288  z-index: 40;
     289  background: rgba(255, 255, 255, 0.88);
     290  backdrop-filter: saturate(180%) blur(14px);
     291  -webkit-backdrop-filter: saturate(180%) blur(14px);
     292  border-bottom: 1px solid var(--bm-border);
     293  padding: 0 28px;
     294}
     295
     296.bm-header-inner {
     297  max-width: 1280px;
     298  min-height: 64px;
     299  margin: 0 auto;
     300  display: flex;
     301  align-items: center;
     302  justify-content: space-between;
     303  gap: 20px;
     304  .bm-dashboard-navigation{
     305    li:has(#bm-tab-compare, #bm-tab-change-log){
     306      display: none;
     307    }
     308  }
     309  .bm-header-quick-links .bm-button{
     310    display: none;
     311  }
     312}
     313
     314.bm-header-brand {
     315  display: flex;
     316  align-items: center;
     317  gap: 10px;
     318  flex-shrink: 0;
     319}
     320
     321.bm-brand-link {
     322  display: inline-flex;
     323  align-items: center;
     324  gap: 10px;
     325  text-decoration: none;
     326  color: var(--bm-heading);
     327  font-weight: 700;
     328  font-size: 15.5px;
     329  letter-spacing: -0.02em;
     330}
     331
     332.bm-brand-link:focus {
     333  outline: none;
     334  box-shadow: none;
     335}
     336
     337.bm-brand-logo {
     338  display: inline-flex;
     339  align-items: center;
     340  justify-content: center;
     341  color: var(--bm-accent);
     342}
     343
     344.bm-brand-logo svg,
     345.bm-brand-logo img {
     346  width: 28px;
     347  height: 28px;
     348  display: block;
     349  object-fit: contain;
     350}
     351
     352.bm-version-pill {
     353  display: inline-flex;
     354  align-items: center;
     355  gap: 6px;
     356  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
     357  font-size: 11px;
     358  font-weight: 600;
     359  font-variant-numeric: tabular-nums;
     360  line-height: 1;
     361  color: #475569;
     362  background: linear-gradient(180deg, #ffffff 0%, #f1f5f9 100%);
     363  border: 1px solid #cbd5e1;
     364  padding: 4px 9px 4px 7px;
     365  border-radius: 999px;
     366  letter-spacing: -0.01em;
     367  text-decoration: none;
     368  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.85);
     369  transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1);
     370}
     371
     372.bm-version-pill:hover,
     373.bm-version-pill:focus {
     374  color: var(--bm-accent);
     375  background: var(--bm-accent-soft);
     376  border-color: var(--bm-accent-border);
     377  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.12);
     378  transform: translateY(-0.5px);
     379  outline: none;
     380}
     381
     382.bm-version-dot {
     383  width: 6px;
     384  height: 6px;
     385  border-radius: 50%;
     386  background: #10b981;
     387  box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.18);
     388  flex-shrink: 0;
     389  transition: background-color 0.18s ease, box-shadow 0.18s ease;
     390}
     391
     392.bm-version-pill:hover .bm-version-dot,
     393.bm-version-pill:focus .bm-version-dot {
     394  background: var(--bm-accent);
     395  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.2);
     396}
     397
     398.bm-version-label {
     399  display: inline-block;
     400}
     401
     402/* Center Segmented/Underline Tab Bar inside Compact Header */
     403.bm-dashboard-navigation {
     404  display: flex;
     405  align-items: center;
     406  list-style: none;
     407  margin: 0;
     408  padding: 0;
     409  gap: 4px;
     410}
     411
     412.bm-dashboard-navigation li {
     413  margin: 0;
     414}
     415
     416.bm-dashboard-navigation .bm-nav-tab {
     417  position: relative;
     418  display: inline-flex;
     419  align-items: center;
     420  justify-content: center;
     421  gap: 7px;
     422  padding: 6px 14px;
     423  color: var(--bm-muted);
     424  font-size: 13.5px;
     425  font-weight: 500;
     426  text-decoration: none;
     427  box-shadow: none;
     428  outline: none;
     429  transition: color 0.16s ease;
     430  border-radius: var(--bm-radius-sm);
     431}
     432
     433.bm-dashboard-navigation .bm-nav-tab:hover:not(.is-active) {
     434  color: var(--bm-heading);
     435}
     436
     437.bm-dashboard-navigation .bm-nav-tab.is-active,
     438.bm-dashboard-navigation .bm-nav-tab[aria-current="page"] {
     439  background: var(--bm-accent-soft);
     440  color: var(--bm-accent);
     441  font-weight: 600;
     442}
     443
     444.bm-dashboard-navigation .bm-nav-tab.is-active::after,
     445.bm-dashboard-navigation .bm-nav-tab[aria-current="page"]::after {
     446  background: var(--bm-accent);
     447}
     448
     449.bm-tab-icon {
     450  display: inline-flex;
     451  align-items: center;
     452  opacity: 0.85;
     453}
     454
     455.bm-dashboard-navigation .bm-nav-tab.is-active .bm-tab-icon {
     456  opacity: 1;
     457}
     458
     459.bm-header-quick-links {
     460  display: flex;
     461  align-items: center;
     462  gap: 8px;
     463  flex-shrink: 0;
     464}
     465
     466.bm-header-link {
     467  display: inline-flex;
     468  align-items: center;
     469  gap: 6px;
     470  padding: 6px 11px;
     471  border-radius: var(--bm-radius-sm);
     472  border: 1px solid var(--bm-border);
     473  font-size: 12.75px;
     474  font-weight: 500;
     475  color: var(--bm-text);
     476  text-decoration: none;
     477  transition: background 0.15s ease, color 0.15s ease;
     478}
     479
     480.bm-header-link:hover {
     481  background: var(--bm-bg-subtle);
     482  color: var(--bm-heading);
     483}
     484
     485.bm-header-cta {
     486  margin-inline-start: 4px;
     487}
     488
     489/* --------------------------------------------------------------------------
     490   Main Layout & Grid
     491   -------------------------------------------------------------------------- */
     492.bm-dashboard-main {
     493  max-width: 1280px;
     494  margin: 0 auto;
     495  padding: 36px 28px 64px;
     496}
     497
     498.bm-tab-panel[hidden] {
     499  display: none !important;
     500}
     501
     502.bm-dashboard-grid {
     503  display: grid;
     504  gap: 28px;
     505  align-items: start;
     506}
     507
     508@media (min-width: 1024px) {
     509  .bm-dashboard-grid[data-columns="2"] {
     510    grid-template-columns: minmax(0, 1fr) 330px;
     511  }
     512}
     513
     514.bm-dashboard-primary {
     515  display: flex;
     516  flex-direction: column;
     517  gap: 40px;
     518  min-width: 0;
     519}
     520
     521/* --------------------------------------------------------------------------
     522   Welcome Hero Card — Modern Editorial Banner
     523   -------------------------------------------------------------------------- */
     524.bm-welcome-hero {
     525  position: relative;
     526  display: grid;
     527  gap: 28px;
     528  padding: 32px;
     529  background:
     530    radial-gradient(circle at 0% 0%, rgba(37, 99, 235, 0.06) 0%, transparent 50%),
     531    radial-gradient(circle at 100% 100%, rgba(99, 102, 241, 0.05) 0%, transparent 50%),
     532    #ffffff;
     533  border: 1px solid var(--bm-border);
     534  border-radius: var(--bm-radius-lg);
     535  align-items: center;
     536  box-shadow: var(--bm-shadow-sm);
     537}
     538
     539@media (min-width: 783px) {
     540  .bm-welcome-hero {
     541    grid-template-columns: 1.15fr 0.85fr;
     542  }
     543}
     544
     545.bm-welcome-eyebrow {
     546  margin-bottom: 12px;
     547}
     548
     549.bm-greeting-badge {
     550  display: inline-flex;
     551  align-items: center;
     552  gap: 7px;
     553  font-size: 11.5px;
     554  font-weight: 600;
     555  color: var(--bm-accent);
     556  background: var(--bm-accent-soft);
     557  border: 1px solid var(--bm-accent-border);
     558  padding: 4px 12px;
     559  border-radius: 999px;
     560  text-decoration: none;
     561  transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1);
     562}
     563
     564.bm-greeting-badge[hidden] {
     565  display: none !important;
     566}
     567
     568.bm-greeting-badge.is-setup-badge {
     569  color: #b45309;
     570  background: #fffbeb;
     571  border-color: #fde68a;
     572  box-shadow: 0 1px 2px rgba(180, 83, 9, 0.05);
     573}
     574
     575.bm-greeting-step-dot {
     576  width: 6px;
     577  height: 6px;
     578  border-radius: 50%;
     579  background: #f59e0b;
     580  box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.22);
     581  flex-shrink: 0;
     582}
     583
     584.bm-greeting-badge.is-edition-badge:hover,
     585.bm-greeting-badge.is-edition-badge:focus {
     586  color: var(--bm-accent-hover);
     587  background: #dbeafe;
     588  border-color: #93c5fd;
     589  transform: translateY(-0.5px);
     590  outline: none;
     591}
     592
     593.bm-greeting-badge.is-pro-edition {
     594  color: #065f46;
     595  background: #ecfdf5;
     596  border-color: #a7f3d0;
     597}
     598
     599.bm-greeting-badge-cta {
     600  padding-inline-start: 7px;
     601  margin-inline-start: 2px;
     602  border-inline-start: 1px solid rgba(37, 99, 235, 0.22);
     603  color: var(--bm-accent-hover);
     604  font-weight: 600;
     605  display: none;
     606}
     607
     608.bm-greeting-badge svg {
     609  width: 13px;
     610  height: 13px;
     611  flex-shrink: 0;
     612}
     613
     614.bm-welcome-title {
     615  font-size: 24px;
     616  font-weight: 700 !important;
     617  margin-bottom: 10px !important;
     618}
     619
     620.bm-welcome-desc {
     621  font-size: 14px !important;
     622  margin-bottom: 24px !important;
     623  color: var(--bm-text) !important;
     624  max-width: 540px;
     625}
     626
     627.bm-welcome-actions {
     628  display: flex;
     629  flex-wrap: wrap;
     630  gap: 10px;
     631}
     632
     633.bm-video-frame,
     634.bm-img-frame {
     635  padding: 6px;
     636  background: var(--bm-bg-subtle);
     637  border: 1px solid var(--bm-border);
     638  border-radius: var(--bm-radius-md);
     639  box-shadow: var(--bm-shadow-xs);
     640}
     641
     642.bm-img-frame img {
     643  display: block;
     644  width: 100%;
     645  height: auto;
     646  border-radius: var(--bm-radius-sm);
     647  object-fit: cover;
     648}
     649
     650.bm-video-frame iframe {
     651  display: block;
     652  width: 100%;
     653  height: 205px;
     654  border: 0;
     655  border-radius: var(--bm-radius-sm);
     656  background: #0f172a;
     657}
     658
     659/* --------------------------------------------------------------------------
     660   Section Headers & Segmented Filter Pills
     661   -------------------------------------------------------------------------- */
     662.bm-section-header {
     663  display: flex;
     664  flex-wrap: wrap;
     665  align-items: center;
     666  justify-content: space-between;
     667  gap: 16px;
     668  margin-bottom: 20px;
     669}
     670
     671.bm-section-title {
     672  font-size: 17px;
     673  font-weight: 700 !important;
     674  margin-bottom: 3px !important;
     675}
     676
     677.bm-section-subtitle {
     678  font-size: 13.5px;
     679}
     680
     681/* --------------------------------------------------------------------------
     682   Customizer Shortcut Cards (Free / Core Theme Controls)
     683   -------------------------------------------------------------------------- */
     684.bm-shortcuts-grid {
     685  display: grid;
     686  gap: 14px;
     687  list-style: none;
     688  margin: 0;
     689  padding: 0;
     690}
     691
     692@media (min-width: 600px) {
     693  .bm-shortcuts-grid {
     694    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
     695  }
     696}
     697
     698.bm-shortcut-card {
     699  display: flex;
     700  flex-direction: column;
     701  margin: 0;
     702  padding: 16px 18px;
     703  background: #ffffff;
     704  border-radius: var(--bm-radius-md);
     705  border: 1px solid var(--bm-border);
     706  box-shadow: var(--bm-shadow-xs);
     707  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.18s ease, border-color 0.18s ease;
     708}
     709
     710.bm-shortcut-card:hover {
     711  border-color: var(--bm-border-hover);
     712  box-shadow: var(--bm-shadow-md);
     713  transform: translateY(-2px);
     714}
     715
     716.bm-shortcut-card.is-pro-card {
     717  border-color: rgba(217, 119, 6, 0.22);
     718}
     719
     720.bm-shortcut-card-top {
     721  display: flex;
     722  align-items: center;
     723  justify-content: space-between;
     724  gap: 10px;
     725  margin-bottom: 10px;
     726}
     727
     728.bm-card-icon-badge {
     729  display: inline-flex;
     730  align-items: center;
     731  justify-content: center;
     732  width: 30px;
     733  height: 30px;
     734  border-radius: 8px;
     735  background: var(--bm-accent-soft);
     736  color: var(--bm-accent);
     737}
     738
     739.bm-card-icon-badge.is-free {
     740  background: var(--bm-accent-soft);
     741  color: var(--bm-accent);
     742}
     743
     744.bm-card-icon-badge.is-pro {
     745  background: var(--bm-pro-soft);
     746  color: var(--bm-pro-amber);
     747}
     748
     749.bm-card-icon-badge svg {
     750  width: 14px;
     751  height: 14px;
     752}
     753
     754.bm-badge {
     755  display: inline-flex;
     756  align-items: center;
     757  padding: 2px 7px;
     758  font-size: 10px;
     759  font-weight: 600;
     760  border-radius: 99px;
     761  text-transform: uppercase;
     762  letter-spacing: 0.04em;
     763  flex-shrink: 0;
     764}
     765
     766.bm-badge-free {
     767  background: #f1f5f9;
     768  color: #475569;
     769}
     770
     771.bm-badge-pro {
     772  background: #fef3c7;
     773  color: #b45309;
     774}
     775
     776.bm-shortcut-title {
     777  font-size: 14px;
     778  font-weight: 600 !important;
     779  margin: 0 0 12px 0 !important;
     780  color: var(--bm-heading);
     781  line-height: 1.35;
     782}
     783
     784.bm-shortcut-actions {
     785  display: flex;
     786  align-items: center;
     787  justify-content: space-between;
     788  gap: 10px;
     789  padding-top: 10px;
     790  border-top: 1px solid #f1f5f9;
     791  margin-top: auto;
     792}
     793
     794.bm-shortcut-link {
     795  display: inline-flex;
     796  align-items: center;
     797  gap: 5px;
     798  font-size: 12.5px;
     799  font-weight: 500;
     800  color: var(--bm-muted);
     801  text-decoration: none;
     802  transition: color 0.15s ease;
     803}
     804
     805.bm-shortcut-link svg {
     806  transition: transform 0.16s ease;
     807}
     808
     809.bm-shortcut-link:hover {
     810  color: var(--bm-heading);
     811}
     812
     813.bm-shortcut-link.bm-link-customize {
     814  color: var(--bm-accent);
     815  font-weight: 600;
     816}
     817
     818.bm-shortcut-link.bm-link-customize:hover svg,
     819.bm-shortcut-link.bm-link-pro:hover svg {
     820  transform: translateX(3px);
     821}
     822
     823.bm-shortcut-link.bm-link-pro {
     824  color: var(--bm-pro-amber);
     825  font-weight: 600;
     826}
     827
     828/* --------------------------------------------------------------------------
     829   Companion Plugin Cards
     830   -------------------------------------------------------------------------- */
     831.bm-plugins-grid {
     832  display: grid;
     833  gap: 20px;
     834  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
     835}
     836
     837.bm-plugin-card {
     838  display: flex;
     839  flex-direction: column;
     840  padding: 22px;
     841  background: #ffffff;
     842  border-radius: var(--bm-radius-md);
     843  border: 1px solid var(--bm-border);
     844  box-shadow: var(--bm-shadow-xs);
     845  transition: box-shadow 0.18s ease, border-color 0.18s ease;
     846}
     847
     848.bm-plugin-card[hidden] {
     849  display: none !important;
     850}
     851
     852.bm-plugin-card:hover {
     853  border-color: var(--bm-border-hover);
     854  box-shadow: var(--bm-shadow-md);
     855}
     856
     857.bm-plugin-card-head {
     858  display: flex;
     859  align-items: flex-start;
     860  gap: 14px;
     861  margin-bottom: 12px;
     862}
     863
     864.bm-plugin-icon {
     865  flex: 0 0 48px;
     866  width: 48px;
     867  height: 48px;
     868  border-radius: 10px;
     869  overflow: hidden;
     870  border: 1px solid var(--bm-border);
     871  background: #f8fafc;
     872  display: flex;
     873  align-items: center;
     874  justify-content: center;
     875}
     876
     877.bm-plugin-icon img {
     878  width: 100%;
     879  height: 100%;
     880  object-fit: cover;
     881}
     882
     883.bm-plugin-heading {
     884  flex: 1;
     885  min-width: 0;
     886}
     887
     888.bm-plugin-title-row {
     889  display: flex;
     890  flex-direction: column;
     891  align-items: flex-start;
     892  gap: 5px;
     893}
     894
     895.bm-plugin-title-row h4 {
     896  font-size: 14.5px;
     897  margin: 0 !important;
     898  line-height: 1.35;
     899}
     900
     901.bm-plugin-status-pill {
     902  font-size: 10.5px;
     903  font-weight: 600;
     904  padding: 2px 8px;
     905  border-radius: 99px;
     906}
     907
     908.bm-plugin-status-pill.is-install {
     909  background: #f1f5f9;
     910  color: #64748b;
     911}
     912
     913.bm-plugin-status-pill.is-activate {
     914  background: #fef3c7;
     915  color: #b45309;
     916}
     917
     918.bm-plugin-status-pill.is-activated {
     919  background: #dcfce7;
     920  color: #15803d;
     921}
     922
     923.bm-plugin-description {
     924  font-size: 13px !important;
     925  line-height: 1.6 !important;
     926  margin-bottom: 18px !important;
     927  flex: 1;
     928}
     929
     930.bm-plugin-actions {
     931  display: flex;
     932  align-items: center;
     933  justify-content: space-between;
     934  gap: 12px;
     935  padding-top: 14px;
     936  border-top: 1px solid #f1f5f9;
     937  margin-top: auto;
     938}
     939
     940.bm-more-detail-link {
     941  display: inline-flex;
     942  align-items: center;
     943  gap: 4px;
     944  font-size: 12.5px;
     945  font-weight: 500;
     946  color: var(--bm-muted);
     947  text-decoration: none;
     948}
     949
     950.bm-more-detail-link:hover {
     951  color: var(--bm-accent);
     952}
     953
     954/* --------------------------------------------------------------------------
     955   Right Sidebar — Pro Spotlight + Modern Resource Card Stack
     956   -------------------------------------------------------------------------- */
     957.bm-dashboard-sidebar {
     958  display: flex;
     959  flex-direction: column;
     960  gap: 16px;
     961  position: sticky;
     962  top: 112px;
     963}
     964
     965.bm-pro-sidebar-card {
     966  display: none;
     967  position: relative;
     968  overflow: hidden;
     969  padding: 24px;
     970  background:
     971    radial-gradient(circle at 100% 0%, rgba(59, 130, 246, 0.28) 0%, transparent 55%),
     972    linear-gradient(160deg, #0f172a 0%, #1e293b 100%);
     973  color: #ffffff;
     974  border-radius: var(--bm-radius-md);
     975  box-shadow: var(--bm-shadow-md);
     976}
     977
     978.bm-pro-sidebar-head {
     979  margin-bottom: 10px;
     980}
     981
     982.bm-pro-pill {
     983  display: inline-flex;
     984  align-items: center;
     985  gap: 5px;
     986  background: rgba(251, 191, 36, 0.16);
     987  border: 1px solid rgba(251, 191, 36, 0.35);
     988  color: #fbbf24;
     989  font-size: 10.5px;
     990  font-weight: 700;
     991  padding: 3px 9px;
     992  border-radius: 99px;
     993  letter-spacing: 0.05em;
     994}
     995
     996.bm-pro-sidebar-title {
     997  color: #ffffff !important;
     998  font-size: 17px;
     999  margin-bottom: 8px !important;
     1000}
     1001
     1002.bm-pro-sidebar-desc {
     1003  color: #94a3b8 !important;
     1004  font-size: 13px !important;
     1005  margin-bottom: 16px !important;
     1006}
     1007
     1008.bm-pro-perks {
     1009  list-style: none;
     1010  margin: 0 0 20px 0;
     1011  padding: 0;
     1012  display: flex;
     1013  flex-direction: column;
     1014  gap: 8px;
     1015}
     1016
     1017.bm-pro-perks li {
     1018  display: flex;
     1019  align-items: center;
     1020  gap: 8px;
     1021  margin: 0;
     1022  font-size: 12.75px;
     1023  color: #e2e8f0;
     1024}
     1025
     1026.bm-pro-perks .dashicons {
     1027  color: #34d399;
     1028  font-size: 17px;
     1029  width: 17px;
     1030  height: 17px;
     1031}
     1032
     1033.bm-resources-stack {
     1034  display: flex;
     1035  flex-direction: column;
     1036  gap: 12px;
     1037}
     1038
     1039.bm-resource-card {
     1040  padding: 18px 20px;
     1041  background: #ffffff;
     1042  border: 1px solid var(--bm-border);
     1043  border-radius: var(--bm-radius-md);
     1044  box-shadow: var(--bm-shadow-xs);
     1045  transition: border-color 0.16s ease, box-shadow 0.16s ease;
     1046}
     1047
     1048.bm-resource-card:hover {
     1049  border-color: var(--bm-border-hover);
     1050  box-shadow: var(--bm-shadow-sm);
     1051}
     1052
     1053.bm-resource-head {
     1054  display: flex;
     1055  align-items: center;
     1056  gap: 10px;
     1057  margin-bottom: 8px;
     1058}
     1059
     1060.bm-resource-head h4 {
     1061  font-size: 14px;
     1062  margin: 0 !important;
     1063}
     1064
     1065.bm-resource-icon {
     1066  display: inline-flex;
     1067  align-items: center;
     1068  justify-content: center;
     1069  width: 30px;
     1070  height: 30px;
     1071  flex: 0 0 30px;
     1072  border-radius: 8px;
     1073  background: var(--bm-accent-soft);
     1074  color: var(--bm-accent);
     1075}
     1076
     1077.bm-resource-card[data-resource="rate_us"] .bm-resource-icon {
     1078  background: #fef3c7;
     1079  color: #d97706;
     1080}
     1081
     1082.bm-resource-card p {
     1083  font-size: 12.75px !important;
     1084  line-height: 1.55 !important;
     1085  margin-bottom: 12px !important;
     1086}
     1087
     1088.bm-resource-link {
     1089  display: inline-flex;
     1090  align-items: center;
     1091  gap: 5px;
     1092  font-size: 12.5px;
     1093  font-weight: 600;
     1094  color: var(--bm-accent);
     1095  text-decoration: none;
     1096}
     1097
     1098.bm-resource-link svg {
     1099  transition: transform 0.16s ease;
     1100}
     1101
     1102.bm-resource-link:hover svg {
     1103  transform: translateX(3px);
     1104}
     1105
     1106/* --------------------------------------------------------------------------
     1107   Free vs Pro Comparison Table
     1108   -------------------------------------------------------------------------- */
     1109.bm-cta-banner-small {
     1110  display: flex;
     1111  flex-wrap: wrap;
     1112  align-items: center;
     1113  justify-content: space-between;
     1114  gap: 20px;
     1115  padding: 22px 26px;
     1116  margin-bottom: 24px;
     1117  background: #ffffff;
     1118  border: 1px solid var(--bm-border);
     1119  border-radius: var(--bm-radius-md);
     1120  box-shadow: var(--bm-shadow-xs);
     1121}
     1122
     1123.bm-cta-banner-small h2 {
     1124  font-size: 16.5px;
     1125  margin-bottom: 4px !important;
     1126}
     1127
     1128.bm-comparison-table ul {
     1129  list-style: none;
     1130  margin: 0;
     1131  padding: 0;
     1132  border: 1px solid var(--bm-border);
     1133  border-radius: var(--bm-radius-md);
     1134  background: #ffffff;
     1135  overflow: hidden;
     1136  box-shadow: var(--bm-shadow-xs);
     1137}
     1138
     1139.bm-comparison-table ul li {
     1140  display: grid;
     1141  grid-template-columns: 3fr 1fr 1fr;
     1142  align-items: center;
     1143  padding: 14px 22px;
     1144  font-size: 13.75px;
     1145  margin: 0;
     1146}
     1147
     1148.bm-comparison-table ul li:not(:first-child) {
     1149  border-bottom: 1px solid #f1f5f9;
     1150}
     1151
     1152.bm-comparison-table ul li:not(.bm-table-heading):hover {
     1153  background: #f8fafc;
     1154}
     1155
     1156.bm-comparison-table ul li:last-child {
     1157  border-bottom: 0;
     1158}
     1159
     1160.bm-comparison-table ul li > span {
     1161  text-align: center;
     1162}
     1163
     1164.bm-comparison-table ul li > span:first-child {
     1165  text-align: start;
     1166  font-weight: 500;
     1167  color: var(--bm-heading);
     1168}
     1169
     1170.bm-comparison-table .bm-table-heading {
     1171  color: var(--bm-heading);
     1172  font-size: 13px;
     1173  font-weight: 700;
     1174  text-transform: uppercase;
     1175  letter-spacing: 0.04em;
     1176  background: #f8fafc;
     1177  border-bottom: 1px solid var(--bm-border);
     1178}
     1179
     1180.bm-comparison-table .bm-col-pro {
     1181  color: var(--bm-accent);
     1182}
     1183
     1184.bm-comparison-table .bm-icon-yes {
     1185  color: #16a34a;
     1186  font-size: 20px;
     1187  width: 20px;
     1188  height: 20px;
     1189}
     1190
     1191.bm-comparison-table .bm-icon-no {
     1192  color: #cbd5e1;
     1193  font-size: 20px;
     1194  width: 20px;
     1195  height: 20px;
     1196}
     1197
     1198.bm-feature-text {
     1199  font-size: 12px;
     1200  color: var(--bm-muted);
     1201  background: #f1f5f9;
     1202  padding: 2px 8px;
     1203  border-radius: 99px;
     1204}
     1205
     1206.bm-feature-text.is-pro {
     1207  color: var(--bm-accent);
     1208  background: var(--bm-accent-soft);
     1209}
     1210
     1211.bm-comparison-footer {
     1212  margin-top: 28px;
     1213  padding: 32px;
     1214  text-align: center;
     1215  background: #ffffff;
     1216  border: 1px solid var(--bm-border);
     1217  border-radius: var(--bm-radius-md);
     1218  box-shadow: var(--bm-shadow-xs);
     1219}
     1220
     1221.bm-comparison-footer p {
     1222  max-width: 520px;
     1223  margin: 0 auto 18px !important;
     1224}
     1225
     1226/* --------------------------------------------------------------------------
     1227   Changelog Tab
     1228   -------------------------------------------------------------------------- */
     1229.bm-changelog-wrapper {
     1230  background: #ffffff;
     1231  border: 1px solid var(--bm-border);
     1232  border-radius: var(--bm-radius-md);
     1233  padding: 28px 32px;
     1234  box-shadow: var(--bm-shadow-xs);
     1235}
     1236
     1237.bm-changelog-info {
     1238  display: flex;
     1239  flex-wrap: wrap;
     1240  align-items: center;
     1241  justify-content: space-between;
     1242  gap: 16px;
     1243  padding-bottom: 20px;
     1244  margin-bottom: 28px;
     1245  border-bottom: 1px solid var(--bm-border);
     1246}
     1247
     1248.bm-changelog-explanation {
     1249  display: flex;
     1250  align-items: center;
     1251  gap: 18px;
     1252  list-style: none;
     1253  margin: 0;
     1254  padding: 0;
     1255  font-size: 13px;
     1256  font-weight: 500;
     1257}
     1258
     1259.bm-changelog-explanation li {
     1260  display: inline-flex;
     1261  align-items: center;
     1262  gap: 7px;
     1263  margin: 0;
     1264}
     1265
     1266.bm-cl-badge {
     1267  display: inline-flex;
     1268  align-items: center;
     1269  justify-content: center;
     1270  width: 20px;
     1271  height: 20px;
     1272  flex: 0 0 20px;
     1273  border-radius: 6px;
     1274}
     1275
     1276.bm-cl-badge::before {
     1277  font-size: 10px;
     1278  font-weight: 700;
     1279}
     1280
     1281.bm-cl-badge.new {
     1282  background: #dcfce7;
     1283  color: #15803d;
     1284}
     1285.bm-cl-badge.new::before {
     1286  content: "N";
     1287}
     1288
     1289.bm-cl-badge.fix {
     1290  background: var(--bm-accent-soft);
     1291  color: var(--bm-accent);
     1292}
     1293.bm-cl-badge.fix::before {
     1294  content: "F";
     1295}
     1296
     1297.bm-cl-badge.improvement {
     1298  background: #fef3c7;
     1299  color: #b45309;
     1300}
     1301.bm-cl-badge.improvement::before {
     1302  content: "I";
     1303}
     1304
     1305.bm-changelog-release:not(:last-of-type) {
     1306  margin-bottom: 28px;
     1307  padding-bottom: 28px;
     1308  border-bottom: 1px solid #f1f5f9;
     1309}
     1310
     1311.bm-changelog-release h2 {
     1312  display: flex;
     1313  align-items: center;
     1314  justify-content: space-between;
     1315  font-size: 16px;
     1316  margin-bottom: 14px !important;
     1317}
     1318
     1319.bm-release-date {
     1320  font-size: 12.5px;
     1321  font-weight: 400;
     1322  color: var(--bm-muted);
     1323}
     1324
     1325.bm-release-changes {
     1326  list-style: none;
     1327  margin: 0;
     1328  padding: 0;
     1329}
     1330
     1331.bm-release-changes li {
     1332  display: flex;
     1333  align-items: flex-start;
     1334  gap: 10px;
     1335  margin-bottom: 10px;
     1336  line-height: 1.5;
     1337  font-size: 13.75px;
     1338  color: var(--bm-text);
     1339}
     1340
     1341.bm-release-changes li:last-child {
     1342  margin-bottom: 0;
     1343}
     1344
     1345/* --------------------------------------------------------------------------
     1346   Dynamic Action Button (.bm-editor-action-btn)
     1347   -------------------------------------------------------------------------- */
     1348.bm-editor-action-btn {
     1349  transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1);
     1350}
     1351
     1352.bm-editor-action-btn .bm-btn-icon {
     1353  display: inline-flex;
     1354  align-items: center;
     1355  justify-content: center;
     1356  line-height: 1;
     1357}
     1358
     1359.bm-editor-action-btn .bm-btn-icon svg {
     1360  display: block;
     1361}
     1362
     1363/* --------------------------------------------------------------------------
     1364   Starter Sites Tab & Modal
     1365   -------------------------------------------------------------------------- */
     1366.bm-modal-main {
     1367  position: relative;
     1368  border-radius: var(--bm-radius-lg);
     1369  overflow: hidden;
     1370  border: 1px solid var(--bm-border);
     1371  min-height: 440px;
     1372  background: #ffffff;
     1373}
     1374
     1375.bm-modal-main .bm-modal-image.overlay {
     1376  filter: blur(6px);
     1377  position: relative;
     1378}
     1379
     1380.bm-modal-main .bm-modal-image.overlay::after {
     1381  content: "";
     1382  position: absolute;
     1383  inset: 0;
     1384  background: rgba(248, 250, 252, 0.55);
     1385}
     1386
     1387.bm-modal-main .bm-modal-image img {
     1388  width: 100%;
     1389  display: block;
     1390}
     1391
     1392.bm-modal-popup {
     1393  position: absolute;
     1394  top: 50%;
     1395  left: 50%;
     1396  transform: translate(-50%, -50%);
     1397  width: 92%;
     1398  max-width: 500px;
     1399  z-index: 2;
     1400}
     1401
     1402.bm-modal-popup-content {
     1403  background: rgba(255, 255, 255, 0.95);
     1404  backdrop-filter: blur(18px);
     1405  padding: 38px 32px;
     1406  border-radius: var(--bm-radius-lg);
     1407  border: 1px solid var(--bm-border);
     1408  box-shadow: var(--bm-shadow-md);
     1409  text-align: center;
     1410}
     1411
     1412.bm-modal-icon img {
     1413  width: 56px;
     1414  height: auto;
     1415  margin-bottom: 14px;
     1416}
     1417
     1418.bm-modal-popup-content h4 {
     1419  font-size: 20px;
     1420  margin-bottom: 10px !important;
     1421}
     1422
     1423.bm-modal-popup-content p {
     1424  margin-bottom: 22px !important;
     1425  color: var(--bm-text) !important;
     1426}
     1427
     1428.bm-modal-actions {
     1429  display: flex;
     1430  flex-wrap: wrap;
     1431  justify-content: center;
     1432  gap: 10px;
     1433}
     1434
     1435/* Responsive adjustments */
     1436@media (max-width: 960px) {
     1437  .bm-dashboard-header {
     1438    position: static;
     1439    padding: 12px 16px 0;
     1440  }
     1441  .bm-header-inner {
     1442    flex-wrap: wrap;
     1443    min-height: auto;
     1444    gap: 12px;
     1445  }
     1446  .bm-dashboard-navigation {
     1447    order: 3;
     1448    width: 100%;
     1449    overflow-x: auto;
     1450    border-top: 1px solid var(--bm-border);
     1451  }
     1452  .bm-dashboard-navigation .bm-nav-tab {
     1453    height: 46px;
     1454    white-space: nowrap;
     1455  }
     1456}
     1457
     1458@media (max-width: 782px) {
     1459  .bm-dashboard-main {
     1460    padding: 24px 16px 48px;
     1461  }
     1462  .bm-comparison-table ul li {
     1463    grid-template-columns: 2fr 1fr 1fr;
     1464    padding: 12px 14px;
     1465  }
     1466}
  • blogger-mag/0.8/admin/js/blogger-mag-admin-script.js

    r329712 r357015  
    11(function ($) {
     2  'use strict';
     3
     4  var ajaxConfig = window.blogger_mag_ajax_object || {};
     5  var i18n = ajaxConfig.i18n || {
     6    installing: 'Installing…',
     7    activating: 'Activating…',
     8    activated: 'Activated',
     9    failed: 'Failed — Retry',
     10    error: 'Error — Retry'
     11  };
     12
     13  /**
     14   * Switch active dashboard tab without page reload, syncing ARIA states,
     15   * URL query parameter, and WP admin left-sidebar submenu highlight.
     16   */
     17  function switchDashboardTab(tabKey, pushHistory) {
     18    if (!tabKey) {
     19      return;
     20    }
     21
     22    var $tabs = $('.bm-dashboard-navigation .bm-nav-tab');
     23    var $targetTab = $tabs.filter('[data-bm-tab="' + tabKey + '"]');
     24    var $panels = $('.bm-tab-panel');
     25    var $targetPanel = $('#bm-panel-' + tabKey);
     26
     27    if (!$targetTab.length || !$targetPanel.length) {
     28      return;
     29    }
     30
     31    // Update tab buttons
     32    $tabs
     33      .removeClass('is-active')
     34      .attr('aria-selected', 'false')
     35      .removeAttr('aria-current');
     36
     37    $targetTab
     38      .addClass('is-active')
     39      .attr('aria-selected', 'true')
     40      .attr('aria-current', 'page');
     41
     42    // Update tab panels
     43    $panels.removeClass('is-active').attr('hidden', 'hidden');
     44    $targetPanel.addClass('is-active').removeAttr('hidden');
     45
     46    // Update browser URL cleanly
     47    if (pushHistory !== false && window.history && window.history.replaceState) {
     48      var url = new URL(window.location.href);
     49      url.searchParams.set('tab', tabKey);
     50      window.history.replaceState({ tab: tabKey }, '', url.toString());
     51    }
     52
     53    // Sync WordPress left admin submenu highlight
     54    var menuSlug = ajaxConfig.menu_slug || 'blogger_mag_admin_menu';
     55    var $topMenu = $('#toplevel_page_' + menuSlug);
     56    if ($topMenu.length) {
     57      $topMenu.find('.wp-submenu li').removeClass('current');
     58      $topMenu.find('.wp-submenu a').removeClass('current').removeAttr('aria-current');
     59
     60      var targetHref =
     61        tabKey === 'starter-sites'
     62          ? 'admin.php?page=' + menuSlug + '&tab=starter-sites'
     63          : 'admin.php?page=' + menuSlug;
     64
     65      var $matchingLink = $topMenu.find('.wp-submenu a[href="' + targetHref + '"]');
     66      if ($matchingLink.length) {
     67        $matchingLink.addClass('current').attr('aria-current', 'page');
     68        $matchingLink.closest('li').addClass('current');
     69      }
     70    }
     71
     72    // Re-sync editor-dependent cards when switching tabs
     73    var detected = detectEditorFromStarterSites();
     74    if (detected) {
     75      updateProSidebarCard(detected, true);
     76    } else {
     77      updateProSidebarCard(currentEditor, false);
     78    }
     79  }
     80
     81  /**
     82   * Normalize editor key ('elementor', 'gutenberg', or 'customizer')
     83   * Supports Ansar Import's canonical values ('default-theme', 'block-editor', 'elementor')
     84   * as well as URL queries and standard aliases.
     85   */
     86  function normalizeEditorType(rawEditor) {
     87    if (!rawEditor) {
     88      return 'customizer';
     89    }
     90    var val = String(rawEditor).toLowerCase().trim();
     91
     92    // If a full URL is passed (like option.value in Ansar Import), extract query param
     93    if (val.indexOf('http') === 0 || val.indexOf('admin.php') !== -1 || val.indexOf('?') !== -1) {
     94      try {
     95        var urlObj = new URL(val, window.location.origin);
     96        var param = urlObj.searchParams.get('editor') || urlObj.searchParams.get('builder');
     97        if (param) {
     98          val = param.toLowerCase().trim();
     99        }
     100      } catch (e) {
     101        var match = val.match(/[?&](?:editor|builder)=([^&#]+)/i);
     102        if (match && match[1]) {
     103          val = decodeURIComponent(match[1]).toLowerCase().trim();
     104        }
     105      }
     106    }
     107
     108    // 1. Elementor check
     109    if (val.indexOf('elementor') !== -1 || val.indexOf('ansar-elements') !== -1) {
     110      return 'elementor';
     111    }
     112
     113    // 2. Gutenberg / Block Editor check
     114    if (
     115      val.indexOf('gutenberg') !== -1 ||
     116      val.indexOf('block') !== -1 ||
     117      val.indexOf('ansar-blocks') !== -1 ||
     118      val.indexOf('ansarbl') !== -1
     119    ) {
     120      return 'gutenberg';
     121    }
     122
     123    // 3. Classic / Customizer / Default Theme check
     124    if (
     125      val.indexOf('classic') !== -1 ||
     126      val.indexOf('customizer') !== -1 ||
     127      val.indexOf('default') !== -1
     128    ) {
     129      return 'customizer';
     130    }
     131
     132    return 'customizer';
     133  }
     134
     135  var currentEditor = normalizeEditorType(ajaxConfig.active_editor || 'customizer');
     136
     137  /**
     138   * Persist selected editor to cookie & localStorage so PHP and JS stay in sync
     139   */
     140  function persistSelectedEditor(normalized) {
     141    try {
     142      if (window.localStorage) {
     143        window.localStorage.setItem('bm_selected_editor', normalized);
     144      }
     145      document.cookie =
     146        'bm_selected_editor=' +
     147        encodeURIComponent(normalized) +
     148        '; path=/; max-age=31536000; SameSite=Lax';
     149    } catch (e) {}
     150  }
     151
     152  /**
     153   * Inspect Ansar Import Starter Sites DOM & storage for currently selected editor.
     154   * Prioritizes Ansar Import's .ansar-editor-switcher component.
     155   */
     156  function detectEditorFromStarterSites() {
     157    // 0. Explicit check for URL query parameter (?editor= or ?builder=)
     158    try {
     159      var urlParams = new URLSearchParams(window.location.search);
     160      var paramEditor = urlParams.get('editor') || urlParams.get('builder');
     161      if (paramEditor) {
     162        return normalizeEditorType(paramEditor);
     163      }
     164    } catch (e) {}
     165
     166    // 1. Primary Check: Ansar Import's .ansar-editor-switcher (select, container data attribute, option)
     167    var $switcher = $('.ansar-editor-switcher, [data-ansar-editor-switcher]');
     168    if ($switcher.length) {
     169      // 1a. Check container data-active-editor
     170      var activeAttr = $switcher.attr('data-active-editor') || $switcher.data('active-editor');
     171      if (activeAttr) {
     172        return normalizeEditorType(activeAttr);
     173      }
     174
     175      // 1b. Check select inside switcher (or switcher if it is a select)
     176      var $sel = $switcher.is('select') ? $switcher : $switcher.find('select');
     177      if ($sel.length) {
     178        var $opt = $sel.find('option:selected');
     179        if ($opt.length) {
     180          var optEditor = $opt.attr('data-editor') || $opt.attr('data-builder');
     181          if (optEditor) {
     182            return normalizeEditorType(optEditor);
     183          }
     184          var optText = $.trim($opt.text());
     185          if (optText && /(elementor|gutenberg|block|classic|customizer|default)/i.test(optText)) {
     186            return normalizeEditorType(optText);
     187          }
     188          var selVal = $opt.val() || $sel.val();
     189          if (selVal) {
     190            return normalizeEditorType(selVal);
     191          }
     192        }
     193      }
     194
     195      // 1c. Check checked input
     196      var $checked = $switcher.find('input:checked');
     197      if ($checked.length) {
     198        var chkVal = $checked.attr('data-editor') || $checked.attr('data-builder') || $checked.val();
     199        if (chkVal) {
     200          return normalizeEditorType(chkVal);
     201        }
     202      }
     203
     204      // 1d. Check active / selected items
     205      var $activeItem = $switcher
     206        .filter('.active, .is-active, .selected, .is-selected, .current, [aria-selected="true"]')
     207        .add(
     208          $switcher.find(
     209            '.active, .is-active, .selected, .is-selected, .current, [aria-selected="true"]'
     210          )
     211        );
     212      if ($activeItem.length) {
     213        var itemHint =
     214          $activeItem.attr('data-editor') ||
     215          $activeItem.attr('data-builder') ||
     216          $activeItem.attr('data-active-editor') ||
     217          $activeItem.attr('data-value') ||
     218          $.trim($activeItem.clone().children().remove().end().text()) ||
     219          $.trim($activeItem.text());
     220        if (itemHint && /(elementor|gutenberg|block|classic|customizer|default)/i.test(itemHint)) {
     221          return normalizeEditorType(itemHint);
     222        }
     223      }
     224    }
     225
     226    // 2. Check any builder/editor select inside .bm-starter-sites-wrap
     227    var foundEditor = '';
     228    $(
     229      '.bm-starter-sites-wrap select, select[name*="editor"], select[id*="editor"], select[name*="builder"], select[id*="builder"], .ansar-editor-select, [data-bm-editor-select]'
     230    ).each(function () {
     231      var $select = $(this);
     232      var $selected = $select.find('option:selected');
     233      var rawVal = String(
     234        $selected.attr('data-editor') ||
     235          $selected.attr('data-builder') ||
     236          $select.val() ||
     237          $selected.text() ||
     238          ''
     239      );
     240      if (rawVal && /(elementor|gutenberg|block|classic|customizer|default)/i.test(rawVal)) {
     241        foundEditor = normalizeEditorType(rawVal);
     242        return false;
     243      }
     244    });
     245    if (foundEditor) {
     246      return foundEditor;
     247    }
     248
     249    // 3. Check checked radio/checkbox inputs inside .bm-starter-sites-wrap
     250    $('.bm-starter-sites-wrap input[type="radio"]:checked, .bm-starter-sites-wrap input[type="checkbox"]:checked').each(function () {
     251      var $input = $(this);
     252      var id = $input.attr('id');
     253      var labelText = id ? $('label[for="' + id + '"]').text() : $input.closest('label').text();
     254      var rawVal = String(
     255        $input.attr('data-editor') ||
     256          $input.attr('data-builder') ||
     257          $input.val() ||
     258          labelText ||
     259          ''
     260      );
     261      if (rawVal && /(elementor|gutenberg|block|classic|customizer|default)/i.test(rawVal)) {
     262        foundEditor = normalizeEditorType(rawVal);
     263        return false;
     264      }
     265    });
     266    if (foundEditor) {
     267      return foundEditor;
     268    }
     269
     270    // 4. Check active/selected buttons, pills, tabs inside .bm-starter-sites-wrap
     271    $('.bm-starter-sites-wrap')
     272      .find(
     273        '.active, .is-active, .selected, .is-selected, .current, [aria-selected="true"], [aria-pressed="true"], [data-selected="true"]'
     274      )
     275      .each(function () {
     276        var $el = $(this);
     277        var attrHint =
     278          $el.attr('data-editor') ||
     279          $el.attr('data-builder') ||
     280          $el.attr('data-page-builder') ||
     281          $el.attr('data-type') ||
     282          $el.attr('data-filter') ||
     283          $el.attr('data-value') ||
     284          $el.attr('data-slug') ||
     285          '';
     286        var textHint =
     287          $.trim($el.clone().children().remove().end().text()) ||
     288          $.trim($el.text());
     289        var candidate = attrHint || (textHint.length <= 30 ? textHint : '');
     290        if (
     291          candidate &&
     292          /(elementor|gutenberg|block|classic|customizer|default)/i.test(candidate)
     293        ) {
     294          foundEditor = normalizeEditorType(candidate);
     295          return false;
     296        }
     297      });
     298    if (foundEditor) {
     299      return foundEditor;
     300    }
     301
     302    // 5. Check cookies
     303    var cookieMatch = document.cookie.match(/(?:^|;\s*)(?:bm_selected_editor|ansar_preferred_editor|ansar_selected_editor)=([^;]+)/);
     304    if (cookieMatch && cookieMatch[1]) {
     305      var decodedCookie = decodeURIComponent(cookieMatch[1]);
     306      if (decodedCookie) {
     307        return normalizeEditorType(decodedCookie);
     308      }
     309    }
     310
     311    // 6. Check localStorage / sessionStorage keys written by Ansar Import or Blogger Mag
     312    try {
     313      if (window.localStorage) {
     314        var saved = window.localStorage.getItem('bm_selected_editor');
     315        if (saved) {
     316          return normalizeEditorType(saved);
     317        }
     318      }
     319    } catch (e) {}
     320
     321    return '';
     322  }
     323
     324  /**
     325   * Smartly update .bm-pro-sidebar-card and .bm-plugins-grid based on selected editor
     326   */
     327  function updateProSidebarCard(editorKey, shouldPersist) {
     328    var proCards = ajaxConfig.pro_cards || {};
     329    var normalized = normalizeEditorType(editorKey);
     330    currentEditor = normalized;
     331
     332    if (shouldPersist !== false) {
     333      persistSelectedEditor(normalized);
     334    }
     335
     336    var targetPluginEditor = normalized === 'gutenberg' ? 'gutenberg' : 'elementor';
     337
     338    // 1. Sync .bm-plugins-grid cards (keep ansar-import always, toggle ansar-blocks vs ansar-elements)
     339    $('.bm-plugins-grid .bm-plugin-card').each(function () {
     340      var $pluginCard = $(this);
     341      var cardEditor = $pluginCard.attr('data-bm-plugin-editor') || 'all';
     342      if (cardEditor === 'all' || cardEditor === targetPluginEditor) {
     343        $pluginCard.removeAttr('hidden');
     344      } else {
     345        $pluginCard.attr('hidden', 'hidden');
     346      }
     347    });
     348
     349    // 2. Sync .bm-pro-sidebar-card content & CTA link
     350    var cardData = proCards[normalized] || proCards.customizer;
     351    if (!cardData) {
     352      return;
     353    }
     354
     355    $('.bm-pro-sidebar-card').each(function () {
     356      var $card = $(this);
     357      $card.attr('data-bm-editor', normalized);
     358
     359      if (cardData.badge) {
     360        $card.find('.bm-pro-pill-text').text(cardData.badge);
     361      }
     362      if (cardData.title) {
     363        $card.find('.bm-pro-sidebar-title').text(cardData.title);
     364      }
     365      if (cardData.description) {
     366        $card.find('.bm-pro-sidebar-desc').text(cardData.description);
     367      }
     368      if ($.isArray(cardData.perks) && cardData.perks.length) {
     369        var $perksList = $card.find('.bm-pro-perks');
     370        if ($perksList.length) {
     371          $perksList.empty();
     372          $.each(cardData.perks, function (_, perkText) {
     373            var $li = $('<li></li>');
     374            $li.append('<span class="dashicons dashicons-yes-alt" aria-hidden="true"></span> ');
     375            $li.append($('<span class="bm-pro-perk-text"></span>').text(perkText));
     376            $perksList.append($li);
     377          });
     378        }
     379      }
     380      if (cardData.button_text) {
     381        $card.find('.bm-pro-btn-label').text(cardData.button_text);
     382      }
     383      if (cardData.url) {
     384        $card.find('.bm-button-pro').attr('href', cardData.url);
     385      }
     386    });
     387
     388    // 3. Sync .bm-header-cta href as per selected editor
     389    var headerUrl = (cardData && cardData.url) ? cardData.url : (ajaxConfig.pro_url || 'https://themeansar.com/themes/blogger-mag-pro/');
     390    $('.bm-header-cta')
     391      .attr('href', headerUrl)
     392      .attr('data-bm-editor', normalized);
     393
     394    // 4. Sync .bm-editor-action-btn (.bm-button.bm-button-lg) to matched editor
     395    updateEditorActionButtons(normalized);
     396  }
     397
     398  /**
     399   * Update the secondary hero & toolbar action button (.bm-button.bm-button-lg.bm-editor-action-btn)
     400   * based on the selected editor in Starter Sites (via Ansar Import's .ansar-editor-switcher):
     401   * - Classic / Customizer: Open Customizer -> admin_url('customize.php')
     402   * - Elementor: Open Theme Builder -> admin_url('admin.php?page=ansar_elements_admin_menu&tab=theme-builder')
     403   * - Block Editor / Gutenberg: Open Theme Builder -> admin_url('admin.php?page=ansarbl-admin&tab=theme-builder')
     404   */
     405  function updateEditorActionButtons(normalized) {
     406    var editorButtons = ajaxConfig.editor_buttons || {};
     407    var btnConfig = editorButtons[normalized] || editorButtons.customizer;
     408
     409    var adminBase = (ajaxConfig.ajax_url || '').replace(/admin-ajax\.php.*$/, '');
     410    if (!btnConfig) {
     411      if (normalized === 'elementor') {
     412        btnConfig = {
     413          label: 'Open Theme Builder',
     414          url: adminBase + 'admin.php?page=ansar_elements_admin_menu&tab=theme-builder'
     415        };
     416      } else if (normalized === 'gutenberg') {
     417        btnConfig = {
     418          label: 'Open Theme Builder',
     419          url: adminBase + 'admin.php?page=ansarbl-admin&tab=theme-builder'
     420        };
     421      } else {
     422        btnConfig = {
     423          label: 'Open Customizer',
     424          url: adminBase + 'customize.php'
     425        };
     426      }
     427    }
     428
     429    var $actionButtons = $(
     430      '.bm-editor-action-btn, .bm-welcome-actions .bm-button.bm-button-lg:not(.bm-button-primary)'
     431    );
     432
     433    $actionButtons.each(function () {
     434      var $btn = $(this);
     435      $btn.attr('href', btnConfig.url);
     436      $btn.attr('data-bm-editor', normalized);
     437
     438      var $label = $btn.find('.bm-btn-label');
     439      if ($label.length) {
     440        $label.text(btnConfig.label);
     441      } else {
     442        var $span = $btn.find('span:last');
     443        if ($span.length) {
     444          $span.text(btnConfig.label);
     445        }
     446      }
     447
     448      if (btnConfig.icon) {
     449        var $icon = $btn.find('.bm-btn-icon');
     450        if ($icon.length) {
     451          $icon.html(btnConfig.icon);
     452        } else {
     453          var $svg = $btn.find('svg');
     454          if ($svg.length) {
     455            $svg.replaceWith(btnConfig.icon);
     456          }
     457        }
     458      }
     459    });
     460  }
     461
     462  /**
     463   * Reusable 2-step AJAX Plugin Installer & Activator
     464   */
     465  function handlePluginAction($btn, options) {
     466    var slug = options.slug;
     467    var pluginFile = options.pluginFile;
     468    var status = options.status;
     469    var redirectUrl = options.redirectUrl || '';
     470    var $card = options.$card || null;
     471
     472    if (!slug || !pluginFile) {
     473      return;
     474    }
     475
     476    function activatePlugin() {
     477      $btn.text(i18n.activating).prop('disabled', true).addClass('is-loading');
     478
     479      $.ajax({
     480        url: ajaxConfig.ajax_url || window.ajaxurl,
     481        type: 'POST',
     482        data: {
     483          action: 'blogger_mag_activate_plugin',
     484          nonce: ajaxConfig.plugin_nonce,
     485          plugin_file: pluginFile
     486        },
     487        success: function (response) {
     488          if (!response || !response.success) {
     489            $btn.text(i18n.failed).prop('disabled', false).removeClass('is-loading');
     490            return;
     491          }
     492
     493          $btn
     494            .removeClass('btn-install btn-activate bm-button-primary is-loading')
     495            .addClass('btn-disabled')
     496            .text(i18n.activated)
     497            .prop('disabled', true);
     498
     499          if ($card && $card.length) {
     500            $card.attr('data-status', 'activated');
     501            $card
     502              .find('.bm-plugin-status-pill')
     503              .removeClass('is-install is-activate')
     504              .addClass('is-activated')
     505              .text('Active');
     506          }
     507
     508          // Switch .bm-greeting-badge from Setup Progress (#4) to Edition Status Pill (#2) when ansar-import activates
     509          if (slug.indexOf('ansar-import') !== -1) {
     510            $('.bm-greeting-badge[data-bm-badge-state="setup"]').attr('hidden', 'hidden');
     511            $('.bm-greeting-badge[data-bm-badge-state="edition"]').removeAttr('hidden');
     512          }
     513
     514          // Smartly sync Pro sidebar card if an editor/builder plugin was activated
     515          if (slug.indexOf('elementor') !== -1 || slug.indexOf('ansar-elements') !== -1) {
     516            updateProSidebarCard('elementor');
     517          } else if (slug.indexOf('gutenberg') !== -1 || slug.indexOf('block') !== -1) {
     518            updateProSidebarCard('gutenberg');
     519          }
     520
     521          if (redirectUrl) {
     522            setTimeout(function () {
     523              window.location.href = redirectUrl;
     524            }, 500);
     525          }
     526        },
     527        error: function () {
     528          $btn.text(i18n.error).prop('disabled', false).removeClass('is-loading');
     529        }
     530      });
     531    }
     532
     533    // Case 1: Already installed -> Activate directly
     534    if (status === 'activate' || $btn.hasClass('btn-activate')) {
     535      activatePlugin();
     536      return;
     537    }
     538
     539    // Case 2: Not installed -> Install first, then Activate
     540    $btn.text(i18n.installing).prop('disabled', true).addClass('is-loading');
     541
     542    $.ajax({
     543      url: ajaxConfig.ajax_url || window.ajaxurl,
     544      type: 'POST',
     545      data: {
     546        action: 'blogger_mag_install_plugin',
     547        nonce: ajaxConfig.plugin_nonce,
     548        slug: slug
     549      },
     550      success: function (response) {
     551        if (!response || !response.success) {
     552          $btn.text(i18n.failed).prop('disabled', false).removeClass('is-loading');
     553          return;
     554        }
     555        activatePlugin();
     556      },
     557      error: function () {
     558        $btn.text(i18n.error).prop('disabled', false).removeClass('is-loading');
     559      }
     560    });
     561  }
     562
    2563  $(document).ready(function () {
    3     $('.blogger-mag-btn-get-started').on('click', function (e) {
     564    // 1. Open Upgrade submenu item in a new tab
     565    $('#bm-upgrade-menu-item').closest('a').attr({
     566      target: '_blank',
     567      rel: 'noopener noreferrer'
     568    });
     569
     570    // 2. Dashboard Tab Navigation (Click + Keyboard Arrows)
     571    $(document).on('click', '.bm-dashboard-navigation .bm-nav-tab', function (e) {
     572      var tabKey = $(this).data('bm-tab');
     573      if (tabKey) {
     574        e.preventDefault();
     575        switchDashboardTab(tabKey, true);
     576      }
     577    });
     578
     579    $(document).on('click', '[data-bm-switch-tab]', function (e) {
     580      var tabKey = $(this).data('bm-switch-tab');
     581      if (tabKey && $('#bm-panel-' + tabKey).length) {
     582        e.preventDefault();
     583        switchDashboardTab(tabKey, true);
     584        window.scrollTo({ top: 0, behavior: 'smooth' });
     585      }
     586    });
     587
     588    $(document).on('keydown', '.bm-dashboard-navigation .bm-nav-tab', function (e) {
     589      var $tabs = $('.bm-dashboard-navigation .bm-nav-tab');
     590      var index = $tabs.index(this);
     591      var nextIndex = -1;
     592
     593      if (e.key === 'ArrowRight') {
     594        nextIndex = (index + 1) % $tabs.length;
     595      } else if (e.key === 'ArrowLeft') {
     596        nextIndex = (index - 1 + $tabs.length) % $tabs.length;
     597      } else if (e.key === 'Home') {
     598        nextIndex = 0;
     599      } else if (e.key === 'End') {
     600        nextIndex = $tabs.length - 1;
     601      }
     602
     603      if (nextIndex !== -1) {
     604        e.preventDefault();
     605        var $nextTab = $tabs.eq(nextIndex);
     606        $nextTab.trigger('focus');
     607        switchDashboardTab($nextTab.data('bm-tab'), true);
     608      }
     609    });
     610
     611    // 3. Plugin Cards Install / Activate
     612    $(document).on('click', '.bm-plugin-card .btn-install, .bm-plugin-card .btn-activate', function (e) {
    4613      e.preventDefault();
    5       if (!blogger_mag_ajax_object.can_install) {
     614      var $btn = $(this);
     615      var $card = $btn.closest('.bm-plugin-card');
     616
     617      handlePluginAction($btn, {
     618        slug: $.trim($card.data('slug')),
     619        pluginFile: $.trim($card.data('plugin')),
     620        status: $.trim($card.attr('data-status')),
     621        redirectUrl: $.trim($card.data('redirect')),
     622        $card: $card
     623      });
     624    });
     625
     626    // 4. Starter Sites Quick Install Button (Welcome Hero & Starter Sites Modal)
     627    $(document).on('click', '.bm-install-starter-plugin', function (e) {
     628      e.preventDefault();
     629      var $btn = $(this);
     630      var $label = $btn.find('span').length ? $btn.find('span') : $btn;
     631
     632      handlePluginAction($label, {
     633        slug: $.trim($btn.data('slug')),
     634        pluginFile: $.trim($btn.data('plugin')),
     635        status: $.trim($btn.data('status')),
     636        redirectUrl: $.trim($btn.data('redirect')) || ajaxConfig.starter_url
     637      });
     638    });
     639
     640    // 5. Welcome Admin Notice "Get Started" Bulk Installer
     641    $(document).on('click', '.blogger-mag-btn-get-started', function (e) {
     642      e.preventDefault();
     643      if (!ajaxConfig.can_install) {
    6644        alert('Sorry, you are not allowed to access this page.');
    7645        return;
    … …  
    9647      var $btn = $(this);
    10648      $btn.html('Processing.. Please wait').addClass('updating-message');
    11       $.post(blogger_mag_ajax_object.ajax_url, {
    12         action: 'install_act_plugin',
    13         security: blogger_mag_ajax_object.install_nonce
    14       }, function (response) {
    15         if (response.success) {
    16           window.location.href = 'admin.php?page=ansar_elements_admin_menu&tab=starter-sites';
    17         } else {
    18           alert(response.data?.message || 'Installation failed.');
    19           $btn.html('Try Again').removeClass('updating-message');
    20         }
    21       }).fail(function () {
     649      $.post(
     650        ajaxConfig.ajax_url || window.ajaxurl,
     651        {
     652          action: 'install_act_plugin',
     653          security: ajaxConfig.install_nonce
     654        },
     655        function (response) {
     656          if (response && response.success) {
     657            window.location.href =
     658              ajaxConfig.starter_url ||
     659              'admin.php?page=blogger_mag_admin_menu&tab=starter-sites';
     660          } else {
     661            alert((response && response.data && response.data.message) || 'Installation failed.');
     662            $btn.html('Try Again').removeClass('updating-message');
     663          }
     664        }
     665      ).fail(function () {
    22666        alert('Something went wrong. Please try again.');
    23667        $btn.html('Try Again').removeClass('updating-message');
    24668      });
    25669    });
     670
     671    // 6. Dismissible Admin Notice Handler
     672    $(document).on('click', '.notice-get-started-class .notice-dismiss', function () {
     673      var type = $(this).closest('.notice-get-started-class').data('notice');
     674      $.post(ajaxConfig.ajax_url || window.ajaxurl, {
     675        action: 'blogger_mag_dismissed_notice_handler',
     676        type: type
     677      });
     678    });
     679
     680    // 7. Direct Event Listeners for Ansar Import Editor Switcher (.ansar-editor-switcher)
     681    $(document).on(
     682      'change',
     683      '.ansar-editor-switcher, .ansar-editor-switcher select, .ansar-editor-switcher input, #ansar-editor-switcher',
     684      function () {
     685        var $el = $(this);
     686        var rawVal = '';
     687        if ($el.is('select')) {
     688          var $selectedOpt = $el.find('option:selected');
     689          rawVal =
     690            $selectedOpt.attr('data-editor') ||
     691            $selectedOpt.attr('data-builder') ||
     692            $selectedOpt.text() ||
     693            $el.val();
     694        } else if ($el.is('input')) {
     695          rawVal = $el.attr('data-editor') || $el.attr('data-builder') || $el.val();
     696        } else {
     697          rawVal = $el.attr('data-active-editor') || $el.attr('data-editor');
     698        }
     699        if (rawVal) {
     700          updateProSidebarCard(rawVal, true);
     701        } else {
     702          setTimeout(syncFromStarterSitesDOM, 30);
     703        }
     704      }
     705    );
     706
     707    $(document).on(
     708      'click',
     709      '.ansar-editor-switcher, .ansar-editor-switcher *',
     710      function (e) {
     711        var $target = $(e.target).closest(
     712          '.ansar-editor-switcher button, .ansar-editor-switcher a, .ansar-editor-switcher li, .ansar-editor-switcher [role="tab"], .ansar-editor-switcher [role="option"], .ansar-editor-switcher label, [data-editor], [data-builder]'
     713        );
     714        if ($target.length) {
     715          var rawVal =
     716            $target.attr('data-editor') ||
     717            $target.attr('data-builder') ||
     718            $target.attr('data-page-builder') ||
     719            $target.attr('data-active-editor') ||
     720            $target.attr('data-value') ||
     721            $target.attr('data-slug') ||
     722            $.trim($target.clone().children().remove().end().text()) ||
     723            $.trim($target.text());
     724          if (rawVal) {
     725            updateProSidebarCard(rawVal, true);
     726            return;
     727          }
     728        }
     729        setTimeout(syncFromStarterSitesDOM, 40);
     730      }
     731    );
     732
     733    // 8. Smart Real-Time Editor Detection & Sync (Ansar Import Select / Dropdown / Buttons / MutationObserver)
     734    function syncFromStarterSitesDOM() {
     735      var detected = detectEditorFromStarterSites();
     736      if (detected) {
     737        updateProSidebarCard(detected, true);
     738      } else {
     739        updateProSidebarCard(currentEditor, false);
     740      }
     741    }
     742
     743    // Initial sync on page load
     744    syncFromStarterSitesDOM();
     745
     746    // Capture-phase change listener so stopPropagation() inside plugins cannot block it
     747    document.addEventListener(
     748      'change',
     749      function (e) {
     750        var target = e.target;
     751        if (!target) {
     752          return;
     753        }
     754        var $target = $(target);
     755        if (
     756          $target.is('select') ||
     757          $target.is('input[type="radio"], input[type="checkbox"]')
     758        ) {
     759          var $opt = $target.is('select') ? $target.find('option:selected') : $target;
     760          var rawHint = String(
     761            $opt.attr('data-editor') ||
     762              $opt.attr('data-builder') ||
     763              $opt.text() ||
     764              $target.val() ||
     765              ''
     766          );
     767          if (rawHint && /(elementor|gutenberg|block|classic|customizer|default)/i.test(rawHint)) {
     768            updateProSidebarCard(rawHint, true);
     769          }
     770        }
     771      },
     772      true
     773    );
     774
     775    // Capture-phase click listener for custom dropdowns, pills, or buttons in Starter Sites
     776    document.addEventListener(
     777      'click',
     778      function (e) {
     779        var target = e.target;
     780        if (!target) {
     781          return;
     782        }
     783        var $el = $(target).closest(
     784          '.ansar-editor-switcher, .ansar-editor-switcher *, [data-editor], [data-builder], [data-page-builder], [data-active-editor], [data-value], [data-filter], [data-slug], .bm-starter-sites-wrap button, .bm-starter-sites-wrap a, .bm-starter-sites-wrap li, .bm-starter-sites-wrap label, .bm-starter-sites-wrap [role="option"], .bm-starter-sites-wrap [role="tab"]'
     785        );
     786        if ($el.length) {
     787          var attrHint =
     788            $el.attr('data-editor') ||
     789            $el.attr('data-builder') ||
     790            $el.attr('data-page-builder') ||
     791            $el.attr('data-active-editor') ||
     792            $el.attr('data-value') ||
     793            $el.attr('data-filter') ||
     794            $el.attr('data-slug') ||
     795            '';
     796          var textHint =
     797            $.trim($el.clone().children('ul, ol').remove().end().text()) ||
     798            $.trim($el.text());
     799          var candidate = attrHint || (textHint.length <= 28 ? textHint : '');
     800          if (
     801            candidate &&
     802            /(elementor|gutenberg|block|classic|customizer|default)/i.test(candidate)
     803          ) {
     804            updateProSidebarCard(candidate, true);
     805            return;
     806          }
     807        }
     808        if ($(target).closest('.ansar-editor-switcher, .bm-starter-sites-wrap').length) {
     809          setTimeout(syncFromStarterSitesDOM, 60);
     810        }
     811      },
     812      true
     813    );
     814
     815    // Observe DOM changes inside .bm-starter-sites-wrap when Ansar Import initializes or updates
     816    var starterWrapEl = document.querySelector('.bm-starter-sites-wrap');
     817    if (starterWrapEl && window.MutationObserver) {
     818      var observerTimer = null;
     819      var observer = new MutationObserver(function () {
     820        if (observerTimer) {
     821          clearTimeout(observerTimer);
     822        }
     823        observerTimer = setTimeout(syncFromStarterSitesDOM, 100);
     824      });
     825      observer.observe(starterWrapEl, {
     826        childList: true,
     827        subtree: true,
     828        attributes: true,
     829        attributeFilter: ['class', 'aria-selected', 'data-editor', 'data-builder', 'value']
     830      });
     831    }
    26832  });
    27 $(document).on('click', '.notice-get-started-class .notice-dismiss', function () {
    28   var type = $(this).closest('.notice-get-started-class').data('notice');
    29   $.post(ajaxurl, {
    30     action: 'blogger_mag_dismissed_notice_handler',
    31     type: type,
    32   });
    33 });
    34833})(jQuery);
  • blogger-mag/0.8/css/core.css

    r332032 r357015  
    11/*---------------------------------------
    2         Core Wordpress
     2        Core WordPress
    33-----------------------------------------*/
    44table {
    … …  
    314314  clear: right;
    315315}
    316 .wp-block-button .wp-block-button__link {
    317   font-size: 16px;
    318   border: 2px solid;
    319   margin-bottom: 1rem;
    320 }
    321316:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) {
    322317  border: none;
  • blogger-mag/0.8/footer.php

    r329065 r357015  
    1414
    1515?>
    16 <footer class="blogger-mag-footer">
    17   <div class="copyright">
    18   <?php
    19     $theme_data = wp_get_theme();
    20    
    21     printf( __( '<p> <span class="copyright-text">Copyright © All rights reserved</span> | %1$s by  <a href="%2$s">%3$s.</a></p>', 'blogger-mag' ), esc_html( $theme_data->Name ), esc_url( 'https://themeansar.com/' ), $theme_data->Author );
    22     ?>
    23   </div>
    24 </footer>
     16<?php
     17// 1. Check if Ansar Elements has an active footer template for the current page
     18$has_ansar_footer = class_exists( 'Ansar_Elements_Theme_Builder_Elementor' )
     19    && Ansar_Elements_Theme_Builder_Elementor::instance()->foot_template_id();
     20
     21if ( $has_ansar_footer ) {
     22    // Render Ansar Elements Footer
     23    do_action( 'ansarel_foot' );
     24} else {
     25    // 2. Fallback to a Gutenberg Block Pattern
     26    // Replace 'blogger-mag/footer-pattern' with your actual registered pattern slug
     27    echo do_blocks( '<!-- wp:pattern {"slug":"blogger-mag/footer-pattern"} /-->' );
     28}
     29?>
    2530<?php wp_footer(); ?>
    2631</body>
  • blogger-mag/0.8/functions.php

    r340927 r357015  
    6363     */
    6464    private function includes() {
    65         // Include admin plugin installer
     65        // Include admin plugin installer and theme admin dashboard
    6666        require_once BLOGGER_MAG_PATH . 'admin/blogger-mag-admin-plugin-install.php';
     67        if ( is_admin() ) {
     68            require_once BLOGGER_MAG_PATH . 'admin/admin.php';
     69        }
    6770       
    6871        // Include customizer and template functions
    … …  
    8285        add_filter( 'excerpt_length', array( $this, 'blogger_mag_excerpt_length' ), 999 );
    8386        add_action( 'after_setup_theme', array( $this, 'add_editor_styles' ) );
     87        add_action( 'init', array( $this, 'register_pattern_categories' ) );
    8488    }
    8589
    … …  
    9094        wp_enqueue_style( 'blogger-mag-theme-style', get_stylesheet_uri() );
    9195       
    92         // Add Google Font
     96        // Add Google Fonts (Figtree & Inter)
    9397        wp_enqueue_style(
    9498            'google-fonts',
    95             'https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap',
     99            'https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
    96100            array(),
    97101            null
    … …  
    117121            BLOGGER_MAG_URI . 'admin/js/blogger-mag-admin-script.js',
    118122            array( 'jquery' ),
    119             '',
     123            BLOGGER_MAG_VERSION,
    120124            true
    121125        );
    … …  
    126130                'ajax_url'      => admin_url( 'admin-ajax.php' ),
    127131                'install_nonce' => wp_create_nonce( 'blogger_mag_install_plugin_nonce' ),
     132                'plugin_nonce'  => wp_create_nonce( 'blogger_mag_plugin_nonce' ),
    128133                'can_install'   => current_user_can( 'install_plugins' ),
     134                'menu_slug'     => 'blogger_mag_admin_menu',
     135                'starter_url'   => admin_url( 'admin.php?page=blogger_mag_admin_menu&tab=starter-sites' ),
    129136            )
    130137        );
    131         wp_enqueue_style( 'blogger-mag-admin', BLOGGER_MAG_URI . 'admin/css/admin.css' );
     138        wp_enqueue_style( 'blogger-mag-admin', BLOGGER_MAG_URI . 'admin/css/admin.css', array(), BLOGGER_MAG_VERSION );
    132139    }
    133140
    … …  
    171178        ) );
    172179        add_theme_support( "wp-block-styles" );
     180
     181        add_theme_support(
     182            'ansar-starter-sites',
     183            array(
     184                'pro_url'              => 'https://themeansar.com/themes/blogger-mag-pro/',
     185                'doc_url'              => 'https://docs.themeansar.com/docs/ansar-elements/',
     186                'demo_fallback_search' => 'Newsup',
     187                'starter_sites_url'    => admin_url( 'admin.php?page=blogger_mag_admin_menu&tab=starter-sites' ),
     188            )
     189        );
    173190    }
    174191
    … …  
    213230        return 20;
    214231    }
     232
     233    /**
     234     * Register theme block pattern category.
     235     */
     236    public function register_pattern_categories() {
     237        if ( function_exists( 'register_block_pattern_category' ) ) {
     238            register_block_pattern_category(
     239                'blogger-mag',
     240                array( 'label' => __( 'Blogger Mag', 'blogger-mag' ) )
     241            );
     242        }
     243    }
    215244}
    216245
  • blogger-mag/0.8/header.php

    r340927 r357015  
    11<?php
    2 
    32/**
    43 * The header for our theme.
    … …  
    1615<!DOCTYPE html>
    1716<html <?php language_attributes(); ?>>
     17<head>
     18    <meta charset="<?php bloginfo( 'charset' ); ?>">
     19    <meta name="viewport" content="width=device-width, initial-scale=1">
     20    <link rel="profile" href="https://gmpg.org/xfn/11">
     21    <?php wp_head(); ?>
     22</head>
     23<body <?php body_class(); ?>>
     24<?php wp_body_open(); ?>
    1825
    19 <head>
    20   <meta charset="<?php bloginfo('charset'); ?>">
    21   <meta name="viewport" content="width=device-width, initial-scale=1">
    22   <link rel="profile" href="http://gmpg.org/xfn/11">
    23   <?php wp_head(); ?>
    24 </head>
     26<?php
     27// 1. Check if Ansar Elements has an active header template for the current page
     28$has_ansar_header = class_exists( 'Ansar_Elements_Theme_Builder_Elementor' )
     29    && Ansar_Elements_Theme_Builder_Elementor::instance()->head_template_id();
    2530
    26 <body <?php body_class(); ?>>
    27   <?php wp_body_open(); ?>
    28   <div id="page" class="site">
    29     <a class="skip-link screen-reader-text" href="#content">
    30       <?php _e('Skip to content', 'blogger-mag'); ?></a>
    31     <div class="wrapper">
    32       <header class="blogger-mag-header">
    33         <div class="blogger-magader-logo">
    34           <?php the_custom_logo();
    35           $header_text = get_theme_mod('header_text', true);
    36           $header_tagline = get_theme_mod('header_tagline', true);
    37           if ( $header_text || $header_tagline) { ?>
    38             <div class="blogger-mag-site-branding">
    39               <?php if( $header_text == true) { ?>
    40                 <h1 class="site-title"><a href="<?php echo esc_url(home_url('/')); ?>" rel="home"><?php echo esc_html(get_bloginfo('name')); ?></a></h1>
    41               <?php }
    42               if( $header_tagline == true ) { ?>
    43                 <p class="site-description"><?php echo esc_html(get_bloginfo('description')); ?></p>
    44               <?php } ?>
    45             </div>
    46           <?php } ?>
    47         </div>
    48         <div class="blogger-mag-header-menu">
    49           <nav id="main-nav" class="main_nav">
    50             <input type="checkbox" id="dropdown" class="blogger-mag-toggle-checkbox" />
    51             <label for="dropdown" class="blogger-mag-toggle">
    52               <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M96 160C96 142.3 110.3 128 128 128L512 128C529.7 128 544 142.3 544 160C544 177.7 529.7 192 512 192L128 192C110.3 192 96 177.7 96 160zM96 320C96 302.3 110.3 288 128 288L512 288C529.7 288 544 302.3 544 320C544 337.7 529.7 352 512 352L128 352C110.3 352 96 337.7 96 320zM544 480C544 497.7 529.7 512 512 512L128 512C110.3 512 96 497.7 96 480C96 462.3 110.3 448 128 448L512 448C529.7 448 544 462.3 544 480z"/></svg>
    53               <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M183.1 137.4C170.6 124.9 150.3 124.9 137.8 137.4C125.3 149.9 125.3 170.2 137.8 182.7L275.2 320L137.9 457.4C125.4 469.9 125.4 490.2 137.9 502.7C150.4 515.2 170.7 515.2 183.2 502.7L320.5 365.3L457.9 502.6C470.4 515.1 490.7 515.1 503.2 502.6C515.7 490.1 515.7 469.8 503.2 457.3L365.8 320L503.1 182.6C515.6 170.1 515.6 149.8 503.1 137.3C490.6 124.8 470.3 124.8 457.8 137.3L320.5 274.7L183.1 137.4z"/></svg>
    54             </label>
    55            <?php
    56               if ( has_nav_menu('primary') ) {
    57                 wp_nav_menu(array(
    58                 'theme_location'  => 'primary',
    59                 'menu_class'     => 'blogger-mag-menu',         
    60               ));
    61             } ?>
    62           </nav>
    63         </div>
    64       </header>
    65       <div class="clearfix"></div>
     31if ( $has_ansar_header ) {
     32    // Render Ansar Elements Header
     33    do_action( 'ansarel_head' );
     34} else {
     35    // 2. Fallback to a Gutenberg Block Pattern
     36    // Replace 'blogger-mag/header-pattern' with your actual registered pattern slug
     37    echo do_blocks( '<!-- wp:pattern {"slug":"blogger-mag/header-pattern"} /-->' );
     38}
     39?>
  • blogger-mag/0.8/inc/customizer.php

    r340927 r357015  
    119119            foreach ( $properties as $setting ) {
    120120                $key         = $setting['key'];
    121                 $default_val = isset( $defaults[ $key ] ) ? $defaults[ $key ] : '';
     121                $default_val = isset( $all_defaults[ $key ] ) ? $all_defaults[ $key ] : '';
    122122
    123123                $blogger_mag_css .= blogger_mag_range_css(
  • blogger-mag/0.8/inc/customizer/defaults.php

    r340927 r357015  
    1818   
    1919    $defaults['side_main_logo_width'] = wp_json_encode( array( 'desktop' => '250', 'tablet'  => '200','mobile'  => '150', 'unit' => 'px',) ) ;
    20     $defaults['simple_border_radius'] = wp_json_encode( array( 'desktop' => '15', 'unit' => 'px',) ) ;
    2120   
    2221    // filter.
  • blogger-mag/0.8/inc/customizer/sanitizations.php

    r340927 r357015  
    3939    return is_numeric( $input ) ? floatval( $input ) : '';
    4040}
    41 
    42 function blogger_mag_json( $string ) {
    43     return is_string( $string ) && is_array( json_decode( $string, true ) ) ? true : false;
    44 }
  • blogger-mag/0.8/inc/customizer/settings/customize-options.php

    r340927 r357015  
    33include_once ABSPATH . 'wp-admin/includes/plugin.php';
    44
    5 if ( class_exists('ANSAR_ELEMENTS') ) {
     5if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'ansar-import/ansar-import.php' ) ) {
    66
    7     $demo_import = 'class="button button-primary" href="' . admin_url( 'admin.php?page=ansar_elements_admin_menu&tab=starter-sites' ) . '"';
     7    $demo_import = 'class="button button-primary" href="' . esc_url( admin_url( 'admin.php?page=blogger_mag_admin_menu&tab=starter-sites' ) ) . '"';
    88   
    99} else {
  • blogger-mag/0.8/index.php

    r329065 r357015  
    1616}
    1717
    18 get_header(); ?>
    19 <main id="content" class="main-section">
    20   <?php get_template_part('template-parts/content'); ?>
    21 </main>
    22 <?php get_footer(); ?>
     18get_header();
     19
     20// 1. Check if Ansar Elements has an active page template for the current page
     21$has_ansar_page = class_exists( 'Ansar_Elements_Theme_Builder_Elementor' )
     22    && Ansar_Elements_Theme_Builder_Elementor::instance()->full_page_template_id();
     23
     24if ( $has_ansar_page ) {
     25    // Render Ansar Elements Page Template
     26    do_action( 'ansarel_full_page' );
     27} else {
     28    // 2. Fallback to a Gutenberg Block Pattern
     29    // Replace 'blogger-mag/archive-pattern' with your actual registered pattern slug
     30    echo do_blocks( '<!-- wp:pattern {"slug":"blogger-mag/archive-pattern"} /-->' );
     31}
     32
     33get_footer(); ?>
  • blogger-mag/0.8/readme.txt

    r340927 r357015  
    22Contributors: themeansar
    33Author: themeansar
    4 Requires at least: WordPress 6.6
    5 Tested up to: WordPress 7.0
     4Requires at least: WordPress 6.0
     5Tested up to: WordPress 7.1
    66Requires PHP: 7.4
    7 Stable tag: 0.7
    8 Version: 0.7
     7Stable tag: 0.8
     8Version: 0.8
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
    … …  
    7070* Added Logo Width Option.
    7171* Added Site Title and Tagline visibility options.
     72
     73= Version 0.8
     74* Added theme.json.
     75* Added patterns.
  • blogger-mag/0.8/single.php

    r329065 r357015  
    1 <!-- =========================
    2      Page Breadcrumb   
    3 ============================== -->
    4 <?php
     1<?php
     2/**
     3 * The template for displaying all single posts.
     4 *
     5 * @package Blogger-Mag
     6 */
     7
    58if ( ! defined( 'ABSPATH' ) ) {
    69        exit; // Exit if accessed directly.
    710}
    8 get_header(); ?>
    9 <!--==================== main content section ====================-->
    10 <!-- =========================
    11      Page Content Section     
    12 ============================== -->
    13 <main id="content" class="main-section single-section"> 
    14   <?php if(have_posts())
    15   {
    16     while(have_posts()) { the_post(); ?>
    17     <div class="blogger-mag-blog-post-box">
    18       <div class="blogger-magog-post-inner">
    19         <div class="blogger-mag-blog-category">
    20           <?php $cat_list = get_the_category_list();
    21             if(!empty($cat_list)) { 
    22               the_category('&nbsp');
    23             } ?>
    24         </div>
    25         <h1 class="blogger-mag-title single">
    26           <?php the_title(); ?>
    27         </h1>
    28         <div class="post-meta">
    29           <a href="<?php echo esc_url(get_day_link(get_post_time('Y'), get_post_time('m'), get_post_time('j')));  ?>">
    30               <span class="post-date"><?php the_time( get_option( 'date_format' ) ); ?></span>
    31           </a>
    32           <span class="meta-sep">/</span>
    33           <?php comments_popup_link( esc_html__( 'No Comments', 'blogger-mag' ), esc_html__( '1 Comment', 'blogger-mag' ), '% '. esc_html__( 'Comments', 'blogger-mag' ), 'post-comments'); ?>
    34         </div>
    35         <?php if (has_tag()) {
    36           the_tags();
    37         }
    38         ?>
    39       </div>
    40       <?php
    41       if(has_post_thumbnail()){
    42         echo the_post_thumbnail( '', array( 'class'=>'img-responsive' ) );
    43       } ?>
    44       <div class="blogger-mag-blog-post-inner single">
    45         <?php the_content(); ?>
    46       </div>
    47     </div>
    48   <?php } } ?>
    49   <div class="blogger-mag-blog-comment">
    50     <?php comments_template('',true); ?>
    51   </div>
    52 </main>
    53 <?php get_footer(); ?>
     11
     12get_header();
     13
     14// 1. Check if Ansar Elements has an active page template for the current page
     15$has_ansar_page = class_exists( 'Ansar_Elements_Theme_Builder_Elementor' )
     16    && Ansar_Elements_Theme_Builder_Elementor::instance()->full_page_template_id();
     17
     18if ( $has_ansar_page ) {
     19    // Render Ansar Elements Page Template
     20    do_action( 'ansarel_full_page' );
     21} else {
     22    // 2. Fallback to a Gutenberg Block Pattern
     23    // Replace 'blogger-mag/single-post-pattern' with your actual registered pattern slug
     24    echo do_blocks( '<!-- wp:pattern {"slug":"blogger-mag/single-post-pattern"} /-->' );
     25}
     26
     27get_footer();
  • blogger-mag/0.8/style.css

    r340927 r357015  
    55Author URI: https://themeansar.com
    66Description: Blogger Mag is a fast, modern, and customizable WordPress theme for news sites, magazines, and blogs. It features a mobile-friendly design, SEO optimization, multiple blog layouts, featured sections, and compatibility with Elementor and Gutenberg. Perfect for creating clean and engaging content websites. Live preview : https://sites.themeansar.com/ae/lite
    7 Version: 0.7
    8 Tested up to: 7.0
    9 Requires at least: 6.6
     7Version: 0.8
     8Tested up to: 7.1
     9Requires at least: 6.0
    1010Requires PHP: 7.4
    1111Tags: right-sidebar, flexible-header, custom-background, custom-header, custom-menu, editor-style, featured-images, footer-widgets,  theme-options, threaded-comments, rtl-language-support, translation-ready, full-width-template, custom-logo, blog, news
    … …  
    6969  border-style: solid;
    7070  transition: all 0.4s ease-in-out 0s;
    71   box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
    7271  color: #ff184e;
    7372  border-color: #ff184e;
Note: See TracChangeset for help on using the changeset viewer.