Plugin Directory

Changeset 3464401


Ignore:
Timestamp:
02/18/2026 02:19:24 PM (4 days ago)
Author:
alimran01
Message:

Added new v1.8.0 in trunk

Location:
spider-elements/trunk
Files:
5 added
24 edited

Legend:

Unmodified
Added
Removed
  • spider-elements/trunk/assets/css/admin.css

    r3316325 r3464401  
    3030.ezd-grid-cols-12 {
    3131  grid-template-columns: repeat(12, minmax(0, 1fr));
     32  width: 100%;
    3233}
    3334
     
    360361  justify-content: center;
    361362  margin-bottom: 20px;
    362 }
    363 .spel_dashboard .tab_contents .tab-box .support_item .dashboard_title {
    364   margin-bottom: 15px;
    365363}
    366364.spel_dashboard .tab_contents .tab-box .support_item p {
     
    408406.spel_dashboard .tab_contents .dashboard_btn.save_btn {
    409407  color: #fff;
    410   background: #6d27e5;
     408  background: #6d27e5 !important;
    411409  padding: 12px 24px;
    412410}
     
    714712  }
    715713}
    716 .spel_dashboard {
    717   /*============ qa_inner css ===============*/
    718 }
    719714.spel_dashboard .tab_contents .elements_tab_menu {
    720715  display: flex;
     
    856851  display: inline-block;
    857852  line-height: 1;
     853  position: relative;
    858854}
    859855.spel_dashboard .tab_contents .element_box .element_right .link {
     
    863859  transition: all 0.3s linear;
    864860}
    865 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top {
    866   position: relative;
     861.spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top {
    867862  display: inline-block;
    868863  text-decoration: none;
    869864}
    870 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top::before {
     865.spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top::before {
    871866  content: attr(data-tooltip);
    872   top: -40px;
    873   left: -20px;
     867  position: absolute;
     868  bottom: 100%;
     869  left: 50%;
    874870  transform: translateX(-50%);
    875871  background-color: #333;
     
    877873  text-align: center;
    878874  border-radius: 6px;
    879   padding: 8px 8px;
     875  padding: 6px 10px;
    880876  opacity: 0;
    881877  visibility: hidden;
    882878  transition: opacity 0.2s;
    883   position: absolute;
    884   width: 190px;
    885 }
    886 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top:hover::before {
     879  width: max-content;
     880  max-width: 200px;
     881  font-size: 11px;
     882  line-height: 1.4;
     883  z-index: 100;
     884  white-space: nowrap;
     885  margin-bottom: 2px;
     886}
     887.spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top:hover::before {
    887888  opacity: 1;
    888889  visibility: visible;
     
    897898  align-items: center;
    898899  position: relative;
    899   overflow: hidden;
    900900}
    901901.spel_dashboard .tab_contents .filter_content .element_switch .badge {
     
    11811181  transform: translate(-50%, -50%) scale(1.02);
    11821182}
     1183.spel_dashboard {
     1184  /*============ qa_inner css ===============*/
     1185}
    11831186.spel_dashboard .qa_inner {
    11841187  border-radius: 12px;
     
    14021405}
    14031406
     1407/**
     1408 * Spider Elements Dashboard - Enhanced Styles
     1409 * Modern UI/UX improvements with animations and better visual hierarchy
     1410 */
     1411:root {
     1412  --spel-primary: #7460ff;
     1413  --spel-primary-light: #9d70ff;
     1414  --spel-primary-dark: #5a4ad9;
     1415  --spel-secondary: #6d27e5;
     1416  --spel-success: #22c55e;
     1417  --spel-success-light: #dcfce7b5;
     1418  --spel-warning: #f59e0b;
     1419  --spel-warning-light: #fef3c7;
     1420  --spel-error: #ef4444;
     1421  --spel-error-light: #fee2e2;
     1422  --spel-info: #3b82f6;
     1423  --spel-info-light: #dbeafe;
     1424  --spel-bg-primary: #f8fafc;
     1425  --spel-bg-secondary: #fff;
     1426  --spel-bg-tertiary: #f1f5f9;
     1427  --spel-text-primary: #0f172a;
     1428  --spel-text-secondary: #475569;
     1429  --spel-text-muted: #94a3b8;
     1430  --spel-border: #e2e8f0;
     1431  --spel-border-light: #f1f5f9;
     1432  --spel-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
     1433  --spel-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
     1434    0 1px 2px -1px rgba(0, 0, 0, 0.1);
     1435  --spel-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
     1436    0 2px 4px -2px rgba(0, 0, 0, 0.1);
     1437  --spel-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
     1438    0 4px 6px -4px rgba(0, 0, 0, 0.1);
     1439  --spel-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
     1440    0 8px 10px -6px rgba(0, 0, 0, 0.1);
     1441  --spel-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
     1442  --spel-transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);
     1443  --spel-transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
     1444  --spel-radius-sm: 6px;
     1445  --spel-radius: 8px;
     1446  --spel-radius-md: 12px;
     1447  --spel-radius-lg: 16px;
     1448  --spel-radius-xl: 24px;
     1449}
     1450
     1451.spel_dashboard {
     1452  background: var(--spel-bg-primary);
     1453  min-height: calc(100vh - 32px);
     1454  position: relative;
     1455}
     1456.spel_dashboard::before {
     1457  content: "";
     1458  position: absolute;
     1459  top: 0;
     1460  left: 0;
     1461  right: 0;
     1462  height: 300px;
     1463  background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #c084fc 100%);
     1464  opacity: 0.05;
     1465  pointer-events: none;
     1466}
     1467
     1468.spel_dashboard .sidebar_navigation .sticky_sidebar {
     1469  background: var(--spel-bg-secondary);
     1470  border-radius: var(--spel-radius-lg);
     1471  box-shadow: var(--spel-shadow-md);
     1472  overflow: hidden;
     1473  border: 1px solid var(--spel-border-light);
     1474}
     1475.spel_dashboard .sidebar_navigation .tab_left_content {
     1476  padding: 8px;
     1477  margin: 0;
     1478}
     1479.spel_dashboard .sidebar_navigation .tab_left_content li {
     1480  margin-bottom: 4px;
     1481}
     1482.spel_dashboard .sidebar_navigation .tab_left_content li:last-child {
     1483  margin-bottom: 0;
     1484}
     1485.spel_dashboard .sidebar_navigation .tab_left_content li .icon {
     1486  width: 40px;
     1487  height: 40px;
     1488  border-radius: var(--spel-radius);
     1489  transition: all var(--spel-transition);
     1490  box-shadow: var(--spel-shadow-sm);
     1491}
     1492.spel_dashboard .sidebar_navigation .tab_left_content li .icon i {
     1493  font-size: 18px;
     1494  transition: transform var(--spel-transition);
     1495}
     1496.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link {
     1497  border-radius: var(--spel-radius);
     1498  overflow: hidden;
     1499  position: relative;
     1500  box-shadow: none;
     1501}
     1502.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link::before {
     1503  content: "";
     1504  position: absolute;
     1505  left: 0;
     1506  top: 50%;
     1507  transform: translateY(-50%);
     1508  width: 3px;
     1509  height: 0;
     1510  background: linear-gradient(180deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     1511  border-radius: 0 3px 3px 0;
     1512  transition: height var(--spel-transition);
     1513}
     1514.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .tab_menu_contents {
     1515  background: linear-gradient(90deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.04) 100%);
     1516}
     1517.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .icon {
     1518  transform: scale(1.05);
     1519}
     1520.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .icon i {
     1521  transform: scale(1.1);
     1522}
     1523.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents {
     1524  padding: 16px 20px;
     1525  transition: all var(--spel-transition);
     1526  border-radius: var(--spel-radius);
     1527}
     1528.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents .content h3 {
     1529  font-size: 15px;
     1530  font-weight: 600;
     1531  color: var(--spel-text-primary);
     1532  margin-bottom: 2px;
     1533  transition: color var(--spel-transition);
     1534}
     1535.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents .content p {
     1536  font-size: 13px;
     1537  color: var(--spel-text-secondary);
     1538  transition: color var(--spel-transition);
     1539}
     1540.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active {
     1541  background: linear-gradient(90deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.02) 100%);
     1542}
     1543.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active::before {
     1544  height: 60%;
     1545}
     1546.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents {
     1547  background: transparent;
     1548  box-shadow: none;
     1549}
     1550.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .icon {
     1551  background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%) !important;
     1552  box-shadow: var(--spel-shadow-md);
     1553}
     1554.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .icon i {
     1555  color: #fff;
     1556}
     1557.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .content h3 {
     1558  color: var(--spel-primary) !important;
     1559}
     1560.spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .content p {
     1561  color: var(--spel-text-secondary) !important;
     1562}
     1563
     1564.spel_dashboard .tab_contents {
     1565  position: relative;
     1566}
     1567.spel_dashboard .tab_contents .tab-box {
     1568  animation: fadeIn var(--spel-transition-slow) ease-out;
     1569}
     1570@keyframes fadeIn {
     1571  from {
     1572    opacity: 0;
     1573    transform: translateY(10px);
     1574  }
     1575  to {
     1576    opacity: 1;
     1577    transform: translateY(0);
     1578  }
     1579}
     1580.spel_dashboard .tab_contents .dashboard_banner {
     1581  position: relative;
     1582  overflow: hidden;
     1583  border-radius: var(--spel-radius-lg);
     1584  padding: 50px 60px;
     1585  background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #a78bfa 100%);
     1586  box-shadow: var(--spel-shadow-xl);
     1587  display: flex;
     1588  align-items: center;
     1589  justify-content: space-between;
     1590  gap: 40px;
     1591}
     1592.spel_dashboard .tab_contents .dashboard_banner::before {
     1593  content: "";
     1594  position: absolute;
     1595  top: -50%;
     1596  right: -20%;
     1597  width: 500px;
     1598  height: 500px;
     1599  background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%);
     1600  animation: floatBubble 15s infinite ease-in-out;
     1601}
     1602.spel_dashboard .tab_contents .dashboard_banner::after {
     1603  content: "";
     1604  position: absolute;
     1605  bottom: -30%;
     1606  left: -10%;
     1607  width: 400px;
     1608  height: 400px;
     1609  background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 60%);
     1610  animation: floatBubble 20s infinite ease-in-out reverse;
     1611}
     1612@keyframes floatBubble {
     1613  0%, 100% {
     1614    transform: translate(0, 0) scale(1);
     1615  }
     1616  50% {
     1617    transform: translate(30px, -30px) scale(1.1);
     1618  }
     1619}
     1620.spel_dashboard .tab_contents .dashboard_banner .banner_content {
     1621  position: relative;
     1622  z-index: 2;
     1623  flex: 1;
     1624  padding-right: 40px;
     1625}
     1626.spel_dashboard .tab_contents .dashboard_banner .version_badge {
     1627  display: inline-flex;
     1628  align-items: center;
     1629  gap: 6px;
     1630  padding: 6px 14px;
     1631  background: rgba(255, 255, 255, 0.2);
     1632  backdrop-filter: blur(8px);
     1633  border-radius: 50px;
     1634  font-size: 12px;
     1635  font-weight: 600;
     1636  color: #fff;
     1637  margin-bottom: 16px;
     1638  border: 1px solid rgba(255, 255, 255, 0.2);
     1639}
     1640.spel_dashboard .tab_contents .dashboard_banner .version_badge i {
     1641  font-size: 14px;
     1642}
     1643.spel_dashboard .tab_contents .dashboard_banner h2 {
     1644  font-size: 32px;
     1645  font-weight: 700;
     1646  color: #fff;
     1647  margin-bottom: 12px;
     1648  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
     1649}
     1650.spel_dashboard .tab_contents .dashboard_banner p {
     1651  font-size: 15px;
     1652  color: rgba(255, 255, 255, 0.9);
     1653  max-width: 600px;
     1654  line-height: 1.7;
     1655}
     1656.spel_dashboard .tab_contents .dashboard_banner img {
     1657  filter: drop-shadow(0 4px 20px rgba(0, 0, 0, 0.2));
     1658  transition: transform var(--spel-transition);
     1659  max-width: 280px;
     1660  height: auto;
     1661  object-fit: contain;
     1662  flex-shrink: 0;
     1663}
     1664.spel_dashboard .tab_contents .dashboard_banner img:hover {
     1665  transform: scale(1.02);
     1666}
     1667.spel_dashboard .tab_contents .quick_stats {
     1668  display: grid;
     1669  grid-template-columns: repeat(4, 1fr);
     1670  gap: 20px;
     1671  margin-top: 24px;
     1672  margin-bottom: 24px;
     1673}
     1674@media (max-width: 1200px) {
     1675  .spel_dashboard .tab_contents .quick_stats {
     1676    grid-template-columns: repeat(2, 1fr);
     1677  }
     1678}
     1679@media (max-width: 768px) {
     1680  .spel_dashboard .tab_contents .quick_stats {
     1681    grid-template-columns: 1fr;
     1682  }
     1683}
     1684.spel_dashboard .tab_contents .stat_card {
     1685  background: var(--spel-bg-secondary);
     1686  border-radius: var(--spel-radius-md);
     1687  padding: 24px;
     1688  box-shadow: var(--spel-shadow);
     1689  border: 1px solid var(--spel-border-light);
     1690  transition: all var(--spel-transition);
     1691  position: relative;
     1692  overflow: hidden;
     1693}
     1694.spel_dashboard .tab_contents .stat_card::before {
     1695  content: "";
     1696  position: absolute;
     1697  top: 0;
     1698  left: 0;
     1699  width: 4px;
     1700  height: 100%;
     1701  border-radius: 4px 0 0 4px;
     1702  transition: width var(--spel-transition);
     1703}
     1704.spel_dashboard .tab_contents .stat_card:hover {
     1705  transform: translateY(-2px);
     1706  box-shadow: var(--spel-shadow-lg);
     1707}
     1708.spel_dashboard .tab_contents .stat_card:hover::before {
     1709  width: 100%;
     1710  opacity: 0.1;
     1711}
     1712.spel_dashboard .tab_contents .stat_card:hover .stat_icon {
     1713  transform: scale(1.1) rotate(5deg);
     1714}
     1715.spel_dashboard .tab_contents .stat_card:hover .stat_icon {
     1716  transform: scale(1.1);
     1717}
     1718.spel_dashboard .tab_contents .stat_card.stat_elements::before {
     1719  background: linear-gradient(180deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     1720}
     1721.spel_dashboard .tab_contents .stat_card.stat_features::before {
     1722  background: linear-gradient(180deg, var(--spel-success) 0%, #34d399 100%);
     1723}
     1724.spel_dashboard .tab_contents .stat_card.stat_active::before {
     1725  background: linear-gradient(180deg, var(--spel-info) 0%, #60a5fa 100%);
     1726}
     1727.spel_dashboard .tab_contents .stat_card.stat_pro::before {
     1728  background: linear-gradient(180deg, #ec4899 0%, #f472b6 100%);
     1729}
     1730.spel_dashboard .tab_contents .stat_card .stat_header {
     1731  display: flex;
     1732  align-items: center;
     1733  justify-content: space-between;
     1734  margin-bottom: 16px;
     1735}
     1736.spel_dashboard .tab_contents .stat_card .stat_icon {
     1737  width: 48px;
     1738  height: 48px;
     1739  border-radius: var(--spel-radius);
     1740  display: flex;
     1741  align-items: center;
     1742  justify-content: center;
     1743  font-size: 22px;
     1744  transition: transform var(--spel-transition);
     1745}
     1746.spel_dashboard .tab_contents .stat_card.stat_elements .stat_icon {
     1747  background: linear-gradient(135deg, rgba(116, 96, 255, 0.12) 0%, rgba(157, 112, 255, 0.08) 100%);
     1748  color: var(--spel-primary);
     1749}
     1750.spel_dashboard .tab_contents .stat_card.stat_features .stat_icon {
     1751  background: linear-gradient(135deg, rgba(34, 197, 94, 0.12) 0%, rgba(52, 211, 153, 0.08) 100%);
     1752  color: var(--spel-success);
     1753}
     1754.spel_dashboard .tab_contents .stat_card.stat_active .stat_icon {
     1755  background: linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(96, 165, 250, 0.08) 100%);
     1756  color: var(--spel-info);
     1757}
     1758.spel_dashboard .tab_contents .stat_card.stat_pro .stat_icon {
     1759  background: linear-gradient(135deg, rgba(236, 72, 153, 0.12) 0%, rgba(244, 114, 182, 0.08) 100%);
     1760  color: #ec4899;
     1761}
     1762.spel_dashboard .tab_contents .stat_card .stat_value {
     1763  font-size: 32px;
     1764  font-weight: 700;
     1765  color: var(--spel-text-primary);
     1766  font-family: "Roboto", sans-serif;
     1767  line-height: 1;
     1768}
     1769.spel_dashboard .tab_contents .stat_card .stat_label {
     1770  font-size: 13px;
     1771  color: var(--spel-text-secondary);
     1772  margin-top: 4px;
     1773  font-weight: 500;
     1774}
     1775.spel_dashboard .tab_contents .stat_card .stat_trend {
     1776  display: inline-flex;
     1777  align-items: center;
     1778  gap: 4px;
     1779  font-size: 12px;
     1780  font-weight: 600;
     1781  padding: 4px 8px;
     1782  border-radius: 50px;
     1783}
     1784.spel_dashboard .tab_contents .stat_card .stat_trend.trend_up {
     1785  color: var(--spel-success);
     1786  background: var(--spel-success-light);
     1787}
     1788.spel_dashboard .tab_contents .stat_card .stat_trend.trend_info {
     1789  color: var(--spel-info);
     1790  background: var(--spel-info-light);
     1791}
     1792.spel_dashboard .tab_contents .support_item {
     1793  background: var(--spel-bg-secondary);
     1794  border-radius: var(--spel-radius-md);
     1795  padding: 32px;
     1796  border: 1px solid var(--spel-border-light);
     1797  box-shadow: var(--spel-shadow);
     1798  transition: all var(--spel-transition);
     1799  display: flex;
     1800  flex-direction: column;
     1801  align-items: flex-start;
     1802}
     1803.spel_dashboard .tab_contents .support_item:hover {
     1804  box-shadow: var(--spel-shadow-lg);
     1805  transform: translateY(-2px);
     1806  border-color: rgba(116, 96, 255, 0.2);
     1807}
     1808.spel_dashboard .tab_contents .support_item:hover .icon {
     1809  transform: scale(1.1) rotate(-5deg);
     1810}
     1811.spel_dashboard .tab_contents .support_item .icon {
     1812  width: 60px;
     1813  height: 60px;
     1814  background: linear-gradient(135deg, rgba(116, 96, 255, 0.12) 0%, rgba(157, 112, 255, 0.08) 100%);
     1815  border-radius: var(--spel-radius-md);
     1816  font-size: 26px;
     1817  color: var(--spel-primary);
     1818  display: flex;
     1819  align-items: center;
     1820  justify-content: center;
     1821  margin-bottom: 20px;
     1822  transition: transform var(--spel-transition);
     1823}
     1824.spel_dashboard .tab_contents .support_item .dashboard_title {
     1825  font-size: 20px;
     1826  font-weight: 600;
     1827  color: var(--spel-text-primary);
     1828  margin-bottom: 0;
     1829}
     1830.spel_dashboard .tab_contents .support_item p {
     1831  font-size: 14px;
     1832  color: var(--spel-text-secondary);
     1833  line-height: 1.7;
     1834  margin-bottom: 20px;
     1835}
     1836.spel_dashboard .tab_contents .quick_links_grid {
     1837  margin-top: 30px;
     1838}
     1839.spel_dashboard .tab_contents .quick_links_grid .ezd-lg-col-6 {
     1840  margin-bottom: 24px;
     1841}
     1842.spel_dashboard .tab_contents .section_header.has_flex {
     1843  display: flex;
     1844  align-items: center;
     1845  justify-content: space-between;
     1846  margin-bottom: 25px;
     1847  gap: 10px;
     1848}
     1849.spel_dashboard .tab_contents .badge_success {
     1850  display: inline-flex;
     1851  align-items: center;
     1852  gap: 6px;
     1853  padding: 6px 14px;
     1854  border-radius: 50px;
     1855  font-size: 12px;
     1856  font-weight: 600;
     1857  background: var(--spel-success-light);
     1858  color: var(--spel-success);
     1859  border: 1px solid rgba(34, 197, 94, 0.2);
     1860}
     1861.spel_dashboard .tab_contents .badge_success i {
     1862  font-size: 14px;
     1863}
     1864.spel_dashboard .tab_contents .note {
     1865  margin-top: 24px;
     1866  padding: 16px 20px;
     1867  background: rgba(59, 130, 246, 0.08);
     1868  border-radius: var(--spel-radius);
     1869  border: 1px solid rgba(59, 130, 246, 0.2);
     1870  display: flex;
     1871  gap: 16px;
     1872  align-items: flex-start;
     1873}
     1874.spel_dashboard .tab_contents .note i {
     1875  font-size: 20px;
     1876  color: var(--spel-info);
     1877  flex-shrink: 0;
     1878  margin-top: 2px;
     1879}
     1880.spel_dashboard .tab_contents .note p {
     1881  margin: 0;
     1882  font-size: 14px;
     1883  color: var(--spel-text-secondary);
     1884  line-height: 1.6;
     1885}
     1886.spel_dashboard .tab_contents .requirement_list {
     1887  border-radius: var(--spel-radius);
     1888  overflow: hidden;
     1889  border: 1px solid var(--spel-border-light);
     1890}
     1891.spel_dashboard .tab_contents .requirement_list li {
     1892  background: var(--spel-bg-secondary);
     1893  padding: 18px 24px;
     1894  border-bottom: 1px solid var(--spel-border-light);
     1895  display: flex;
     1896  align-items: center;
     1897  transition: background var(--spel-transition);
     1898}
     1899.spel_dashboard .tab_contents .requirement_list li:nth-child(odd) {
     1900  background: rgba(241, 245, 249, 0.7);
     1901}
     1902.spel_dashboard .tab_contents .requirement_list li:last-child {
     1903  border-bottom: none;
     1904}
     1905.spel_dashboard .tab_contents .requirement_list li:hover {
     1906  background: var(--spel-bg-tertiary);
     1907}
     1908.spel_dashboard .tab_contents .requirement_list li strong {
     1909  font-size: 14px;
     1910  font-weight: 600;
     1911  color: var(--spel-text-primary);
     1912  flex: 0 0 50%;
     1913}
     1914.spel_dashboard .tab_contents .requirement_list li span {
     1915  font-size: 14px;
     1916  color: var(--spel-text-secondary);
     1917  display: flex;
     1918  align-items: center;
     1919  gap: 12px;
     1920  font-weight: 500;
     1921}
     1922.spel_dashboard .tab_contents .requirement_list li span.valid i {
     1923  background: var(--spel-success);
     1924  box-shadow: 0 2px 4px rgba(34, 197, 94, 0.4);
     1925  transform: scale(1.1);
     1926}
     1927.spel_dashboard .tab_contents .requirement_list li span.invalid i {
     1928  background: var(--spel-error);
     1929  box-shadow: 0 2px 4px rgba(239, 68, 68, 0.4);
     1930}
     1931.spel_dashboard .tab_contents .requirement_list li i {
     1932  font-size: 10px;
     1933  width: 24px;
     1934  height: 24px;
     1935  display: inline-flex;
     1936  align-items: center;
     1937  justify-content: center;
     1938  border-radius: 50%;
     1939  color: #fff;
     1940  transition: transform var(--spel-transition);
     1941}
     1942.spel_dashboard .tab_contents .dashboard_btn {
     1943  display: inline-flex;
     1944  align-items: center;
     1945  justify-content: center;
     1946  gap: 8px;
     1947  padding: 12px 24px;
     1948  font-size: 14px;
     1949  font-weight: 600;
     1950  color: var(--spel-primary);
     1951  background: transparent;
     1952  border: 2px solid var(--spel-primary);
     1953  border-radius: var(--spel-radius);
     1954  text-decoration: none;
     1955  cursor: pointer;
     1956  transition: all var(--spel-transition);
     1957  position: relative;
     1958  overflow: hidden;
     1959}
     1960.spel_dashboard .tab_contents .dashboard_btn::before {
     1961  content: "";
     1962  position: absolute;
     1963  top: 0;
     1964  left: 0;
     1965  width: 100%;
     1966  height: 100%;
     1967  background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     1968  opacity: 0;
     1969  transition: opacity var(--spel-transition);
     1970  z-index: -1;
     1971}
     1972.spel_dashboard .tab_contents .dashboard_btn:hover {
     1973  color: #fff;
     1974  color: #fff;
     1975  border-color: var(--spel-primary);
     1976  transform: translateY(-2px);
     1977  box-shadow: 0 4px 15px rgba(116, 96, 255, 0.35);
     1978}
     1979.spel_dashboard .tab_contents .dashboard_btn:hover::before {
     1980  opacity: 1;
     1981}
     1982.spel_dashboard .tab_contents .dashboard_btn:hover i {
     1983  transform: translateX(3px);
     1984}
     1985.spel_dashboard .tab_contents .dashboard_btn i {
     1986  transition: transform var(--spel-transition);
     1987}
     1988.spel_dashboard .tab_contents .dashboard_btn.save_btn {
     1989  color: #fff;
     1990  background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     1991  border: none;
     1992  padding: 14px 28px;
     1993  box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25);
     1994}
     1995.spel_dashboard .tab_contents .dashboard_btn.save_btn:hover {
     1996  box-shadow: 0 6px 20px rgba(116, 96, 255, 0.4);
     1997  transform: translateY(-2px);
     1998}
     1999.spel_dashboard .tab_contents .dashboard_btn.save_btn.save-now {
     2000  animation: pulse 1.5s infinite;
     2001}
     2002@keyframes pulse {
     2003  0%, 100% {
     2004    box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25);
     2005  }
     2006  50% {
     2007    box-shadow: 0 2px 20px rgba(116, 96, 255, 0.5);
     2008  }
     2009}
     2010.spel_dashboard .tab_contents .dashboard_btn.activated {
     2011  background: var(--spel-success-light);
     2012  color: var(--spel-success);
     2013  border-color: var(--spel-success-light);
     2014  pointer-events: none;
     2015}
     2016.spel_dashboard .tab_contents .dashboard_btn.activated::before {
     2017  display: none;
     2018}
     2019.spel_dashboard .tab_contents .elements_tab_menu {
     2020  background: var(--spel-bg-secondary);
     2021  border-radius: var(--spel-radius-md);
     2022  padding: 20px 24px;
     2023  box-shadow: var(--spel-shadow);
     2024  border: 1px solid var(--spel-border-light);
     2025  margin-bottom: 0;
     2026}
     2027.spel_dashboard .tab_contents .elements_tab_menu .tab_contents .icon {
     2028  width: 44px;
     2029  height: 44px;
     2030  border-radius: var(--spel-radius);
     2031  font-size: 20px;
     2032}
     2033.spel_dashboard .tab_contents .elements_tab_menu .tab_contents .content h3 {
     2034  font-size: 18px;
     2035  font-weight: 700;
     2036  color: var(--spel-text-primary);
     2037}
     2038.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content {
     2039  gap: 20px;
     2040}
     2041.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher {
     2042  background: var(--spel-bg-tertiary);
     2043  padding: 8px 16px;
     2044  border-radius: var(--spel-radius);
     2045}
     2046.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .toggler {
     2047  font-size: 13px;
     2048  font-weight: 500;
     2049  color: var(--spel-text-secondary);
     2050  transition: color var(--spel-transition);
     2051  line-height: 2;
     2052}
     2053.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .toggler:hover {
     2054  color: var(--spel-text-primary);
     2055}
     2056.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .switch {
     2057  width: 44px;
     2058  height: 24px;
     2059  background: var(--spel-text-muted);
     2060  border-radius: 50px;
     2061  margin: 0 16px;
     2062}
     2063.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .switch::before {
     2064  width: 18px;
     2065  height: 18px;
     2066  border-radius: 50%;
     2067  left: 3px;
     2068  top: 3px;
     2069  box-shadow: var(--spel-shadow-sm);
     2070}
     2071.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher input:checked + .switch {
     2072  background: linear-gradient(90deg, var(--spel-success) 0%, #34d399 100%);
     2073}
     2074.spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher input:checked + .switch::before {
     2075  transform: translateX(20px);
     2076}
     2077.spel_dashboard .tab_contents .elements_tab {
     2078  background: var(--spel-bg-secondary);
     2079  padding: 12px 16px;
     2080  border-radius: var(--spel-radius);
     2081  margin: 20px 0;
     2082  display: flex;
     2083  gap: 8px;
     2084  box-shadow: var(--spel-shadow-sm);
     2085  border: 1px solid var(--spel-border-light);
     2086}
     2087.spel_dashboard .tab_contents .elements_tab .filter_data {
     2088  padding: 10px 20px;
     2089  font-size: 14px;
     2090  font-weight: 500;
     2091  color: var(--spel-text-secondary);
     2092  border-radius: var(--spel-radius-sm);
     2093  cursor: pointer;
     2094  transition: all var(--spel-transition);
     2095  display: flex;
     2096  align-items: center;
     2097  gap: 8px;
     2098}
     2099.spel_dashboard .tab_contents .elements_tab .filter_data i {
     2100  font-size: 14px;
     2101  transition: transform var(--spel-transition);
     2102}
     2103.spel_dashboard .tab_contents .elements_tab .filter_data:hover {
     2104  background: var(--spel-bg-tertiary);
     2105  color: var(--spel-text-primary);
     2106}
     2107.spel_dashboard .tab_contents .elements_tab .filter_data:hover i {
     2108  transform: scale(1.15);
     2109}
     2110.spel_dashboard .tab_contents .elements_tab .filter_data.active {
     2111  background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     2112  color: #fff;
     2113  box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25);
     2114}
     2115.spel_dashboard .tab_contents .spel_search_box {
     2116  background: var(--spel-bg-secondary);
     2117  padding: 16px 20px;
     2118  border-radius: var(--spel-radius);
     2119  margin-bottom: 20px;
     2120  box-shadow: var(--spel-shadow-sm);
     2121  border: 1px solid var(--spel-border-light);
     2122  display: flex;
     2123  align-items: center;
     2124  gap: 12px;
     2125  margin-top: 5px;
     2126}
     2127.spel_dashboard .tab_contents .spel_search_box .search_icon {
     2128  color: var(--spel-text-muted);
     2129  font-size: 18px;
     2130}
     2131.spel_dashboard .tab_contents .spel_search_box input {
     2132  flex: 1;
     2133  border: none;
     2134  background: transparent;
     2135  font-size: 14px;
     2136  color: var(--spel-text-primary);
     2137  outline: none;
     2138}
     2139.spel_dashboard .tab_contents .spel_search_box input::placeholder {
     2140  color: var(--spel-text-muted);
     2141}
     2142.spel_dashboard .tab_contents .spel_search_box .search_count {
     2143  font-size: 13px;
     2144  color: var(--spel-text-muted);
     2145  padding: 4px 10px;
     2146  background: var(--spel-bg-tertiary);
     2147  border-radius: var(--spel-radius-sm);
     2148}
     2149.spel_dashboard .tab_contents .element_box {
     2150  background: var(--spel-bg-secondary);
     2151  border-radius: var(--spel-radius-md);
     2152  padding: 26px;
     2153  box-shadow: var(--spel-shadow);
     2154  border: 1px solid var(--spel-border-light);
     2155  transition: all var(--spel-transition);
     2156  position: relative;
     2157  overflow: hidden;
     2158}
     2159.spel_dashboard .tab_contents .element_box::before {
     2160  content: "";
     2161  position: absolute;
     2162  top: 0;
     2163  left: 0;
     2164  right: 0;
     2165  height: 3px;
     2166  background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%);
     2167  opacity: 0;
     2168  transition: opacity var(--spel-transition);
     2169}
     2170.spel_dashboard .tab_contents .element_box:hover {
     2171  transform: translateY(-3px);
     2172  box-shadow: var(--spel-shadow-lg);
     2173  border-color: rgba(116, 96, 255, 0.2);
     2174}
     2175.spel_dashboard .tab_contents .element_box:hover::before {
     2176  opacity: 1;
     2177}
     2178.spel_dashboard .tab_contents .element_box:hover .element_content i {
     2179  transform: scale(1.15);
     2180  color: var(--spel-primary);
     2181}
     2182.spel_dashboard .tab_contents .element_box:hover .element_right .link {
     2183  opacity: 1;
     2184  visibility: visible;
     2185  transform: translateX(0);
     2186}
     2187.spel_dashboard .tab_contents .element_box .element_content i {
     2188  font-size: 28px;
     2189  color: var(--spel-text-primary);
     2190  margin-right: 16px;
     2191  transition: all var(--spel-transition);
     2192}
     2193.spel_dashboard .tab_contents .element_box .element_content label {
     2194  font-size: 14px;
     2195  font-weight: 500;
     2196  color: var(--spel-text-primary);
     2197}
     2198.spel_dashboard .tab_contents .element_box .element_right .link {
     2199  opacity: 0;
     2200  visibility: hidden;
     2201  transform: translateX(-5px);
     2202  transition: all var(--spel-transition);
     2203  display: flex;
     2204  gap: 8px;
     2205}
     2206.spel_dashboard .tab_contents .element_box .element_right .link a {
     2207  width: 28px;
     2208  height: 28px;
     2209  display: flex !important;
     2210  align-items: center;
     2211  justify-content: center;
     2212  background: var(--spel-bg-tertiary);
     2213  border-radius: var(--spel-radius-sm);
     2214  transition: all var(--spel-transition);
     2215}
     2216.spel_dashboard .tab_contents .element_box .element_right .link a:hover {
     2217  background: var(--spel-primary);
     2218}
     2219.spel_dashboard .tab_contents .element_box .element_right .link a:hover img {
     2220  filter: brightness(0) invert(1);
     2221}
     2222.spel_dashboard .tab_contents .element_box .element_right .link a img {
     2223  width: 14px;
     2224  height: 14px;
     2225  transition: filter var(--spel-transition);
     2226}
     2227.spel_dashboard .tab_contents .element_box .element_right .switch_label {
     2228  cursor: pointer;
     2229}
     2230.spel_dashboard .tab_contents .element_box .element_right .switch_label .widget_switcher {
     2231  width: 44px;
     2232  height: 24px;
     2233  background: var(--spel-text-muted);
     2234  border-radius: 50px;
     2235  position: relative;
     2236  transition: background var(--spel-transition);
     2237}
     2238.spel_dashboard .tab_contents .element_box .element_right .switch_label .widget_switcher::before {
     2239  width: 18px;
     2240  height: 18px;
     2241  border-radius: 50%;
     2242  left: 3px;
     2243  top: 3px;
     2244  box-shadow: var(--spel-shadow-sm);
     2245  transition: transform var(--spel-transition);
     2246}
     2247.spel_dashboard .tab_contents .element_box .element_right .switch_label input:checked + .widget_switcher {
     2248  background: linear-gradient(90deg, var(--spel-success) 0%, #34d399 100%);
     2249}
     2250.spel_dashboard .tab_contents .element_box .element_right .switch_label input:checked + .widget_switcher::before {
     2251  transform: translateX(20px);
     2252}
     2253.spel_dashboard .tab_contents .element_box .element_right .switch_label input:disabled + .widget_switcher {
     2254  opacity: 0.5;
     2255  cursor: not-allowed;
     2256}
     2257.spel_dashboard .tab_contents .filter_content .pro .badge::before {
     2258  width: 70px;
     2259  height: 70px;
     2260  left: -38px;
     2261  top: -38px;
     2262  font-size: 9px;
     2263  font-weight: 700;
     2264  background: linear-gradient(135deg, #ec4899 0%, #f472b6 100%);
     2265  letter-spacing: 0.5px;
     2266}
     2267.spel_dashboard .tab_contents .integration_banner {
     2268  background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #a78bfa 100%) !important;
     2269  padding: 45px 50px !important;
     2270  border-radius: var(--spel-radius-lg) !important;
     2271}
     2272.spel_dashboard .tab_contents .integration_banner h2 {
     2273  font-size: 28px !important;
     2274  font-weight: 700 !important;
     2275}
     2276.spel_dashboard .tab_contents .integration_banner p {
     2277  font-size: 15px !important;
     2278  max-width: 700px;
     2279}
     2280.spel_dashboard .tab_contents .integration_item {
     2281  background: var(--spel-bg-secondary);
     2282  border-radius: var(--spel-radius-md);
     2283  padding: 32px;
     2284  box-shadow: var(--spel-shadow);
     2285  border: 1px solid var(--spel-border-light);
     2286  transition: all var(--spel-transition);
     2287}
     2288.spel_dashboard .tab_contents .integration_item:hover {
     2289  transform: translateY(-4px);
     2290  box-shadow: var(--spel-shadow-lg);
     2291  border-color: rgba(116, 96, 255, 0.2);
     2292}
     2293.spel_dashboard .tab_contents .integration_item:hover img {
     2294  transform: scale(1.1);
     2295}
     2296.spel_dashboard .tab_contents .integration_item img {
     2297  width: 52px;
     2298  height: auto;
     2299  transition: transform var(--spel-transition);
     2300}
     2301.spel_dashboard .tab_contents .integration_item h3 {
     2302  font-size: 17px;
     2303  font-weight: 600;
     2304  color: var(--spel-text-primary);
     2305  margin-top: 16px;
     2306  margin-bottom: 10px;
     2307}
     2308.spel_dashboard .tab_contents .integration_item p {
     2309  font-size: 14px;
     2310  color: var(--spel-text-secondary);
     2311  line-height: 1.65;
     2312  min-height: 50px;
     2313}
     2314.spel_dashboard .tab_contents .integration_item .action_buttons {
     2315  display: flex;
     2316  gap: 10px;
     2317  justify-content: center;
     2318  align-items: center;
     2319  margin-top: 20px;
     2320}
     2321.spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn {
     2322  width: 100%;
     2323}
     2324.spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn.learn_more_btn {
     2325  background: var(--spel-bg-tertiary);
     2326  color: var(--spel-text-secondary);
     2327  border: 1px solid var(--spel-border-light);
     2328}
     2329.spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn.learn_more_btn:hover {
     2330  background: var(--spel-bg-primary);
     2331  color: #fff;
     2332  border-color: var(--spel-border);
     2333}
     2334.spel_dashboard .tab_contents .note {
     2335  background: linear-gradient(135deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.04) 100%);
     2336  border: 1px solid rgba(116, 96, 255, 0.1);
     2337  padding: 16px 24px;
     2338  margin-top: 20px;
     2339  border-radius: var(--spel-radius);
     2340  display: flex;
     2341  align-items: flex-start;
     2342  gap: 12px;
     2343}
     2344.spel_dashboard .tab_contents .note::before {
     2345  content: "\f05a";
     2346  font-family: "Font Awesome 6 Pro", "Font Awesome 5 Free", sans-serif;
     2347  font-weight: 900;
     2348  color: var(--spel-primary);
     2349  font-size: 18px;
     2350  margin-top: 2px;
     2351}
     2352.spel_dashboard .tab_contents .note p {
     2353  font-size: 13px !important;
     2354  color: var(--spel-text-secondary) !important;
     2355  line-height: 1.6 !important;
     2356  margin: 0 !important;
     2357}
     2358.spel_dashboard .tab_contents .elements_pro_popup .message_content {
     2359  border-radius: var(--spel-radius-lg);
     2360  padding: 48px 40px;
     2361  max-width: 420px;
     2362  box-shadow: var(--spel-shadow-xl);
     2363}
     2364.spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close {
     2365  position: absolute;
     2366  right: 16px;
     2367  top: 16px;
     2368  width: 32px;
     2369  height: 32px;
     2370  background: var(--spel-bg-tertiary);
     2371  border-radius: 50%;
     2372  display: flex;
     2373  align-items: center;
     2374  justify-content: center;
     2375  cursor: pointer;
     2376  transition: all var(--spel-transition);
     2377}
     2378.spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close:hover {
     2379  background: var(--spel-error-light);
     2380}
     2381.spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close img {
     2382  width: 12px;
     2383  opacity: 0.7;
     2384}
     2385.spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-icon {
     2386  width: 72px;
     2387  height: 72px;
     2388  background: linear-gradient(135deg, rgba(236, 72, 153, 0.1) 0%, rgba(244, 114, 182, 0.05) 100%);
     2389  border-radius: 50%;
     2390  display: flex;
     2391  align-items: center;
     2392  justify-content: center;
     2393  margin: 0 auto 20px;
     2394}
     2395.spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-icon img {
     2396  width: 36px;
     2397}
     2398.spel_dashboard .tab_contents .elements_pro_popup .message_content h3 {
     2399  font-size: 24px;
     2400  font-weight: 700;
     2401  color: var(--spel-text-primary);
     2402  margin-bottom: 10px;
     2403}
     2404.spel_dashboard .tab_contents .elements_pro_popup .message_content p {
     2405  font-size: 15px;
     2406  color: var(--spel-text-secondary);
     2407  line-height: 1.6;
     2408}
     2409.spel_dashboard .tab_contents .elements_pro_popup .message_content .dashboard_btn {
     2410  margin-top: 16px;
     2411  background: linear-gradient(90deg, #ec4899 0%, #f472b6 100%);
     2412  border: none;
     2413  color: #fff;
     2414}
     2415.spel_dashboard .tab_contents .elements_pro_popup .message_content .dashboard_btn:hover {
     2416  box-shadow: 0 6px 20px rgba(236, 72, 153, 0.4);
     2417}
     2418
     2419.spel_toast {
     2420  position: fixed;
     2421  bottom: 24px;
     2422  right: 24px;
     2423  background: var(--spel-bg-secondary);
     2424  padding: 16px 24px;
     2425  border-radius: var(--spel-radius);
     2426  box-shadow: var(--spel-shadow-xl);
     2427  display: flex;
     2428  align-items: center;
     2429  gap: 12px;
     2430  z-index: 9999;
     2431  transform: translateY(100px);
     2432  opacity: 0;
     2433  transition: all var(--spel-transition-slow);
     2434  border-left: 4px solid var(--spel-success);
     2435}
     2436.spel_toast.show {
     2437  transform: translateY(0);
     2438  opacity: 1;
     2439}
     2440.spel_toast.toast_error {
     2441  border-left-color: var(--spel-error);
     2442}
     2443.spel_toast.toast_error .toast_icon {
     2444  background: var(--spel-error-light);
     2445  color: var(--spel-error);
     2446}
     2447.spel_toast .toast_icon {
     2448  width: 36px;
     2449  height: 36px;
     2450  background: var(--spel-success-light);
     2451  color: var(--spel-success);
     2452  border-radius: var(--spel-radius-sm);
     2453  display: flex;
     2454  align-items: center;
     2455  justify-content: center;
     2456  font-size: 18px;
     2457}
     2458.spel_toast .toast_content h4 {
     2459  font-size: 14px;
     2460  font-weight: 600;
     2461  color: var(--spel-text-primary);
     2462  margin: 0 0 2px;
     2463}
     2464.spel_toast .toast_content p {
     2465  font-size: 13px;
     2466  color: var(--spel-text-secondary);
     2467  margin: 0;
     2468}
     2469.spel_toast .toast_close {
     2470  margin-left: 16px;
     2471  cursor: pointer;
     2472  color: var(--spel-text-muted);
     2473  transition: color var(--spel-transition);
     2474}
     2475.spel_toast .toast_close:hover {
     2476  color: var(--spel-text-primary);
     2477}
     2478
     2479@media (max-width: 1400px) {
     2480  .spel_dashboard .tab_contents .dashboard_banner {
     2481    padding: 40px;
     2482  }
     2483  .spel_dashboard .tab_contents .dashboard_banner h2 {
     2484    font-size: 28px;
     2485  }
     2486  .spel_dashboard .tab_contents .stat_card {
     2487    padding: 20px;
     2488  }
     2489  .spel_dashboard .tab_contents .stat_card .stat_value {
     2490    font-size: 28px;
     2491  }
     2492}
     2493@media (max-width: 1200px) {
     2494  .spel_dashboard .tab_contents .quick_stats {
     2495    grid-template-columns: repeat(2, 1fr);
     2496  }
     2497}
     2498@media (max-width: 768px) {
     2499  .spel_dashboard .tab_contents .quick_stats {
     2500    grid-template-columns: 1fr;
     2501  }
     2502  .spel_dashboard .tab_contents .elements_tab_menu {
     2503    flex-direction: column;
     2504    gap: 16px;
     2505  }
     2506  .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content {
     2507    width: 100%;
     2508    justify-content: space-between;
     2509  }
     2510  .spel_dashboard .tab_contents .elements_tab {
     2511    flex-wrap: wrap;
     2512  }
     2513}
     2514
    14042515/*# sourceMappingURL=admin.css.map */
  • spider-elements/trunk/assets/css/admin.css.map

    r3258212 r3464401  
    1 {"version":3,"sourceRoot":"","sources":["../scss/admin.scss","../scss/admin/_notice.scss","../scss/admin/_framework.scss","../scss/admin/_welcome.scss","../scss/admin/_elements.scss","../scss/admin/_theme_builder.scss"],"names":[],"mappings":"AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;ACAA;EACE;;AACA;EACE;EACA;EACA;;AAEE;EACE;;AAIF;EACE;EACA;;;ACKR;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGJ;EACE;;;AAEF;EACE;EACA;EACA;;;AChNF;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAVF;IAWI;;;AAGF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;;AAGI;EACI;;AAIR;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aD5GR;EC6GQ;;AAGF;EACE;EACA,aDnHN;ECoHM;EACA;EACA;EACA;EACA;;AACA;EARF;IASI;;;AAON;EACE;;AACA;EACE;EACA;;AAIA;EACE;;AASd;EACE;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA,aDxLF;ECyLE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aD9MJ;EC+MI;;AAUE;EACE;EACA;;AASZ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA,aD9QF;EC+QE;EACA;;AAGF;EACE,aDrRA;ECsRA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,aDxSF;ECySE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA,aDpTJ;ECqTI;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA,aD5VJ;EC6VI;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA,aDlXA;ECmXA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aDnZA;ECoZA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA,aDpaF;ECqaE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGE;EACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,aDtfJ;ECufI;EACA;EACA;;AAGF;EACE;EACA;EACA,aDhgBF;ECigBE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAUV;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACzlBJ;AA0iBE;;AAviBE;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aFlCN;EEmCM;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA,aF7DJ;EE8DI;EACA;;AACA;EACE;;AAGF;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,aF7HF;EE8HE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGE;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAOV;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aFxOJ;EEyOI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA,aFxPJ;EEyPI;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AASV;EACE;;AAEA;EACE;EACA;EACA;EACA,aF9UA;EE+UA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,aF1VE;EE2VF;;AAKE;EACE;EACA;EACA;EACA;EACA,aFpWJ;EEqWI;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA,aF/WJ;EEgXI;EACA;EACA;EACA;;AFjXR;EEmXU;;AFhXV;EEgXU;;AF7WV;EE6WU;;AF1WV;EE0WU;;AAGF;EACE;;AAKN;EACE;EACA,aFjYA;EEkYA;EACA;EACA;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA,aF7ZA;EE8ZA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aFzaE;EE0aF;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAMR;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aF3cA;EE4cA;;AAGF;EACE;EACA;EACA;EACA,aFpdE;EEqdF;;AAGF;EACE;EACA;EACA;EACA,aF5dE;EE6dF;;AAEA;EACE;EACA;;AAIA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAQR;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA,aFxjBA;EEyjBA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;AAAA;AAAA;EAIE;EACA;;;AAKJ;EACE;;;AAGF;AACA;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AC5mBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE","file":"admin.css"}
     1{"version":3,"sourceRoot":"","sources":["../scss/admin.scss","../scss/admin/_notice.scss","../scss/admin/_framework.scss","../scss/admin/_welcome.scss","../scss/admin/_elements.scss","../scss/admin/_theme_builder.scss","../scss/admin/_dashboard-enhanced.scss"],"names":[],"mappings":"AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;ACAA;EACE;;AACA;EACE;EACA;EACA;;AAEE;EACE;;AAIF;EACE;EACA;;;ACKR;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGJ;EACE;;;AAEF;EACE;EACA;EACA;;;ACjNF;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAVF;IAWI;;;AAGF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;;AAGI;EACI;;AAIR;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aD5GR;EC6GQ;;AAGF;EACE;EACA,aDnHN;ECoHM;EACA;EACA;EACA;EACA;;AACA;EARF;IASI;;;AAON;EACE;;AACA;EACE;EACA;;AAIA;EACE;;AASd;EACE;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA,aDpLF;ECqLE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aD1MJ;EC2MI;;AAUE;EACE;EACA;;AASZ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA,aD1QF;EC2QE;EACA;;AAGF;EACE,aDjRA;ECkRA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,aDpSF;ECqSE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA,aDhTJ;ECiTI;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA,aDxVJ;ECyVI;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA,aD9WA;EC+WA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aD/YA;ECgZA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA,aDhaF;ECiaE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGE;EACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,aDlfJ;ECmfI;EACA;EACA;;AAGF;EACE;EACA;EACA,aD5fF;EC6fE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAUV;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACllBA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aFlCN;EEmCM;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA,aF7DJ;EE8DI;EACA;;AACA;EACE;;AAGF;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,aF7HF;EE8HE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGE;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAOV;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aF7OJ;EE8OI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA,aF7PJ;EE8PI;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AASV;EACE;;AAEA;EACE;EACA;EACA;EACA,aFnVA;EEoVA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,aF/VE;EEgWF;;AAKE;EACE;EACA;EACA;EACA;EACA,aFzWJ;EE0WI;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA,aFpXJ;EEqXI;EACA;EACA;EACA;;AFtXR;EEwXU;;AFrXV;EEqXU;;AFlXV;EEkXU;;AF/WV;EE+WU;;AAGF;EACE;;AAKN;EACE;EACA,aFtYA;EEuYA;EACA;EACA;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA,aFlaA;EEmaA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aF9aE;EE+aF;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAMR;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aFhdA;EEidA;;AAGF;EACE;EACA;EACA;EACA,aFzdE;EE0dF;;AAGF;EACE;EACA;EACA;EACA,aFjeE;EEkeF;;AAEA;EACE;EACA;;AAIA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAxiBV;AA+iBE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA,aF7jBA;EE8jBA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;AAAA;AAAA;EAIE;EACA;;;AAKJ;EACE;;;AAGF;AACA;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACjnBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;;;ACrLhB;AAAA;AAAA;AAAA;AAMA;EAEE;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;AAAA;EAIA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAMA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;;AAIA;EACE;;AAOF;EACE;;AAEA;EACE;;AAKN;EACE;EACA;EACA;;AAGE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKN;EACE;;AAMA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EAKA;;AACA;EACE;;AAIJ;EACG;;AAEH;EACE;;;AASZ;EACE;;AAGA;EACE;;AAGF;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EAMA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;;AAGF;EACE;IAEE;;EAEF;IACE;;;AAKJ;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;EAPF;IAQI;;;AAGF;EAXF;IAYI;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;;AAMF;EACE;;AAEF;EACE;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EAKA;;AAEF;EACE;EAKA;;AAEF;EACE;EAKA;;AAEF;EACE;EAKA;;AAGF;EACE;EACA;EACA;EACA,aJ9dA;EI+dA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;;AAOA;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACI;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAIN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACG;;AAGH;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EAKA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;IAEE;;EAEF;IACE;;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAMA;EACE;;AAQV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EAKA;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAKN;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAMA;EACE;;AAIJ;EACE;EACA;;AAOR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EAMA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAQV;EACE;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EAKA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAQV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAMN;EAGM;IACE;;EAEA;IACE;;EAIJ;IACE;;EAEA;IACE;;;AAOV;EAGM;IACE;;;AAMR;EAGM;IACE;;EAGF;IACE;IACA;;EAEA;IACE;IACA;;EAIJ;IACE","file":"admin.css"}
  • spider-elements/trunk/assets/css/main.css

    r3416399 r3464401  
    82568256  margin-bottom: 30px;
    82578257  background: transparent;
    8258   color: rgb(29, 39, 70);
     8258  color: var(--black_900);
    82598259  text-decoration: none;
    82608260  margin-left: 8px;
     
    82828282  margin-bottom: 0;
    82838283  transition: all 0.3s linear;
    8284   background: #ffffff;
     8284  background: var(--bs-white);
    82858285  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
    82868286}
  • spider-elements/trunk/assets/js/admin.js

    r3416399 r3464401  
    22
    33    "use strict";
     4
     5    // ===== Toast Notification System =====
     6    window.SpelToast = {
     7        show: function (title, message, type = 'success') {
     8            // Remove existing toasts
     9            $('.spel_toast').remove();
     10
     11            const iconClass = type === 'success' ? 'icon-check' : 'icon-close';
     12            const toast = $(`
     13                <div class="spel_toast ${type === 'error' ? 'toast_error' : ''}">
     14                    <span class="toast_icon"><i class="${iconClass}"></i></span>
     15                    <div class="toast_content">
     16                        <h4>${title}</h4>
     17                        <p>${message}</p>
     18                    </div>
     19                    <span class="toast_close"><i class="icon-close"></i></span>
     20                </div>
     21            `);
     22
     23            $('body').append(toast);
     24
     25            // Show toast
     26            setTimeout(() => toast.addClass('show'), 100);
     27
     28            // Auto-hide after 4 seconds
     29            setTimeout(() => {
     30                toast.removeClass('show');
     31                setTimeout(() => toast.remove(), 300);
     32            }, 4000);
     33
     34            // Close button
     35            toast.find('.toast_close').on('click', function () {
     36                toast.removeClass('show');
     37                setTimeout(() => toast.remove(), 300);
     38            });
     39        }
     40    };
     41
     42    // ===== Search Functionality =====
     43    function initSearchFunctionality() {
     44        // Widget Search
     45        $('#spel_widget_search').on('input', function () {
     46            const searchTerm = $(this).val().toLowerCase().trim();
     47            const $items = $('#elements_list .ezd-colum-space-4');
     48            let visibleCount = 0;
     49
     50            $items.each(function () {
     51                const widgetName = $(this).data('widget-name') || '';
     52                const isMatch = widgetName.includes(searchTerm);
     53
     54                if (isMatch || searchTerm === '') {
     55                    $(this).show().css('opacity', '1');
     56                    visibleCount++;
     57                } else {
     58                    $(this).hide().css('opacity', '0');
     59                }
     60            });
     61
     62            // Update count
     63            const totalWidgets = $items.length;
     64            const countText = searchTerm
     65                ? `${visibleCount} of ${totalWidgets} widgets`
     66                : `${totalWidgets} widgets`;
     67            $('#spel_search_count').text(countText);
     68
     69            // Re-apply isotope layout
     70            $('#elements_list').isotope('layout');
     71        });
     72
     73        // Feature Search
     74        $('#spel_feature_search').on('input', function () {
     75            const searchTerm = $(this).val().toLowerCase().trim();
     76            const $items = $('#features_gallery .ezd-colum-space-4');
     77            let visibleCount = 0;
     78
     79            $items.each(function () {
     80                const featureName = $(this).data('feature-name') || '';
     81                const isMatch = featureName.includes(searchTerm);
     82
     83                if (isMatch || searchTerm === '') {
     84                    $(this).show().css('opacity', '1');
     85                    visibleCount++;
     86                } else {
     87                    $(this).hide().css('opacity', '0');
     88                }
     89            });
     90
     91            // Update count
     92            const totalFeatures = $items.length;
     93            const countText = searchTerm
     94                ? `${visibleCount} of ${totalFeatures} features`
     95                : `${totalFeatures} features`;
     96            $('#spel_feature_search_count').text(countText);
     97
     98            // Re-apply isotope layout
     99            $('#features_gallery').isotope('layout');
     100        });
     101    }
    4102
    5103    // Remove svg.radial-progress .complete inline styling
     
    70168
    71169        if (featureDisable && featureEnable && featureSwitcher) {
    72             console.log('Feature switcher found.');
    73170            featureDisable.addEventListener("click", function () {
    74171                featureSwitcher.checked = false;
     
    87184                featureDisable.classList.toggle("toggler--is-active");
    88185            });
    89         } else {
    90             console.log('Feature switcher not found.');
    91186        }
    92187
     
    96191
    97192    $(document).ready(function () {
     193
     194        // Initialize search functionality
     195        initSearchFunctionality();
    98196
    99197        // Map of tab content names to WordPress admin submenu page slugs
     
    105203        };
    106204
     205        // LocalStorage key for tab persistence
     206        const STORAGE_KEY = 'spel_active_tab';
     207
    107208        // Function to update WordPress admin menu active state
    108209        function updateAdminMenuActiveState(tabName) {
     
    117218        }
    118219
     220        // Function to save active tab to localStorage
     221        function saveActiveTab(tabName) {
     222            try {
     223                localStorage.setItem(STORAGE_KEY, tabName);
     224            } catch (e) {
     225                console.warn('Spider Elements: Could not save tab state to localStorage', e);
     226            }
     227        }
     228
     229        // Function to get active tab from localStorage
     230        function getActiveTab() {
     231            try {
     232                return localStorage.getItem(STORAGE_KEY);
     233            } catch (e) {
     234                console.warn('Spider Elements: Could not read tab state from localStorage', e);
     235                return null;
     236            }
     237        }
     238
    119239        // Set up event listener for tab click
    120240        $(".tab-menu li a").on("click", function () {
     
    138258            filterMasonryThree();
    139259
    140             // Set a cookie to remember the active button
    141             setCookie('spe_settings_current_tab', tabName, 1);
     260            // Save active tab to localStorage for persistence after page refresh
     261            saveActiveTab(tabName);
    142262
    143263            // Update WordPress admin menu active state
     
    157277        });
    158278
    159         // Function to set a cookie
    160         function setCookie(name, value, days) {
    161             let expires = "";
    162             if (days) {
    163                 let date = new Date();
    164                 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    165                 expires = "; expires=" + date.toUTCString();
    166             }
    167             document.cookie = name + "=" + value + expires + "; path=/";
    168         }
    169 
    170         // Function to get a cookie
    171         function getCookie(name) {
    172             let nameEQ = name + "=";
    173             let ca = document.cookie.split(';');
    174             for (let i = 0; i < ca.length; i++) {
    175                 let c = ca[i];
    176                 while (c.charAt(0) === ' ') c = c.substring(1, c.length);
    177                 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
    178             }
    179             return null;
    180         }
    181 
    182         // Remain the last active settings tab
     279        // Remain the last active settings tab after page refresh
    183280        function spel_keep_settings_current_tab() {
    184             // First priority: Check for active tab from URL (via data attribute set by server)
     281            // Check if we're on the Spider Elements dashboard page
    185282            let spelDashboard = $('#spel_settings');
    186             let activeButton = spelDashboard.data('active-tab');
    187 
    188             // Fallback to cookie if no data attribute (for in-page sidebar tab clicks)
    189             if (!activeButton) {
    190                 activeButton = getCookie('spe_settings_current_tab');
    191             }
    192 
    193             if (activeButton) {
    194                 // Update sidebar tab-menu active state
    195                 $('.tab-menu .tab-menu-link[data-content="' + activeButton + '"]').addClass('active');
    196                 $('.tab-menu .tab-menu-link:not([data-content="' + activeButton + '"])').removeClass('active');
    197 
    198                 // Update tab content active state
    199                 $('.tab_contents .tab-box').removeClass('active');
    200                 $('.tab_contents .tab-box#' + activeButton).addClass('active');
    201 
    202                 // Also sync WordPress admin menu active state
    203                 updateAdminMenuActiveState(activeButton);
    204             }
     283            if (!spelDashboard.length) {
     284                return;
     285            }
     286
     287            // Priority 1: Server-side data-active-tab (URL-based, from WordPress submenu navigation)
     288            // This MUST take priority so that clicking a WordPress submenu always
     289            // navigates to the correct tab, regardless of what localStorage says.
     290            let serverTab = spelDashboard.data('active-tab');
     291            let activeTab = serverTab || 'welcome';
     292
     293            // Clear localStorage to keep it in sync with the current submenu page.
     294            // This prevents stale localStorage values from overriding the URL on
     295            // subsequent page loads.
     296            saveActiveTab(activeTab);
     297
     298            // Update sidebar tab-menu active state
     299            $('.tab-menu .tab-menu-link').removeClass('active');
     300            $('.tab-menu .tab-menu-link[data-content="' + activeTab + '"]').addClass('active');
     301
     302            // Update tab content active state
     303            $('.tab_contents .tab-box').removeClass('active');
     304            $('.tab_contents .tab-box#' + activeTab).addClass('active');
     305
     306            // Sync WordPress admin menu active state
     307            updateAdminMenuActiveState(activeTab);
     308
     309            // Update hidden input field
     310            $('#spel_active_tab').val(activeTab);
    205311        }
    206312
     
    220326                    itemSelector: ".ezd-colum-space-4",
    221327                    filter: "*",
     328                    animationOptions: {
     329                        duration: 750,
     330                        easing: 'linear',
     331                        queue: false
     332                    }
    222333                });
    223334            });
     
    235346            $(this).addClass("active");
    236347
     348            // Clear search when filter is clicked
     349            $('#spel_widget_search').val('');
     350            $('#elements_list .ezd-colum-space-4').show().css('opacity', '1');
     351
    237352            let selector = $(this).attr("data-filter");
    238353            filter.isotope({
    239354                filter: selector,
    240355            });
     356
     357            // Update count
     358            const visibleItems = selector === '*'
     359                ? $('#elements_list .ezd-colum-space-4').length
     360                : $('#elements_list .ezd-colum-space-4' + selector).length;
     361            const totalItems = $('#elements_list .ezd-colum-space-4').length;
     362            $('#spel_search_count').text(visibleItems + ' widgets');
     363
    241364            return false;
    242365        });
     
    289412                    itemSelector: ".ezd-colum-space-4",
    290413                    filter: "*",
     414                    animationOptions: {
     415                        duration: 750,
     416                        easing: 'linear',
     417                        queue: false
     418                    }
    291419                });
    292420            });
     
    298426        filterMasonryThree();
    299427        var filter = $("#features_gallery");
    300         // Add isotope click function
     428
     429        // Add isotope click function for features
    301430        $("#features_filter div").on("click", function () {
    302431            $("#features_filter div").removeClass("active");
    303432            $(this).addClass("active");
    304433
     434            // Clear search when filter is clicked
     435            $('#spel_feature_search').val('');
     436            $('#features_gallery .ezd-colum-space-4').show().css('opacity', '1');
     437
    305438            var selector = $(this).attr("data-filter");
    306439            filter.isotope({
    307440                filter: selector,
    308441            });
     442
     443            // Update count
     444            const visibleItems = selector === '*'
     445                ? $('#features_gallery .ezd-colum-space-4').length
     446                : $('#features_gallery .ezd-colum-space-4' + selector).length;
     447            $('#spel_feature_search_count').text(visibleItems + ' features');
     448
    309449            return false;
    310450        });
     
    316456    $(".pro-close").on("click", function (e) {
    317457        $("#elements_popup1").removeClass("popup-visible");
     458    });
     459
     460    // Close popup on background click
     461    $(".elements_pro_popup").on("click", function (e) {
     462        if ($(e.target).hasClass('elements_pro_popup')) {
     463            $(this).removeClass("popup-visible");
     464        }
     465    });
     466
     467    // Close popup on Escape key
     468    $(document).on("keyup", function (e) {
     469        if (e.key === "Escape") {
     470            $(".elements_pro_popup").removeClass("popup-visible");
     471        }
    318472    });
    319473
     
    339493            // Check if the checkbox is checked
    340494            if ($(this).is(":checked")) {
    341                 $(".dashboard_btn").addClass("save-now");
     495                $(".dashboard_btn.save_btn").addClass("save-now");
    342496            } else {
    343                 $(".dashboard_btn")
     497                $(".dashboard_btn.save_btn")
    344498                    .removeClass("save-now")
    345499                    .removeAttr("disabled")
     
    360514            });
    361515
    362             $(".dashboard_btn")
     516            $(".dashboard_btn.save_btn")
    363517                .addClass("save-now")
    364518                .removeAttr("disabled")
     
    369523        let widgetSwitcher = $(".element_right .widget-list:checked");
    370524        widgetSwitcher.on("click", function () {
    371             $(".dashboard_btn")
     525            $(".dashboard_btn.save_btn")
    372526                .addClass("save-now")
    373527                .removeAttr("disabled")
     
    378532        let elementsSettingBtn = $(".elements_tab_menu .menu_right_content .save_btn");
    379533        elementsSettingBtn.on("click", function (event) {
    380             //event.preventDefault();
    381             //alert('Saved Successfully');
     534            // Show toast on save (optional - form will submit normally)
     535            // SpelToast.show('Settings Saved', 'Your settings have been saved successfully.');
    382536        });
    383537    }
     
    385539    elementsSaveNowButton();
    386540
     541    // ===== Keyboard Shortcuts =====
     542    $(document).on('keydown', function (e) {
     543        // Only work on Spider Elements dashboard
     544        if (!$('.spel_dashboard').length) return;
     545
     546        // Ctrl/Cmd + S to save
     547        if ((e.ctrlKey || e.metaKey) && e.key === 's') {
     548            e.preventDefault();
     549            $('.save_btn:visible').first().trigger('click');
     550        }
     551
     552        // Ctrl/Cmd + F to focus search
     553        if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
     554            const $activeTab = $('.tab-box.active');
     555            const $searchInput = $activeTab.find('input[type="text"]').first();
     556            if ($searchInput.length) {
     557                e.preventDefault();
     558                $searchInput.focus().select();
     559            }
     560        }
     561    });
     562
    387563})(jQuery);
  • spider-elements/trunk/assets/scss/admin.scss

    r3316325 r3464401  
    1212@import "admin/elements";
    1313@import "admin/theme_builder";
     14@import "admin/dashboard-enhanced";
  • spider-elements/trunk/assets/scss/admin/_elements.scss

    r3316325 r3464401  
    173173          display: inline-block;
    174174          line-height: 1;
     175          position: relative; // Add for tooltip positioning
    175176        }
    176177
     
    181182          transition: all 0.3s linear;
    182183
    183           .tooltip-top {
    184             position: relative;
     184          a.tooltip-top {
    185185            display: inline-block;
    186186            text-decoration: none;
     
    188188            &::before {
    189189              content: attr(data-tooltip);
    190               top: -40px;
    191               left: -20px;
     190              position: absolute;
     191              bottom: 100%;
     192              left: 50%;
    192193              transform: translateX(-50%);
    193194              background-color: #333;
     
    195196              text-align: center;
    196197              border-radius: 6px;
    197               padding: 8px 8px;
     198              padding: 6px 10px;
    198199              opacity: 0;
    199200              visibility: hidden;
    200201              transition: opacity 0.2s;
    201               position: absolute;
    202               width: 190px;
     202              width: max-content;
     203              max-width: 200px;
     204              font-size: 11px;
     205              line-height: 1.4;
     206              z-index: 100;
     207              white-space: nowrap;
     208              margin-bottom: 2px;
    203209            }
    204210
     
    221227        align-items: center;
    222228        position: relative;
    223         overflow: hidden;
    224229
    225230        .badge {
  • spider-elements/trunk/assets/scss/admin/_framework.scss

    r3316325 r3464401  
    2525.ezd-grid-cols-12 {
    2626  grid-template-columns: repeat(12, minmax(0, 1fr));
     27  width: 100%;
    2728}
    2829
  • spider-elements/trunk/assets/scss/admin/_welcome.scss

    r3316325 r3464401  
    178178        }
    179179
    180         .dashboard_title {
    181           margin-bottom: 15px;
    182         }
    183 
    184180        p {
    185181          font-size: 16px;
     
    243239      &.save_btn {
    244240        color: #fff;
    245         background: #6d27e5;
     241        background: #6d27e5 !important;
    246242        padding: 12px 24px;
    247243        &:hover {
  • spider-elements/trunk/assets/scss/frontend/_Cheat_sheet.scss

    r3316325 r3464401  
    2525        margin-bottom: 30px;
    2626        background: transparent;
    27         color: rgb(29 39 70);
     27        color: var(--black_900);
    2828        text-decoration: none;
    2929        margin-left: 8px;
     
    6060  margin-bottom: 0;
    6161  transition: all 0.3s linear;
    62   background: #ffffff;
     62  background: var(--bs-white);
    6363  box-shadow: 0 .125rem .25rem rgba(0,0,0,.075);
    6464
  • spider-elements/trunk/includes/Admin/Assets.php

    r3416399 r3464401  
    4646            // Register Admin Panel Style's
    4747            wp_enqueue_style( 'spel-icomoon', SPEL_VEND . '/icomoon/style.css', [], SPEL_VERSION );
     48            wp_enqueue_style( 'spel-font-awesome', SPEL_VEND . '/font-awesome/css/all.css', [], SPEL_VERSION );
    4849            wp_enqueue_style( 'spel-fancybox', SPEL_VEND . '/fancybox/fancybox.min.css', [], SPEL_VERSION );
    4950           
  • spider-elements/trunk/includes/Admin/Dashboard.php

    r3416399 r3464401  
    3333
    3434    /**
     35     * Hide all admin notices on Spider Elements pages.
     36     *
    3537     * @return void
    36      * Hide all admin notices on Spider Elements pages.
    3738     */
    3839    public function hide_admin_notices(): void {
     
    4950
    5051    /**
     52     * Add menu page to the WordPress admin dashboard.
     53     *
    5154     * @return void
    52      * Add menu page to the WordPress admin dashboard.
    5355     */
    5456    public function add_menu_page(): void {
     
    104106
    105107    /**
     108     * Get the active tab based on the current page URL.
     109     *
    106110     * @return string
    107      * Get the active tab based on the current page URL.
    108111     */
    109112    public function get_active_tab(): string {
    110113        $page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : 'spider_elements_settings';
    111        
     114
    112115        $tab_map = [
    113116            'spider_elements_settings'    => 'welcome',
     
    122125
    123126    /**
    124      * @return void
    125127     * Render the content of the menu page.
    126128     * This is where you would add your custom HTML
     129     *
     130     * @return void
    127131     */
    128132    public function render_plugin_page(): void {
    129133        // Get the active tab based on which submenu was clicked
    130134        $active_tab = $this->get_active_tab();
    131        
     135
    132136        // Map tab names to submenu page slugs
    133137        $tab_to_page = [
     
    137141            'integration' => 'spider_elements_integration',
    138142        ];
    139        
     143
    140144        // Get the page slug for the active tab
    141145        $current_page = $tab_to_page[ $active_tab ] ?? 'spider_elements_settings';
    142         $form_action = admin_url( 'admin.php?page=' . $current_page );
     146        $form_action  = admin_url( 'admin.php?page=' . $current_page );
    143147
    144148        echo '<form action="' . esc_url( $form_action ) . '" method="post" id="spel_settings" name="spel_settings" class="wrapper spel_dashboard" data-active-tab="' . esc_attr( $active_tab ) . '">';
    145        
     149
    146150        // Hidden field to track current active tab (updated by JavaScript)
    147151        echo '<input type="hidden" name="spel_active_tab" id="spel_active_tab" value="' . esc_attr( $active_tab ) . '">';
     
    150154        echo '<div class="sidebar_navigation">';
    151155
    152         if ( file_exists( require_once __DIR__ . '/dashboard/sidebar.php' ) ) {
     156        if ( file_exists( __DIR__ . '/dashboard/sidebar.php' ) ) {
    153157            require_once __DIR__ . '/dashboard/sidebar.php';
    154158        }
     
    160164        echo '<div class="tab_contents">';
    161165
    162         if ( file_exists( require_once __DIR__ . '/dashboard/welcome.php' ) ) {
     166        if ( file_exists( __DIR__ . '/dashboard/welcome.php' ) ) {
    163167            require_once __DIR__ . '/dashboard/welcome.php';
    164168        }
    165169
    166         if ( file_exists( require_once __DIR__ . '/dashboard/elements.php' ) ) {
     170        if ( file_exists( __DIR__ . '/dashboard/elements.php' ) ) {
    167171            require_once __DIR__ . '/dashboard/elements.php';
    168172        }
    169173
    170         if ( file_exists( require_once __DIR__ . '/dashboard/features.php' ) ) {
     174        if ( file_exists( __DIR__ . '/dashboard/features.php' ) ) {
    171175            require_once __DIR__ . '/dashboard/features.php';
    172176        }
    173177
    174         if ( file_exists( require_once __DIR__ . '/dashboard/integration.php' ) ) {
     178        if ( file_exists( __DIR__ . '/dashboard/integration.php' ) ) {
    175179            require_once __DIR__ . '/dashboard/integration.php';
    176180        }
    177181
    178         if ( file_exists( require_once __DIR__ . '/dashboard/popup-pro.php' ) ) {
     182        if ( file_exists( __DIR__ . '/dashboard/popup-pro.php' ) ) {
    179183            require_once __DIR__ . '/dashboard/popup-pro.php';
    180184        }
     
    188192
    189193    /**
     194     * Return the base64 encoded SVG icon.
     195     *
    190196     * @return string
    191      * Return the base64 encoded SVG icon.
    192197     */
    193198    public function icon(): string {
  • spider-elements/trunk/includes/Admin/Plugin_Installer.php

    r3316325 r3464401  
    1313{
    1414    private static $instance;
    15     private $installed_plugins = [];
    1615    private $activated_plugins = [];
     16    private $initialized = false;
    1717
    1818    /**
     
    3636    public function __construct()
    3737    {
    38         add_action('plugins_loaded', [$this, 'init']);
     38        // If this class is instantiated after `plugins_loaded` has already fired,
     39        // the hook would never run and status checks would always report
     40        // "not_installed". So we initialize immediately when possible.
     41        if ( \did_action( 'plugins_loaded' ) ) {
     42            $this->init();
     43        } else {
     44            \add_action( 'plugins_loaded', [ $this, 'init' ] );
     45        }
    3946    }
    4047
     
    4451    public function init(): void
    4552    {
    46         $this->collect_installed_plugins();
    4753        $this->collect_activated_plugins();
    4854
    49         // Debugging statements
    50         error_log('Installed Plugins: ' . print_r($this->installed_plugins, true));
    51         error_log('Activated Plugins: ' . print_r($this->activated_plugins, true));
    52     }
    53 
    54     /**
    55      * Collects the list of installed plugins
    56      */
    57     private function collect_installed_plugins(): void
    58     {
    59         if (!function_exists('get_plugins')) {
    60             require_once ABSPATH . 'wp-admin/includes/plugin.php';
    61         }
    62 
    63         $this->installed_plugins = array_keys(get_plugins());
    64 
    65         // Debugging statement
    66         error_log('Collecting Installed Plugins: ' . print_r($this->installed_plugins, true));
     55        $this->initialized = true;
    6756    }
    6857
     
    7261    private function collect_activated_plugins(): void
    7362    {
    74         $this->activated_plugins = get_option('active_plugins', []);
    75 
    76         // Debugging statement
    77         error_log('Collecting Activated Plugins: ' . print_r($this->activated_plugins, true));
     63        $this->activated_plugins = \get_option( 'active_plugins', [] );
    7864    }
    7965
     
    8773    public function check_installed_plugin(string $name): bool
    8874    {
    89         return in_array($name, $this->installed_plugins);
     75        if ( $this->check_activated_plugin( $name ) ) {
     76            return true;
     77        }
     78
     79        // Security: Prevent path traversal
     80        if ( 0 !== validate_file( $name ) ) {
     81            return false;
     82        }
     83
     84        // Sentinel Fix: Use file check instead of heavy get_plugins() scan
     85        return file_exists( WP_PLUGIN_DIR . '/' . $name );
    9086    }
    9187
     
    9995    public function check_activated_plugin(string $name): bool
    10096    {
    101         return in_array($name, $this->activated_plugins);
     97        return in_array( $name, $this->activated_plugins, true );
    10298    }
    10399
     
    111107    public function get_status(string $name): array
    112108    {
     109        if ( ! $this->initialized ) {
     110            $this->init();
     111        }
     112
    113113        $data = array(
    114114            'url' => '',
     
    121121        if ($this->check_installed_plugin($name)) {
    122122            if ($this->check_activated_plugin($name)) {
    123                 $data['title'] = esc_html__('Activated', 'spider-elements');
     123                $data['title'] = \esc_html__( 'Activated', 'spider-elements' );
    124124                $data['status'] = 'activated';
    125125            } else {
    126                 $data['title'] = esc_html__('Activate Now', 'spider-elements');
    127                 $data['status'] = 'installed';
     126                $data['title'] = \esc_html__( 'Activate', 'spider-elements' );
     127                $data['status'] = 'inactive';
    128128                $data['activation_url'] = $this->activation_url($name);
    129129            }
    130130        } else {
    131             $data['title'] = esc_html__('Install Now', 'spider-elements');
     131            $data['title'] = \esc_html__( 'Install Now', 'spider-elements' );
    132132            $data['status'] = 'not_installed';
    133133            $data['installation_url'] = $this->installation_url($name);
     
    135135        }
    136136
    137         // Debug output
    138         error_log("Plugin: $name");
    139         error_log(print_r($data, true));
    140 
    141137        return $data;
    142138    }
     
    151147    public function activation_url(string $pluginName): string
    152148    {
    153         return wp_nonce_url(
    154             add_query_arg(
     149        return \wp_nonce_url(
     150            \add_query_arg(
    155151                array(
    156152                    'action' => 'activate',
     
    159155                    'paged' => '1&s',
    160156                ),
    161                 admin_url('plugins.php')
     157                \admin_url( 'plugins.php' )
    162158            ),
    163159            'activate-plugin_' . $pluginName
     
    177173        $pluginSlug = $this->get_plugin_slug($pluginName);
    178174
    179         return wp_nonce_url(
    180             add_query_arg(
     175        return \wp_nonce_url(
     176            \add_query_arg(
    181177                array(
    182178                    'action' => $action,
    183179                    'plugin' => $pluginSlug,
    184180                ),
    185                 admin_url('update.php')
     181                \admin_url( 'update.php' )
    186182            ),
    187183            $action . '_' . $pluginSlug
  • spider-elements/trunk/includes/Admin/dashboard/elements.php

    r3416399 r3464401  
    1111$checked_global   = ( ! isset( $element_opt['element_global_switcher'] ) || $element_opt['element_global_switcher'] === 'on' ) ? ' checked' : '';
    1212$docy_widget_list = [ 'docly_cheatsheet', 'spel_videos_playlist', 'docy_tabs', 'docly_alerts_box' ];
     13
     14// Count widgets for search placeholder
     15$total_widgets = isset( $elements['spider_elements_widgets'] ) ? count( $elements['spider_elements_widgets'] ) : 0;
    1316?>
    1417<div id="elements" class="tab-box">
     
    3033                    <label class="b switch" for="element_switcher"></label>
    3134                </div>
    32                 <label class="toggler" id="element_enabled"><?php esc_html_e( 'Enabled All', 'spider-elements' ); ?></label>
     35                <label class="toggler" id="element_enabled"><?php esc_html_e( 'Enable All', 'spider-elements' ); ?></label>
    3336            </div>
    3437            <button type="submit" name="elements-submit" id="elements-submit" class="dashboard_btn save_btn">
     38                <i class="icon-check"></i>
    3539                <?php esc_html_e( 'Save Changes', 'spider-elements' ); ?>
    3640            </button>
    3741            <?php wp_nonce_field( 'spel_elements_nonce', 'spel_elements_nonce' ); ?>
    3842        </div>
     43    </div>
     44
     45    <!-- Search Box -->
     46    <div class="spel_search_box">
     47        <span class="search_icon"><i class="icon-search"></i></span>
     48        <input type="text" id="spel_widget_search" placeholder="<?php echo esc_attr( sprintf( __( 'Search %d widgets...', 'spider-elements' ), $total_widgets ) ); ?>">
     49        <span class="search_count" id="spel_search_count"><?php echo esc_html( $total_widgets ); ?> <?php esc_html_e( 'widgets', 'spider-elements' ); ?></span>
    3950    </div>
    4051
     
    5869                $widget_type = $item['widget_type'] ?? '';
    5970                $widget_name = $item['name'] ?? '';
     71                $widget_label = $item['label'] ?? '';
    6072                $is_pro      = $widget_type === 'pro';
    6173
     
    7385                }
    7486                ?>
    75                 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['widget_type'] ) ?>">
     87                <div class="ezd-colum-space-4 <?php echo esc_attr( $item['widget_type'] ) ?>" data-widget-name="<?php echo esc_attr( strtolower( $widget_label ) ); ?>">
    7688                    <div class="element_box element_switch badge">
    7789                        <div class="element_content">
  • spider-elements/trunk/includes/Admin/dashboard/features.php

    r3416399 r3464401  
    1010// Global switcher
    1111$opt             = get_option( 'spel_features_settings' );
    12 $global_switcher = $opt['features_global_switcher'] ?? '';
    13 $is_checked      = ! empty ( $global_switcher == 'on' ) ? ' checked' : '';
    14 $checked         = ! isset ( $opt['features_global_switcher'] ) ? ' checked' : $is_checked;
     12$checked_global  = ( ! isset( $opt['features_global_switcher'] ) || $opt['features_global_switcher'] === 'on' ) ? ' checked' : '';
    1513
    1614// Get the current theme
    17 $theme = wp_get_theme();
    18 $theme = in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] );
     15$theme_obj  = wp_get_theme();
     16$theme_name = $theme_obj->get( 'Name' );
     17$is_jobi    = in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true );
     18$is_docy    = spel_unlock_docy_theme();
     19$is_docly   = in_array( $theme_name, [ 'Docly', 'docly', 'Docly Child', 'docly-child' ], true );
     20$is_ama     = in_array( $theme_name, [ 'Ama', 'ama', 'Ama Child', 'ama-child' ], true );
     21
     22// Smooth Animation is unlocked for Docy, Jobi, Docly, or Ama theme users
     23$is_smooth_anim_unlocked = $is_docy || $is_jobi || $is_docly || $is_ama;
     24
     25// Count features for search placeholder
     26$total_features = isset( $features['spider_elements_features'] ) ? count( $features['spider_elements_features'] ) : 0;
    1927?>
    2028<div id="features" class="tab-box">
     
    3442                <label class="toggler" id="features_disabled"><?php esc_html_e( 'Disable All', 'spider-elements' ); ?></label>
    3543                <div class="toggle">
    36                     <input type="checkbox" data-id="widget-list" id="features_switcher" name="features_global_switcher" class="check features_global_switcher">
     44                    <input type="checkbox" data-id="widget-list" id="features_switcher" name="features_global_switcher" class="check features_global_switcher" <?php echo esc_attr( $checked_global ); ?>>
    3745                    <label class="b switch" for="features_switcher"></label>
    3846                </div>
    39                 <label class="toggler" id="features_enabled"><?php esc_html_e( 'Enabled All', 'spider-elements' ); ?></label>
     47                <label class="toggler" id="features_enabled"><?php esc_html_e( 'Enable All', 'spider-elements' ); ?></label>
    4048            </div>
    4149            <button type="submit" name="features-submit" id="features-submit" class="dashboard_btn save_btn">
     50                <i class="icon-check"></i>
    4251                <?php esc_html_e( 'Save Changes', 'spider-elements' ); ?>
    4352            </button>
     
    4756    </div>
    4857
    49     <div class="elements_tab" id="elements_filter">
     58    <!-- Search Box -->
     59    <div class="spel_search_box">
     60        <span class="search_icon"><i class="icon-search"></i></span>
     61        <input type="text" id="spel_feature_search" placeholder="<?php echo esc_attr( sprintf( __( 'Search %d features...', 'spider-elements' ), $total_features ) ); ?>">
     62        <span class="search_count" id="spel_feature_search_count"><?php echo esc_html( $total_features ); ?> <?php esc_html_e( 'features', 'spider-elements' ); ?></span>
     63    </div>
     64
     65    <div class="elements_tab" id="features_filter">
    5066        <div class="filter_data active" data-filter="*">
    5167            <i class="icon-star"></i>
     
    6985                $feature_type = $item['feature_type'] ?? '';
    7086                $feature_name = $item['name'] ?? '';
     87                $feature_label = $item['label'] ?? '';
    7188
    7289                // Default class and attributes for widgets
     
    7592
    7693                // Unlock specific features for Jobi theme users
    77                 if ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ] ) && $theme || spel_is_premium() ) {
     94                if ( ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ], true ) && $is_jobi ) || spel_is_premium() ) {
    7895                    $is_pro_feature         = ''; // Remove pro_popup class
    7996                    $is_pro_feature_enabled = ''; // Enable widget
    8097                }
    8198
    82                 // By default, only free features are checked
    83                 $opt_input = $opt[ $feature_name ] ?? '';
    84                 if ( $feature_type === 'pro' && ! spel_is_premium() && ! ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ] ) && $theme ) ) {
     99                // Unlock Smooth Animation for Docy, Jobi, or Docly theme users
     100                if ( $item['name'] === 'spel_smooth_animation' && $is_smooth_anim_unlocked ) {
     101                    $is_pro_feature         = ''; // Remove pro_popup class
     102                    $is_pro_feature_enabled = ''; // Enable widget
     103                }
     104
     105                // Determine if this feature is unlocked via theme
     106                $is_jobi_unlocked = in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ], true ) && $is_jobi;
     107                $is_smooth_unlocked = $item['name'] === 'spel_smooth_animation' && $is_smooth_anim_unlocked;
     108
     109                if ( $feature_type === 'pro' && ! spel_is_premium() && ! $is_jobi_unlocked && ! $is_smooth_unlocked ) {
    85110                    // Pro feature: unchecked by default
    86                     $checked = ! isset( $opt[ $feature_name ] ) ? '' : ( ! empty( $opt_input == 'on' ) ? ' checked' : '' );
     111                    $checked = ! isset( $opt[ $feature_name ] ) ? '' : ( $opt[ $feature_name ] === 'on' ? ' checked' : '' );
    87112                } else {
    88113                    // Free feature or unlocked pro: checked by default
    89                     $is_checked = ! empty( $opt_input == 'on' ) ? ' checked' : '';
    90                     $checked    = ! isset( $opt[ $feature_name ] ) ? ' checked' : $is_checked;
     114                    $checked = ( ! isset( $opt[ $feature_name ] ) || $opt[ $feature_name ] === 'on' ) ? ' checked' : '';
    91115                }
    92116                ?>
    93                 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['feature_type'] ) ?>">
     117                <div class="ezd-colum-space-4 <?php echo esc_attr( $item['feature_type'] ) ?>" data-feature-name="<?php echo esc_attr( strtolower( $feature_label ) ); ?>">
    94118                    <div class="element_box element_switch badge">
    95119                        <div class="element_content">
     
    100124                            }
    101125                            if ( ! empty( $item['label'] ) ) { ?>
    102                                 <label for="elementor-video"><?php echo esc_html( $item['label'] ) ?></label>
     126                                <label for="<?php echo esc_attr( $item['name'] ) ?>"><?php echo esc_html( $item['label'] ) ?></label>
    103127                                <?php
    104128                            }
     
    119143                                        <?php
    120144                                    }
    121                                     if ( ! empty( $item['demo_url'] ) ) {
     145                                    if ( ! empty( $item['video_url'] ) ) {
    122146                                        ?>
    123147                                        <a href="<?php echo esc_url( $item['video_url'] ) ?>" class="tooltip-top" data-tooltip="<?php echo esc_attr( sprintf( __( 'View %s Video Tutorial', 'spider-elements' ), $item['label'] ) ); ?>"
  • spider-elements/trunk/includes/Admin/dashboard/integration.php

    r3316325 r3464401  
    44}
    55
    6 $integrations = [
    7     [
     6$integrations = array(
     7    array(
    88        'slug'     => 'bbp-core',
    99        'basename' => 'bbp-core/bbp-core.php',
    1010        'logo'     => SPEL_IMG . '/dashboard/bbp-core-logo.svg',
    11         'title'    => esc_html__( 'BBP Core', 'spider-elements' ),
    12         'desc'     => esc_html__( 'Expand bbPress powered forums with useful features like - private reply, solved topics ...', 'spider-elements' ),
    13     ],
    14     [
     11        'title'    => esc_html__( 'Forumax', 'spider-elements' ),
     12        'desc'     => esc_html__( 'A complete, self-contained platform for building support forums, or discussion communities.', 'spider-elements' ),
     13        'category' => 'community',
     14    ),
     15    array(
    1516        'slug'     => 'eazydocs',
    1617        'basename' => 'eazydocs/eazydocs.php',
     
    1819        'title'    => esc_html__( 'EazyDocs', 'spider-elements' ),
    1920        'desc'     => esc_html__( 'A powerful & beautiful documentation, knowledge base builder plugin.', 'spider-elements' ),
    20     ],
    21     [
     21        'category' => 'documentation',
     22    ),
     23    array(
    2224        'slug'     => 'changeloger',
    2325        'basename' => 'changeloger/changeloger.php',
     
    2527        'title'    => esc_html__( 'Changeloger', 'spider-elements' ),
    2628        'desc'     => esc_html__( 'Auto-convert plain text changelogs into engaging visuals for WordPress.', 'spider-elements' ),
    27     ],
    28     [
    29         'slug'     => 'advanced-accordion-block',
    30         'basename' => 'advanced-accordion-block/advanced-accordion-block.php',
    31         'logo'     => SPEL_IMG . '/dashboard/AAGB-logo.svg',
    32         'title'    => esc_html__( 'Advanced Accordion Block', 'spider-elements' ),
    33         'desc'     => esc_html__( 'A custom Gutenberg Block that allows to showcase the content in accordion mode. It also helps to build FAQ sections easily.',
    34             'spider-elements' ),
    35     ],
    36 ];
     29        'category' => 'utility',
     30    ),
     31    array(
     32        'slug'     => 'advanced-accordion-block',
     33        'basename' => 'advanced-accordion-block/advanced-accordion-block.php',
     34        'logo'     => SPEL_IMG . '/dashboard/AAGB-logo.svg',
     35        'title'    => esc_html__( 'Advanced Accordion Block', 'spider-elements' ),
     36        'desc'     => esc_html__( '#1 WordPress plugin for creating professional FAQ sections, expandable content accordions.', 'spider-elements' ),
     37        'category' => 'gutenberg',
     38    ),
     39    array(
     40        'slug'     => 'antimanual',
     41        'basename' => 'antimanual/antimanual.php',
     42        'logo'     => SPEL_IMG . '/dashboard/antimanual-logo.png',
     43        'title'    => esc_html__( 'Antimanual', 'spider-elements' ),
     44        'desc'     => esc_html__( 'The ultimate AI powerhouse for your website. Do automatically with AI instead of manually.', 'spider-elements' ),
     45        'category' => 'ai',
     46    ),
     47    array(
     48        'slug'     => 'jobus',
     49        'basename' => 'jobus/jobus.php',
     50        'logo'     => SPEL_IMG . '/dashboard/jobus-logo.png',
     51        'title'    => esc_html__( 'Jobus', 'spider-elements' ),
     52        'desc'     => esc_html__( 'A modern and powerful plugin designed to transform your website into a fully functional Job portal.', 'spider-elements' ),
     53        'category' => 'community',
     54    ),
     55);
    3756?>
    3857
    3958<div id="integration" class="tab-box">
    4059    <div class="dashboard_banner integration_banner">
    41         <h2><?php esc_html_e( 'Elevate Your WordPress Website to the Next Level!', 'spider-elements' ); ?></h2>
    42         <p><?php esc_html_e( 'Explore our versatile range of plugins tailored to meet every need for WordPress, Gutenberg, Elementor, and WooCommerce. Discover solutions that empower your site with enhanced functionality and seamless performance.', 'spider-elements' ); ?></p>
     60        <div class="banner_content">
     61            <span class="version_badge">
     62                <i class="icon-star"></i>
     63                <?php esc_html_e( 'Recommended Plugins', 'spider-elements' ); ?>
     64            </span>
     65            <h2><?php esc_html_e( 'Elevate Your WordPress Website to the Next Level!', 'spider-elements' ); ?></h2>
     66            <p><?php esc_html_e( 'Explore our versatile range of plugins tailored to meet every need for WordPress, Gutenberg, Elementor, and WooCommerce. Discover solutions that empower your site with enhanced functionality and seamless performance.', 'spider-elements' ); ?></p>
     67        </div>
    4368    </div>
    44     <div class="ezd-grid ezd-grid-cols-12">
     69
     70    <div class="ezd-grid ezd-grid-cols-12" style="margin-top: 24px;">
    4571        <?php
    4672        if ( isset( $integrations ) && is_array( $integrations ) ) {
     
    5480                $plugin_status_label     = isset( $plugin_data['status'] ) ? ( $plugin_data['status'] == 'activated' ? 'activated' : '' ) : '';
    5581                $plugin_status_title     = $plugin_data['title'] ?? esc_html__( 'Activate', 'spider-elements' );
     82
     83                // Determine button icon based on status
     84                $button_icon = 'icon-download';
     85                if ( $plugin_status === 'activated' ) {
     86                    $button_icon = 'icon-check';
     87                } elseif ( $plugin_status === 'inactive' ) {
     88                    $button_icon = 'icon-power';
     89                }
    5690                ?>
    5791                <div class="ezd-lg-col-4">
     
    6195                        <p><?php echo esc_html( $plugin['desc'] ); ?></p>
    6296
    63                         <?php
    64                         echo sprintf(
    65                             '<a data-plugin_status="%1$s" data-activation_url="%2$s" href="%3$s" class="dashboard_btn %4$s">%5$s</a>',
    66                             esc_attr( $plugin_status ),
    67                             esc_url( $plugin_activation_url ),
    68                             esc_url( $plugin_status === 'not_installed' ? $plugin_installation_url : $plugin_activation_url ),
    69                             esc_attr( $plugin_status_label ),
    70                             esc_html( $plugin_status_title )
    71                         );
    72                         ?>
     97                        <?php
     98                        if ( $plugin['slug'] === 'bbp-core' ) {
     99                            $wp_org_link = 'https://wordpress.org/plugins/forumax/';
     100                        } elseif($plugin['slug'] === 'advanced-accordion-block') {
     101                            $wp_org_link = 'https://wordpress.org/plugins/advanced-accordion-block/';
     102                        } else {
     103                            $wp_org_link = 'https://wordpress.org/plugins/' . $plugin['slug'] . '/';
     104                        }
     105
     106                        printf(
     107                            '<div class="action_buttons">
     108                                <a data-plugin_status="%1$s" data-activation_url="%2$s" href="%3$s" class="dashboard_btn %4$s"><i class="%5$s"></i>%6$s</a>
     109                                <a href="%7$s" class="dashboard_btn learn_more_btn" target="_blank"><i class="fab fa-wordpress-simple"></i> %8$s</a>
     110                            </div>',
     111                            esc_attr( $plugin_status ),
     112                            esc_url( $plugin_activation_url ),
     113                            esc_url( $plugin_status === 'not_installed' ? $plugin_installation_url : $plugin_activation_url ),
     114                            esc_attr( $plugin_status_label ),
     115                            esc_attr( $button_icon ),
     116                            esc_html( $plugin_status_title ),
     117                            esc_url( $wp_org_link ),
     118                            esc_html__( 'Learn More', 'spider-elements' )
     119                        );
     120                        ?>
    73121                    </div>
    74122                </div>
  • spider-elements/trunk/includes/Admin/dashboard/popup-pro.php

    r3316325 r3464401  
    11<?php
    2 if (!defined('ABSPATH')) {
    3     exit; // Exit if accessed directly
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
    44}
    55?>
     
    77    <div class="message_content ezd-text-center">
    88        <div class="close-pro">
    9             <img class="pro-close" src="<?php echo esc_url(SPEL_IMG . '/dashboard/modal-close.png') ?>"
    10                  alt="<?php esc_attr_e('Popup Close', 'spider-elements'); ?>">
     9            <img class="pro-close" src="<?php echo esc_url( SPEL_IMG . '/dashboard/modal-close.png' ) ?>"
     10                 alt="<?php esc_attr_e( 'Close Popup', 'spider-elements' ); ?>">
    1111        </div>
    1212        <div class="pro-icon">
    13             <img class="pro-image" src="<?php echo esc_url(SPEL_IMG . '/dashboard/dimond.png') ?>"
    14                  alt="<?php esc_attr_e('Popup Pro Diamond', 'spider-elements'); ?>">
     13            <img class="pro-image" src="<?php echo esc_url( SPEL_IMG . '/dashboard/dimond.png' ) ?>"
     14                 alt="<?php esc_attr_e( 'Pro Feature', 'spider-elements' ); ?>">
    1515        </div>
    1616        <div class="pro-content">
    17             <h3><?php esc_html_e('Go Pro', 'spider-elements'); ?></h3>
    18             <p><?php esc_html_e('Upgrade to Pro Version for Unlock more features!', 'spider-elements'); ?></p>
    19             <a href="admin.php?page=spider_elements_settings-pricing" class="dashboard_btn" target="_blank">
    20                 <?php esc_html_e('Upgrade Now', 'spider-elements'); ?>
     17            <h3><?php esc_html_e( 'Unlock Pro Features', 'spider-elements' ); ?></h3>
     18            <p><?php esc_html_e( 'Upgrade to Spider Elements Pro to unlock all premium widgets and features for building amazing websites!', 'spider-elements' ); ?></p>
     19            <ul class="pro-benefits" style="text-align: left; margin: 20px 0; padding-left: 24px;">
     20                <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);">
     21                    <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i>
     22                    <?php esc_html_e( 'All Premium Widgets', 'spider-elements' ); ?>
     23                </li>
     24                <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);">
     25                    <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i>
     26                    <?php esc_html_e( 'Premium Extensions', 'spider-elements' ); ?>
     27                </li>
     28                <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);">
     29                    <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i>
     30                    <?php esc_html_e( 'Priority Support', 'spider-elements' ); ?>
     31                </li>
     32                <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);">
     33                    <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i>
     34                    <?php esc_html_e( 'Regular Updates', 'spider-elements' ); ?>
     35                </li>
     36            </ul>
     37            <a href="admin.php?page=spider_elements_settings-pricing" class="dashboard_btn">
     38                <i class="icon-premium"></i>
     39                <?php esc_html_e( 'Upgrade to Pro', 'spider-elements' ); ?>
    2140            </a>
    2241        </div>
  • spider-elements/trunk/includes/Admin/dashboard/sidebar.php

    r3316325 r3464401  
    33    exit; // Exit if accessed directly
    44}
     5
     6$current_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : 'spider_elements_settings';
     7$tab_map = array(
     8    'spider_elements_settings'    => 'welcome',
     9    'spider_elements_elements'    => 'elements',
     10    'spider_elements_features'    => 'features',
     11    'spider_elements_integration' => 'integration',
     12);
     13$active_tab = $tab_map[ $current_page ] ?? 'welcome';
    514?>
    615
     
    1019
    1120        <li>
    12             <a href="#welcome" class="tab-menu-link active" data-content="welcome">
     21            <a href="#welcome" class="tab-menu-link <?php echo $active_tab === 'welcome' ? 'active' : ''; ?>" data-content="welcome">
    1322                <div class="tab_menu_contents">
    1423                    <div class="icon">
     
    2433
    2534        <li>
    26             <a href="#elements" class="tab-menu-link" data-content="elements">
     35            <a href="#elements" class="tab-menu-link <?php echo $active_tab === 'elements' ? 'active' : ''; ?>" data-content="elements">
    2736                <div class="tab_menu_contents">
    2837                    <div class="icon">
     
    3847
    3948        <li>
    40             <a href="#features" class="tab-menu-link" data-content="features">
     49            <a href="#features" class="tab-menu-link <?php echo $active_tab === 'features' ? 'active' : ''; ?>" data-content="features">
    4150                <div class="tab_menu_contents">
    4251                    <div class="icon">
     
    5261
    5362        <li>
    54             <a href="#integration" class="tab-menu-link" data-content="integration">
     63            <a href="#integration" class="tab-menu-link <?php echo $active_tab === 'integration' ? 'active' : ''; ?>" data-content="integration">
    5564                <div class="tab_menu_contents">
    5665                    <div class="icon">
  • spider-elements/trunk/includes/Admin/dashboard/welcome.php

    r3370551 r3464401  
    33    exit;
    44} // Exit if accessed directly
     5
     6use SPEL\includes\Admin\Module_Settings;
    57
    68$php_version        = phpversion();
     
    1315$close_icon         = '<span class="invalid"><i class="icon-close"></i></span>';
    1416$environment        = spel_get_environment_info();
     17
     18// Get widget and feature stats
     19$widget_settings = Module_Settings::get_widget_settings();
     20$widget_opt      = get_option( 'spe_widget_settings' );
     21$feature_opt     = get_option( 'spel_features_settings' );
     22
     23// Count active widgets and features
     24$total_widgets  = isset( $widget_settings['spider_elements_widgets'] ) ? count( $widget_settings['spider_elements_widgets'] ) : 0;
     25$total_features = isset( $widget_settings['spider_elements_features'] ) ? count( $widget_settings['spider_elements_features'] ) : 0;
     26
     27$active_widgets = 0;
     28if ( isset( $widget_settings['spider_elements_widgets'] ) ) {
     29    foreach ( $widget_settings['spider_elements_widgets'] as $widget ) {
     30        $widget_name = $widget['name'] ?? '';
     31        if ( ! isset( $widget_opt[ $widget_name ] ) || $widget_opt[ $widget_name ] === 'on' ) {
     32            if ( $widget['widget_type'] !== 'pro' || spel_is_premium() ) {
     33                ++$active_widgets;
     34            }
     35        }
     36    }
     37}
     38
     39$active_features = 0;
     40if ( isset( $widget_settings['spider_elements_features'] ) ) {
     41    foreach ( $widget_settings['spider_elements_features'] as $feature ) {
     42        $feature_name = $feature['name'] ?? '';
     43        if ( ! isset( $feature_opt[ $feature_name ] ) || $feature_opt[ $feature_name ] === 'on' ) {
     44            if ( $feature['feature_type'] !== 'pro' || spel_is_premium() ) {
     45                ++$active_features;
     46            }
     47        }
     48    }
     49}
     50
     51// Count pro widgets
     52$pro_widgets = 0;
     53if ( isset( $widget_settings['spider_elements_widgets'] ) ) {
     54    foreach ( $widget_settings['spider_elements_widgets'] as $widget ) {
     55        if ( $widget['widget_type'] === 'pro' ) {
     56            ++$pro_widgets;
     57        }
     58    }
     59}
     60
     61$free_widgets = $total_widgets - $pro_widgets;
    1562?>
    1663<div id="welcome" class="tab-box active">
    1764
    18     <div class="dashboard_banner text-center">
    19         <img src="<?php echo esc_url( SPEL_IMG . '/dashboard/logo.png' ) ?>" alt="<?php esc_attr_e( 'Dashboard Banner', 'spider-elements' ); ?>">
    20     </div>
    21 
    22     <div class="ezd-grid ezd-grid-cols-12">
    23         <div class="ezd-lg-col-12">
    24             <div class="support_item">
    25                 <h2 class="dashboard_title"><?php esc_html_e( 'System Requirement', 'spider-elements' ); ?></h2>
    26                 <div class="ezd-grid ezd-grid-cols-12">
    27 
    28                     <ul class="list-unstyled requirement_list ezd-lg-col-6">
    29                         <li>
    30                             <strong><?php esc_html_e( 'PHP Version:', 'spider-elements' ); ?></strong>
    31                             <?php
    32                             if ( version_compare( $php_version, '7.4', '<' ) ) {
    33                                 echo '<span title="' . esc_attr__( 'Minimum: 7.4 Recommended', 'spider-elements' ) . '">'
    34                                     . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>';
    35                             } else {
    36                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>';
    37                             }
    38                             ?>
    39                         </li>
    40                         <li>
    41                             <strong><?php esc_html_e( 'Memory Limit:', 'spider-elements' ); ?></strong>
    42                             <?php
    43                             if ( intval( $memory_limit ) < 512 ) {
    44                                 echo '<span title="' . esc_attr__( 'Minimum 512M Recommended', 'spider-elements' ) . '">'
    45                                     . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>';
    46                             } else {
    47                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>';
    48                             }
    49                             ?>
    50                         </li>
    51                         <li>
    52                             <strong><?php esc_html_e( 'Uploads Folder Writable:', 'spider-elements' ); ?></strong>
    53                             <?php
    54                             if ( ! is_writable( $upload_path ) ) {
    55                                 echo wp_kses_post( $close_icon );
    56                             } else {
    57                                 echo wp_kses_post( $check_icon );
    58                             }
    59                             ?>
    60                         </li>
    61                         <li>
    62                             <strong><?php esc_html_e( 'GZip Enabled:', 'spider-elements' ); ?></strong>
    63                             <?php
    64                             if ( $environment['gzip_enabled'] ) {
    65                                 echo wp_kses_post( $check_icon );
    66                             } else {
    67                                 echo wp_kses_post( $close_icon );
    68                             }
    69                             ?>
    70                         </li>
    71                     </ul>
    72 
    73                     <ul class="list-unstyled requirement_list ezd-lg-col-6">
    74                         <li>
    75                             <strong><?php esc_html_e( 'Max Execution Time:', 'spider-elements' ); ?></strong>
    76                             <?php
    77                             if ( intval( $max_execution_time ) < 90 ) {
    78                                 echo '<span title="' . esc_attr__( 'Minimum 90 Recommended', 'spider-elements' ) . '">'
    79                                     . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>';
    80                             } else {
    81                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>';
    82                             }
    83                             ?>
    84                         </li>
    85                         <li>
    86                             <strong><?php esc_html_e( 'Max Post Limit:', 'spider-elements' ); ?></strong>
    87                             <?php
    88                             if ( intval( $post_limit ) < 32 ) {
    89                                 echo '<span title="' . esc_attr__( 'Minimum 32M Recommended', 'spider-elements' ) . '">'
    90                                     . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>';
    91                             } else {
    92                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>';
    93                             }
    94                             ?>
    95                         </li>
    96                         <li>
    97                             <strong><?php esc_html_e( 'Multisite:', 'spider-elements' ); ?></strong>
    98                             <?php
    99                             if ( $environment['wp_multisite'] ) {
    100                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Multisite', 'spider-elements' ) . '</span>';
    101                             } else {
    102                                 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'No Multisite', 'spider-elements' ) . '</span>';
    103                             }
    104                             ?>
    105                         </li>
    106                         <li>
    107                             <strong><?php esc_html_e( 'Debug Mode:', 'spider-elements' ); ?></strong>
    108                             <?php
    109                             if ( $environment['wp_debug_mode'] ) {
    110                                 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently Turned On', 'spider-elements' ) . '</span>';
    111                             } else {
    112                                 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'Currently Turned Off', 'spider-elements' ) . '</span>';
    113                             }
    114                             ?>
    115                         </li>
    116                     </ul>
    117 
    118 
    119                 </div>
    120 
    121                 <div class="note">
    122                     <p>
     65    <!-- Enhanced Dashboard Banner -->
     66    <div class="dashboard_banner">
     67        <div class="banner_content">
     68            <span class="version_badge">
     69                <i class="icon-star"></i>
     70                <?php echo esc_html( sprintf( __( 'Version %s', 'spider-elements' ), SPEL_VERSION ) ); ?>
     71            </span>
     72            <h2><?php esc_html_e( 'Welcome to Spider Elements', 'spider-elements' ); ?></h2>
     73            <p><?php esc_html_e( 'The ultimate Elementor addon bundle packed with powerful widgets and features to create stunning websites effortlessly.', 'spider-elements' ); ?></p>
     74        </div>
     75        <img src="<?php echo esc_url( SPEL_IMG . '/dashboard/logo.png' ); ?>" alt="<?php esc_attr_e( 'Spider Elements Logo', 'spider-elements' ); ?>">
     76    </div>
     77
     78    <!-- Quick Stats Section -->
     79    <div class="quick_stats">
     80        <div class="stat_card stat_elements">
     81            <div class="stat_header">
     82                <span class="stat_icon">
     83                    <i class="icon-element"></i>
     84                </span>
     85                <span class="stat_trend trend_info">
     86                    <i class="icon-star"></i> <?php esc_html_e( 'Widgets', 'spider-elements' ); ?>
     87                </span>
     88            </div>
     89            <div class="stat_value"><?php echo esc_html( $total_widgets ); ?></div>
     90            <div class="stat_label"><?php esc_html_e( 'Total Widgets Available', 'spider-elements' ); ?></div>
     91        </div>
     92
     93        <div class="stat_card stat_active">
     94            <div class="stat_header">
     95                <span class="stat_icon">
     96                    <i class="icon-check"></i>
     97                </span>
     98                <span class="stat_trend trend_up">
     99                    <i class="icon-star"></i> <?php esc_html_e( 'Active', 'spider-elements' ); ?>
     100                </span>
     101            </div>
     102            <div class="stat_value"><?php echo esc_html( $active_widgets ); ?></div>
     103            <div class="stat_label"><?php esc_html_e( 'Active Widgets', 'spider-elements' ); ?></div>
     104        </div>
     105
     106        <div class="stat_card stat_features">
     107            <div class="stat_header">
     108                <span class="stat_icon">
     109                    <i class="icon-feature_two"></i>
     110                </span>
     111                <span class="stat_trend trend_info">
     112                    <i class="icon-star"></i> <?php esc_html_e( 'Features', 'spider-elements' ); ?>
     113                </span>
     114            </div>
     115            <div class="stat_value"><?php echo esc_html( $total_features ); ?></div>
     116            <div class="stat_label"><?php esc_html_e( 'Total Features', 'spider-elements' ); ?></div>
     117        </div>
     118
     119        <div class="stat_card stat_pro">
     120            <div class="stat_header">
     121                <span class="stat_icon">
     122                    <i class="icon-premium"></i>
     123                </span>
     124                <span class="stat_trend trend_info">
     125                    <i class="icon-diamond"></i> <?php esc_html_e( 'Pro', 'spider-elements' ); ?>
     126                </span>
     127            </div>
     128            <div class="stat_value"><?php echo esc_html( $pro_widgets ); ?></div>
     129            <div class="stat_label"><?php esc_html_e( 'Pro Widgets', 'spider-elements' ); ?></div>
     130        </div>
     131    </div>
     132
     133    <!-- System Requirement Section -->
     134    <div class="ezd-grid ezd-grid-cols-12">
     135        <div class="ezd-lg-col-12">
     136            <div class="support_item">
     137                <div class="section_header has_flex">
     138                    <h2 class="dashboard_title"><?php esc_html_e( 'System Requirements', 'spider-elements' ); ?></h2>
     139                    <span class="requirement_status badge_success">
     140                        <i class="icon-check"></i>
     141                        <?php esc_html_e( 'All Good', 'spider-elements' ); ?>
     142                    </span>
     143                </div>
     144                <div class="ezd-grid ezd-grid-cols-12">
     145
     146                    <ul class="list-unstyled requirement_list ezd-lg-col-6">
     147                        <li>
     148                            <strong><?php esc_html_e( 'PHP Version:', 'spider-elements' ); ?></strong>
     149                            <?php
     150                            if ( version_compare( $php_version, '7.4', '<' ) ) {
     151                                echo '<span title="' . esc_attr__( 'Minimum: 7.4 Recommended', 'spider-elements' ) . '">'
     152                                    . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>';
     153                            } else {
     154                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>';
     155                            }
     156                            ?>
     157                        </li>
     158                        <li>
     159                            <strong><?php esc_html_e( 'Memory Limit:', 'spider-elements' ); ?></strong>
     160                            <?php
     161                            if ( intval( $memory_limit ) < 512 ) {
     162                                echo '<span title="' . esc_attr__( 'Minimum 512M Recommended', 'spider-elements' ) . '">'
     163                                    . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>';
     164                            } else {
     165                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>';
     166                            }
     167                            ?>
     168                        </li>
     169                        <li>
     170                            <strong><?php esc_html_e( 'Uploads Folder Writable:', 'spider-elements' ); ?></strong>
     171                            <?php
     172                            if ( ! is_writable( $upload_path ) ) {
     173                                echo wp_kses_post( $close_icon );
     174                            } else {
     175                                echo wp_kses_post( $check_icon );
     176                            }
     177                            ?>
     178                        </li>
     179                        <li>
     180                            <strong><?php esc_html_e( 'GZip Enabled:', 'spider-elements' ); ?></strong>
     181                            <?php
     182                            if ( $environment['gzip_enabled'] ) {
     183                                echo wp_kses_post( $check_icon );
     184                            } else {
     185                                echo wp_kses_post( $close_icon );
     186                            }
     187                            ?>
     188                        </li>
     189                    </ul>
     190
     191                    <ul class="list-unstyled requirement_list ezd-lg-col-6">
     192                        <li>
     193                            <strong><?php esc_html_e( 'Max Execution Time:', 'spider-elements' ); ?></strong>
     194                            <?php
     195                            if ( intval( $max_execution_time ) < 90 ) {
     196                                echo '<span title="' . esc_attr__( 'Minimum 90 Recommended', 'spider-elements' ) . '">'
     197                                    . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>';
     198                            } else {
     199                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>';
     200                            }
     201                            ?>
     202                        </li>
     203                        <li>
     204                            <strong><?php esc_html_e( 'Max Post Limit:', 'spider-elements' ); ?></strong>
     205                            <?php
     206                            if ( intval( $post_limit ) < 32 ) {
     207                                echo '<span title="' . esc_attr__( 'Minimum 32M Recommended', 'spider-elements' ) . '">'
     208                                    . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>';
     209                            } else {
     210                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>';
     211                            }
     212                            ?>
     213                        </li>
     214                        <li>
     215                            <strong><?php esc_html_e( 'Multisite:', 'spider-elements' ); ?></strong>
     216                            <?php
     217                            if ( $environment['wp_multisite'] ) {
     218                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Multisite', 'spider-elements' ) . '</span>';
     219                            } else {
     220                                echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'No Multisite', 'spider-elements' ) . '</span>';
     221                            }
     222                            ?>
     223                        </li>
     224                        <li>
     225                            <strong><?php esc_html_e( 'Debug Mode:', 'spider-elements' ); ?></strong>
     226                            <?php
     227                            if ( $environment['wp_debug_mode'] ) {
     228                                echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently Turned On', 'spider-elements' ) . '</span>';
     229                            } else {
     230                                echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'Currently Turned Off', 'spider-elements' ) . '</span>';
     231                            }
     232                            ?>
     233                        </li>
     234                    </ul>
     235                </div>
     236
     237                <div class="note">
     238                    <i class="dashicons dashicons-info-outline"></i>
     239                    <p>
    123240                        <?php
    124241                        printf(
    125                             /* translators: %1$s and %2$s are opening and closing strong HTML tags. */
     242                            /* translators: %1$s and %2$s are opening and closing strong HTML tags. */
    126243                            esc_html__(
    127                                 'Note: If you have multiple addons like %1$s Spider Elements %2$s, you may need more resources. Ensure you allocate more memory for other addons as well.', 'spider-elements'
     244                                'Note: If you have multiple addons like %1$s Spider Elements %2$s, you may need more resources. Ensure you allocate more memory for other addons as well.',
     245                                'spider-elements'
    128246                            ),
    129247                            '<strong>',
     
    131249                        );
    132250                        ?>
    133                     </p>
    134                 </div>
    135             </div>
    136         </div>
    137     </div>
    138 
    139     <div class="ezd-grid ezd-grid-cols-12">
    140         <div class="ezd-lg-col-6">
    141             <div class="support_item">
    142                 <span class="icon icon-documentation"></span>
    143                 <h2 class="dashboard_title"><?php esc_html_e( 'Documentation', 'spider-elements' ); ?></h2>
    144                 <p><?php esc_html_e( 'Get detailed and guided instruction to level up your website with the necessary set up.', 'spider-elements' ); ?></p>
    145                 <a href="https://helpdesk.spider-themes.net/docs/spider-elements" class="dashboard_btn" target="_blank">
     251                    </p>
     252                </div>
     253            </div>
     254        </div>
     255    </div>
     256
     257    <!-- Quick Links Section -->
     258    <div class="ezd-grid ezd-grid-cols-12 quick_links_grid">
     259        <div class="ezd-lg-col-6">
     260            <div class="support_item">
     261                <span class="icon icon-documentation"></span>
     262                <h2 class="dashboard_title"><?php esc_html_e( 'Documentation', 'spider-elements' ); ?></h2>
     263                <p><?php esc_html_e( 'Get detailed and guided instruction to level up your website with the necessary set up.', 'spider-elements' ); ?></p>
     264                <a href="https://helpdesk.spider-themes.net/docs/spider-elements" class="dashboard_btn" target="_blank">
     265                    <i class="icon-document"></i>
    146266                    <?php esc_html_e( 'Read Documentation', 'spider-elements' ); ?>
    147                 </a>
    148             </div>
    149         </div>
    150         <div class="ezd-lg-col-6">
    151             <div class="support_item">
    152                 <span class="icon icon-help"></span>
    153                 <h2 class="dashboard_title"><?php esc_html_e( 'Need Help', 'spider-elements' ); ?></h2>
    154                 <p><?php esc_html_e( 'If you are stuck at anything while using our product, reach out to us immediately', 'spider-elements' ); ?>
    155                 </p>
    156                 <a href="https://wordpress.org/support/plugin/spider-elements/" class="dashboard_btn" target="_blank">
    157                     <?php esc_html_e( 'Support Ticket', 'spider-elements' ); ?>
    158                 </a>
    159             </div>
    160         </div>
    161     </div>
    162 
    163 
    164     <div class="ezd-grid ezd-grid-cols-12">
    165 
    166         <div class="ezd-lg-col-6">
    167             <div class="support_item">
    168                 <span class="icon icon-love"></span>
    169                 <h2 class="dashboard_title"><?php esc_html_e( 'Show Your Love', 'spider-elements' ); ?></h2>
    170                 <p><?php echo esc_html__( 'Leave your feedback to help us out if you liked our product and customer service.', 'spider-elements' ); ?></p>
    171                 <a href="https://wordpress.org/support/plugin/spider-elements/reviews/#new-post" class="dashboard_btn" target="_blank">
     267                </a>
     268            </div>
     269        </div>
     270        <div class="ezd-lg-col-6">
     271            <div class="support_item">
     272                <span class="icon icon-help"></span>
     273                <h2 class="dashboard_title"><?php esc_html_e( 'Need Help?', 'spider-elements' ); ?></h2>
     274                <p><?php esc_html_e( 'If you are stuck at anything while using our product, reach out to us immediately!', 'spider-elements' ); ?></p>
     275                <a href="https://wordpress.org/support/plugin/spider-elements/" class="dashboard_btn" target="_blank">
     276                    <i class="icon-bubble"></i>
     277                    <?php esc_html_e( 'Get Priority Support', 'spider-elements' ); ?>
     278                </a>
     279            </div>
     280        </div>
     281        <div class="ezd-lg-col-6">
     282            <div class="support_item">
     283                <span class="icon icon-love"></span>
     284                <h2 class="dashboard_title"><?php esc_html_e( 'Love Spider Elements?', 'spider-elements' ); ?></h2>
     285                <p><?php echo esc_html__( 'Leave your feedback to help us out if you liked our product and customer service.', 'spider-elements' ); ?></p>
     286                <a href="https://wordpress.org/support/plugin/spider-elements/reviews/#new-post" class="dashboard_btn" target="_blank">
     287                    <i class="icon-star"></i>
    172288                    <?php esc_html_e( 'Leave a Review', 'spider-elements' ); ?>
    173                 </a>
    174             </div>
    175         </div>
    176         <div class="ezd-lg-col-6">
    177             <div class="support_item">
    178                 <span class="icon icon-debug"></span>
    179                 <h2 class="dashboard_title"> <?php esc_html_e( 'Facing an issues?', 'spider-elements' ); ?> </h2>
    180                 <p> <?php echo esc_html__( "Think you've spotted a bug? Please let us know! Your feedback helps us make improvements.", "spider-elements" ); ?> </p>
    181                 <a href="https://github.com/spider-themes/spider-elements/issues/new" class="dashboard_btn" target="_blank">
    182                     <?php esc_html_e( 'Get Help Now', 'spider-elements' ); ?>
    183                 </a>
    184             </div>
    185         </div>
    186     </div>
     289                </a>
     290            </div>
     291        </div>
     292        <div class="ezd-lg-col-6">
     293            <div class="support_item">
     294                <span class="icon icon-debug"></span>
     295                <h2 class="dashboard_title"> <?php esc_html_e( 'Found a Bug?', 'spider-elements' ); ?> </h2>
     296                <p> <?php echo esc_html__( "Think you've spotted a bug? Please let us know! Your feedback helps us make improvements.", 'spider-elements' ); ?> </p>
     297                <a href="https://github.com/spider-themes/spider-elements/issues/new" class="dashboard_btn" target="_blank">
     298                    <i class="icon-github"></i>
     299                    <?php esc_html_e( 'Report on GitHub', 'spider-elements' ); ?>
     300                </a>
     301            </div>
     302        </div>
     303    </div>
    187304
    188305</div>
  • spider-elements/trunk/includes/Frontend/Assets.php

    r3416399 r3464401  
    4242        $theme = wp_get_theme();
    4343        $features_opt   = get_option( 'spel_features_settings' );
    44         $is_premium_or_theme = spel_is_premium() || in_array($theme->get('Name'), ['jobi', 'Jobi', 'jobi-child', 'Jobi Child']);
     44        $is_premium_or_theme = spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true );
    4545
    46         if ( isset($features_opt['spel_smooth_animation']) && $features_opt[ 'spel_smooth_animation' ] == 'on' ) {
     46        if ( isset( $features_opt['spel_smooth_animation'] ) && 'on' === $features_opt['spel_smooth_animation'] ) {
    4747
    4848            // Define all the handlers in one string, separated by commas
     
    7575
    7676        if ( $is_premium_or_theme ) {
    77             if ( isset($features_opt['spel_heading_highlighted']) && $features_opt[ 'spel_heading_highlighted' ] == 'on' ) {
    78                 wp_enqueue_style('spel-extension');
     77            if ( isset( $features_opt['spel_heading_highlighted'] ) && 'on' === $features_opt['spel_heading_highlighted'] ) {
     78                wp_enqueue_style( 'spel-extension' );
    7979            }
    80             if ( isset($features_opt['spel_badge']) && $features_opt[ 'spel_badge' ] == 'on' ) {
    81                 wp_enqueue_style('spel-extension');
     80            if ( isset( $features_opt['spel_badge'] ) && 'on' === $features_opt['spel_badge'] ) {
     81                wp_enqueue_style( 'spel-extension' );
    8282            }
    8383        }
  • spider-elements/trunk/includes/filters.php

    r3416399 r3464401  
    11<?php
     2/**
     3 * Plugin Filters and Actions
     4 *
     5 * This file handles various hooks, including image sizes, constants,
     6 * and admin form submissions.
     7 *
     8 * @package SpiderElements
     9 */
     10
    211if ( ! defined( 'ABSPATH' ) ) {
    312    exit; // Exit if accessed directly
     
    2635
    2736
     37/**
     38 * Handle Element Settings Form Submission
     39 */
    2840add_action( 'admin_init', function () {
    2941
     
    5163            'spe_timeline_widget',
    5264            'spe_counter',
    53             'spel_icon_box'
     65            'spel_icon_box',
    5466        ];
    5567
     
    6678            'spel_marquee_slider',
    6779            'spe_skill_showcase_widget',
    68             'spel_stacked_image'
     80            'spel_stacked_image',
    6981        ];
    7082
     
    120132
    121133
    122 // Dashboard Features Setting Save Data
     134/**
     135 * Handle Features Settings Form Submission
     136 */
    123137add_action( 'admin_init', function () {
    124138
     
    156170        update_option( 'spel_features_settings', $data );
    157171
    158         // If the user is not on a pro-plan or Jobi theme, reset pro-widgets
     172        // If the user is not on a pro-plan or Jobi theme, reset pro-features
    159173        $theme               = wp_get_theme();
    160         $is_premium_or_theme = spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] );
     174        $theme_name          = $theme->get( 'Name' );
     175        $is_premium_or_theme = spel_is_premium() || in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true );
     176
     177        // Smooth Animation is unlocked for Docy, Jobi, Docly, or Ama theme users
     178        $is_smooth_anim_unlocked = spel_unlock_docy_theme()
     179            || in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true )
     180            || in_array( $theme_name, [ 'Docly', 'docly', 'Docly Child', 'docly-child' ], true )
     181            || in_array( $theme_name, [ 'Ama', 'ama', 'Ama Child', 'ama-child' ], true );
     182
    161183        if ( ! $is_premium_or_theme ) {
    162184            foreach ( $pro_features as $feature ) {
     185                // Keep Smooth Animation enabled for Docy, Jobi, or Docly theme users
     186                if ( $feature === 'spel_smooth_animation' && $is_smooth_anim_unlocked ) {
     187                    continue;
     188                }
    163189                $data[ $feature ] = 'off';
    164190            }
  • spider-elements/trunk/includes/functions.php

    r3393425 r3464401  
    66
    77/**
    8  * Check if the pro-plugin and plan is active
     8 * Check if the pro-plugin and plan is active.
     9 *
     10 * @return bool True if premium code can be used, false otherwise.
     11 */
     12function spel_is_premium(): bool {
     13    return spel_fs()->is_plan( 'pro' ) && spel_fs()->can_use_premium_code();
     14}
     15
     16/**
     17 * Check if the Docy theme is active
    918 *
    1019 * @return bool
    1120 */
    12 function spel_is_premium(): bool
    13 {
    14     return spel_fs()->is_plan('pro') && spel_fs()->can_use_premium_code();
    15 }
    16 
    1721function spel_unlock_docy_theme(): bool {
    18     $theme = wp_get_theme();
    19     $theme_name = $theme->get('Name');
    20     $docy_themes = [ 'Docy', 'docy', 'Docy Child', 'docy-child' ];
    21 
    22     return in_array($theme_name, $docy_themes, true) || spel_is_premium();
    23 }
    24 
    25 if ( ! function_exists( 'spel_rtl') ) {
    26     function spel_rtl(): string {
     22    $theme       = wp_get_theme();
     23    $theme_name  = $theme->get( 'Name' );
     24    $docy_themes = [ 'Docy', 'docy', 'Docy Child', 'docy-child' ];
     25
     26    return in_array( $theme_name, $docy_themes, true ) || spel_is_premium();
     27}
     28
     29function spel_rtl(): string {
    2730        return is_rtl() ? 'true' : 'false';
    28     }
    29 }
    30 
    31 /**
     31}
     32
     33/**
     34 * Elementor is edit mode
     35 *
    3236 * @return bool
    33  * Elementor is edit mode
    34  */
    35 function spider_elements_is_edit(): bool
    36 {
     37 */
     38function spider_elements_is_edit(): bool {
    3739    return \Elementor\Plugin::$instance->editor->is_edit_mode();
    3840}
    3941
    4042/**
     43 * Elementor is preview mode
     44 *
    4145 * @return bool
    42  * Elementor is preview mode
    43  */
    44 function spider_elements_is_preview(): bool
    45 {
     46 */
     47function spider_elements_is_preview(): bool {
    4648    return \Elementor\Plugin::$instance->preview->is_preview_mode();
    4749}
     
    4951/**
    5052 * Elementor Title tags
     53 *
     54 * @return array
    5155 */
    5256if ( ! function_exists( 'spel_get_title_tags' ) ) {
    53     function spel_get_title_tags(): array
    54     {
    55         return [
    56             'h1'   => esc_html__( 'H1', 'spider-elements' ),
    57             'h2'   => esc_html__( 'H2', 'spider-elements' ),
    58             'h3'   => esc_html__( 'H3', 'spider-elements' ),
    59             'h4'   => esc_html__( 'H4', 'spider-elements' ),
    60             'h5'   => esc_html__( 'H5', 'spider-elements' ),
    61             'h6'   => esc_html__( 'H6', 'spider-elements' ),
    62             'div'  => esc_html__( 'Div', 'spider-elements' ),
    63             'span' => esc_html__( 'Span', 'spider-elements' ),
    64             'p'    => esc_html__( 'Paragraph', 'spider-elements' ),
    65         ];
    66     }
     57    function spel_get_title_tags(): array {
     58        return [
     59            'h1'   => esc_html__( 'H1', 'spider-elements' ),
     60            'h2'   => esc_html__( 'H2', 'spider-elements' ),
     61            'h3'   => esc_html__( 'H3', 'spider-elements' ),
     62            'h4'   => esc_html__( 'H4', 'spider-elements' ),
     63            'h5'   => esc_html__( 'H5', 'spider-elements' ),
     64            'h6'   => esc_html__( 'H6', 'spider-elements' ),
     65            'div'  => esc_html__( 'Div', 'spider-elements' ),
     66            'span' => esc_html__( 'Span', 'spider-elements' ),
     67            'p'    => esc_html__( 'Paragraph', 'spider-elements' ),
     68        ];
     69    }
    6770}
    6871
     
    7073 * Echo button link attributes.
    7174 *
    72  * @param array $settings_key
    73  * @param bool  $is_echo
     75 * @param array $settings_key Settings array.
     76 * @param bool  $is_echo      Whether to echo the attributes.
     77 * @return void
    7478 */
    7579if ( ! function_exists( 'spel_button_link' ) ) {
    76     function spel_button_link( $settings_key, $is_echo = true ): void
    77     {
    78         if ( $is_echo ) {
    79             echo ! empty( $settings_key['url'] ) ? 'href="' . esc_url( $settings_key['url'] ) . '"' : '';
    80             echo $settings_key['is_external'] ? ' target="_blank"' : '';
    81             echo $settings_key['nofollow'] ? ' rel="nofollow"' : '';
    82 
    83             if ( ! empty( $settings_key['custom_attributes'] ) ) {
    84                 $attrs = explode( ',', $settings_key['custom_attributes'] );
    85 
    86                 if ( is_array( $attrs ) ) {
    87                     foreach ( $attrs as $data ) {
    88                         $data_attrs = explode( '|', $data );
    89                         echo ' ' . esc_attr( $data_attrs[0] ) . '="' . esc_attr( $data_attrs[1] ) . '"';
    90                     }
    91                 }
    92             }
    93         }
    94     }
     80    function spel_button_link( $settings_key, $is_echo = true ): void {
     81        if ( $is_echo ) {
     82            echo ! empty( $settings_key['url'] ) ? 'href="' . esc_url( $settings_key['url'] ) . '"' : '';
     83            echo $settings_key['is_external'] ? ' target="_blank"' : '';
     84            echo $settings_key['nofollow'] ? ' rel="nofollow"' : '';
     85
     86            if ( ! empty( $settings_key['custom_attributes'] ) ) {
     87                $attrs = explode( ',', $settings_key['custom_attributes'] );
     88
     89                if ( is_array( $attrs ) ) {
     90                    foreach ( $attrs as $data ) {
     91                        $data_attrs = explode( '|', $data, 2 );
     92                        $attr_name  = trim( $data_attrs[0] );
     93                        $attr_value = isset( $data_attrs[1] ) ? $data_attrs[1] : '';
     94
     95                        // Security: Sanitize attribute name (allow alphanumeric, dashes, colons)
     96                        $attr_name = preg_replace( '/[^a-zA-Z0-9_\-:]/', '', $attr_name );
     97
     98                        // Security: Prevent XSS by blocking event handlers (on*) and critical attributes
     99                        if ( preg_match( '/^(on|href|src|formaction)/i', $attr_name ) ) {
     100                            continue;
     101                        }
     102
     103                        if ( ! empty( $attr_name ) ) {
     104                            echo ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
     105                        }
     106                    }
     107                }
     108            }
     109        }
     110    }
    95111}
    96112
    97113/**
    98114 * Category IDs
     115 *
    99116 * @return array
    100  */
    101 if ( ! function_exists( 'spel_cat_ids') ) {
    102     function spel_cat_ids() {
    103 
    104         $taxonomys = get_terms( array(
    105             'taxonomy'   => 'category',
    106             'hide_empty' => true,
    107         ) );
    108         $taxonomy  = [];
    109         if ( is_array( $taxonomys ) ) {
    110             foreach ( $taxonomys as $cat_id ) {
    111                 $taxonomy[ $cat_id->term_id ] = $cat_id->name;
    112             }
    113         }
    114 
    115         return $taxonomy;
    116 
    117     }
     117 * @since 1.0.0
     118 */
     119if ( ! function_exists( 'spel_cat_ids' ) ) {
     120    function spel_cat_ids() {
     121        $taxonomys = get_terms( [
     122            'taxonomy'   => 'category',
     123            'hide_empty' => true,
     124        ] );
     125        $taxonomy  = [];
     126        if ( is_array( $taxonomys ) ) {
     127            foreach ( $taxonomys as $cat_id ) {
     128                $taxonomy[ $cat_id->term_id ] = $cat_id->name;
     129            }
     130        }
     131
     132        return $taxonomy;
     133    }
    118134}
    119135
    120136/**
    121137 * Day link to archive page
     138 *
     139 * @return void
    122140 **/
    123141if ( ! function_exists( 'spel_day_link' ) ) {
    124     function spel_day_link(): void
    125     {
    126         $archive_year  = get_the_time( 'Y' );
    127         $archive_month = get_the_time( 'm' );
    128         $archive_day   = get_the_time( 'd' );
    129         echo esc_url( get_day_link( $archive_year, $archive_month, $archive_day ) );
    130     }
     142    function spel_day_link(): void {
     143        $archive_year  = get_the_time( 'Y' );
     144        $archive_month = get_the_time( 'm' );
     145        $archive_day   = get_the_time( 'd' );
     146        echo esc_url( get_day_link( $archive_year, $archive_month, $archive_day ) );
     147    }
    131148}
    132149
     
    144161 *
    145162 * @return string The trimmed post title, or empty string if no title exists.
     163 * @since 1.0.0
    146164 */
    147165function spel_get_title_length( array $settings, string $settings_key, int $default = 10 ): string {
     
    156174 * Post's excerpt text
    157175 *
    158  * @param $settings_key
    159  * @param bool $echo
     176 * @param array  $settings
     177 * @param string $settings_key
     178 * @param int    $default
    160179 *
    161180 * @return string
    162  **/
     181 * @since 1.0.0
     182 */
    163183if ( ! function_exists( 'spel_get_excerpt_length' ) ) {
    164     function spel_get_excerpt_length( $settings, $settings_key, $default = 10 ): string {
    165         $excerpt_length = ! empty( $settings[ $settings_key ] ) ? $settings[ $settings_key ] : $default;
    166         return get_the_excerpt() ? wp_trim_words( get_the_excerpt(), $excerpt_length, '...' ) : wp_trim_words( get_the_content(), $excerpt_length, '...' );
    167     }
     184    function spel_get_excerpt_length( $settings, $settings_key, $default = 10 ): string {
     185        $excerpt_length = ! empty( $settings[ $settings_key ] ) ? $settings[ $settings_key ] : $default;
     186
     187        return get_the_excerpt() ? wp_trim_words( get_the_excerpt(), $excerpt_length, '...' ) : wp_trim_words( get_the_content(), $excerpt_length, '...' );
     188    }
    168189}
    169190
     
    175196 *
    176197 * @return string
     198 * @since 1.0.0
    177199 */
    178200if ( ! function_exists( 'spel_get_first_taxonomy' ) ) {
    179     function spel_get_first_taxonomy( $term = 'category' ): string
    180     {
    181         $cats = get_the_terms( get_the_ID(), $term );
    182         $cat  = is_array( $cats ) ? $cats[0]->name : '';
    183 
    184         return esc_html( $cat );
    185     }
     201    function spel_get_first_taxonomy( $term = 'category' ): string {
     202        $cats = get_the_terms( get_the_ID(), $term );
     203        $cat  = is_array( $cats ) ? $cats[0]->name : '';
     204
     205        return esc_html( $cat );
     206    }
    186207}
    187208
     
    193214 *
    194215 * @return string
     216 * @since 1.0.0
    195217 */
    196218if ( ! function_exists( 'spel_get_first_taxonomy_link' ) ) {
    197     function spel_get_first_taxonomy_link( $term = 'category' ): string
    198     {
    199 
    200         $cats = get_the_terms( get_the_ID(), $term );
    201         $cat  = is_array( $cats ) ? get_category_link( $cats[0]->term_id ) : '';
    202 
    203         return esc_url( $cat );
    204     }
     219    function spel_get_first_taxonomy_link( $term = 'category' ): string {
     220
     221        $cats = get_the_terms( get_the_ID(), $term );
     222        $cat  = is_array( $cats ) ? get_category_link( $cats[0]->term_id ) : '';
     223
     224        return esc_url( $cat );
     225    }
    205226}
    206227
     
    212233 *
    213234 * @return array
     235 * @since 1.0.0
    214236 */
    215237if ( ! function_exists( 'spel_get_categories' ) ) {
    216     function spel_get_categories( $term = 'category' ) {
    217 
    218         $cats = get_terms( array(
    219             'taxonomy'   => $term,
    220             'hide_empty' => true
    221         ) );
    222 
    223         $cat_array        = [];
    224         $cat_array['all'] = esc_html__( 'All', 'spider-elements' );
    225 
    226         if ( is_array( $cats ) ) {
    227             foreach ( $cats as $cat ) {
    228                 $cat_array[ $cat->term_id ] = $cat->name;
    229             }
    230         }
    231 
    232         return $cat_array;
    233     }
     238    function spel_get_categories( $term = 'category' ) {
     239
     240        $cats = get_terms( [
     241            'taxonomy'   => $term,
     242            'hide_empty' => true
     243        ] );
     244
     245        $cat_array        = [];
     246        $cat_array['all'] = esc_html__( 'All', 'spider-elements' );
     247
     248        if ( is_array( $cats ) ) {
     249            foreach ( $cats as $cat ) {
     250                $cat_array[ $cat->term_id ] = $cat->name;
     251            }
     252        }
     253
     254        return $cat_array;
     255    }
    234256}
    235257
     
    238260 * Get a category list
    239261 *
    240  * @param string $term
     262 * @return void
     263 * @since 1.0.0
     264 */
     265if ( ! function_exists( 'spel_get_post_category_list' ) ) {
     266    function spel_get_post_category_list(): void {
     267        $categories = get_categories();
     268
     269        if ( ! empty( $categories ) ) {
     270            echo '<span class="blog-category">';
     271
     272            $category_names = [];
     273
     274            if ( is_array( $categories ) ) {
     275                foreach ( $categories as $category ) {
     276                    $category_link    = get_category_link( $category->term_id );
     277                    $category_names[] = '<a href="' . esc_url( $category_link ) . '">' . esc_html( $category->name ) . '</a>';
     278                }
     279            }
     280
     281            echo esc_html( implode( ', ', $category_names ) );
     282
     283            echo '</span>';
     284        } else {
     285            echo esc_html__( 'No categories found.', 'spider-elements' );
     286        }
     287    }
     288}
     289
     290
     291/**
     292 * Get an author name array
     293 *
     294 * @return void
     295 * @since 1.0.0
     296 */
     297if ( ! function_exists( 'spel_get_post_author_name' ) ) {
     298    function spel_get_post_author_name(): void {
     299        global $post;
     300        $byline = sprintf(
     301        /* translators: %s: post author. */
     302            esc_html_x( 'By: %s', 'post author', 'spider-elements' ),
     303            '<span class="author"><a class="url fn n" href="' . esc_url( get_author_posts_url( $post->post_author ) ) . '">' . esc_html( get_the_author_meta(
     304                'display_name',
     305                $post->post_author
     306            ) ) . '</a></span>'
     307        );
     308
     309        echo wp_kses_post( $byline ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     310    }
     311}
     312
     313/**
     314 * Get Default Image Elementor
     315 *
     316 * @param array  $settings_key
     317 * @param string $alt
     318 * @param string $class
     319 * @param array  $atts
     320 * @return void
     321 * @since 1.0.0
     322 */
     323if ( ! function_exists( 'spel_el_image' ) ) {
     324    function spel_el_image( $settings_key = [], $alt = '', $class = '', $atts = [] ): void {
     325        if ( ! empty( $settings_key['id'] ) ) {
     326            // WordPress handles escaping internally here
     327            echo wp_get_attachment_image( $settings_key['id'], 'full', false, [ 'class' => esc_attr( $class ) ] );
     328        } elseif ( ! empty( $settings_key['url'] ) && empty( $settings_key['id'] ) ) {
     329            $class_attr = ! empty( $class ) ? ' class="' . esc_attr( $class ) . '"' : '';
     330            $atts_str   = '';
     331
     332            if ( ! empty( $atts ) ) {
     333                foreach ( $atts as $k => $att ) {
     334                    // Security: Sanitize attribute name (allow alphanumeric, dashes, colons)
     335                    $k = preg_replace( '/[^a-zA-Z0-9_\-:]/', '', $k );
     336
     337                    // Security: Prevent XSS by blocking event handlers (on*) and critical attributes
     338                    if ( empty( $k ) || preg_match( '/^(on|style|formaction|src|href)/i', $k ) ) {
     339                        continue;
     340                    }
     341
     342                    $atts_str .= ' ' . esc_attr( $k ) . '="' . esc_attr( $att ) . '"';
     343                }
     344            }
     345
     346            printf(
     347                '<img src="%1$s"%2$s alt="%3$s"%4$s />',
     348                esc_url( $settings_key['url'] ),
     349                // $class_attr contains safe HTML attribute string
     350                $class_attr, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     351                esc_attr( $alt ),
     352                // $atts_str contains safe HTML attribute string
     353                $atts_str // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     354            );
     355        }
     356    }
     357}
     358
     359
     360/**
     361 * Get Default Image Elementor Caption
     362 *
     363 * @param $image_id
     364 *
     365 * @return array
     366 */
     367if ( ! function_exists( 'spel_el_image_caption' ) ) {
     368    function spel_el_image_caption( $image_id = '' ): array {
     369        $img_attachment = get_post( $image_id );
     370
     371        return [
     372            'alt'     => get_post_meta( $img_attachment->ID, '_wp_attachment_image_alt', true ),
     373            'caption' => $img_attachment->post_excerpt,
     374            'href'    => get_permalink( $img_attachment->ID ),
     375            'src'     => $img_attachment->guid,
     376            'title'   => $img_attachment->post_title
     377        ];
     378    }
     379}
     380
     381
     382/**
     383 * Filter text content to allow only safe HTML.
     384 *
     385 * @param string $content Text content to filter.
     386 *
     387 * @return string Filtered content containing only the allowed HTML.
     388 * @since 1.0.0
     389 */
     390if ( ! function_exists( 'spel_kses_post' ) ) {
     391    function spel_kses_post( $content ): string {
     392        $allowed_tag = [
     393            'strong' => [],
     394            'br'     => [],
     395            'p'      => [
     396                'class' => [],
     397                'style' => [],
     398            ],
     399            'i'      => [
     400                'class' => [],
     401                'style' => [],
     402            ],
     403            'ul'     => [
     404                'class' => [],
     405                'style' => [],
     406            ],
     407            'li'     => [
     408                'class' => [],
     409                'style' => [],
     410            ],
     411            'span'   => [
     412                'class' => [],
     413                'style' => [],
     414            ],
     415            'a'      => [
     416                'href'  => [],
     417                'class' => [],
     418                'title' => []
     419            ],
     420            'div'    => [
     421                'class' => [],
     422                'style' => [],
     423            ],
     424            'h1'     => [
     425                'class' => [],
     426                'style' => []
     427            ],
     428            'h2'     => [
     429                'class' => [],
     430                'style' => []
     431            ],
     432            'h3'     => [
     433                'class' => [],
     434                'style' => []
     435            ],
     436            'h4'     => [
     437                'class' => [],
     438                'style' => []
     439            ],
     440            'h5'     => [
     441                'class' => [],
     442                'style' => []
     443            ],
     444            'h6'     => [
     445                'class' => [],
     446                'style' => []
     447            ],
     448            'img'    => [
     449                'class'  => [],
     450                'style'  => [],
     451                'height' => [],
     452                'width'  => [],
     453                'src'    => [],
     454                'srcset' => [],
     455                'alt'    => [],
     456            ],
     457
     458        ];
     459
     460        return wp_kses( $content, $allowed_tag );
     461    }
     462}
     463
     464
     465/**
     466 * Tab data
     467 *
     468 * @param array $getCats
     469 * @param array $schedule_cats
     470 *
     471 * @return array
     472 * @since 1.0.0
     473 */
     474if ( ! function_exists( 'spel_get_tab_data' ) ) {
     475    function spel_get_tab_data( $getCats, $schedule_cats ): array {
     476        $tab_data = [];
     477
     478        foreach ( $getCats as $val ) {
     479            $matching_data = [];
     480
     481            foreach ( $schedule_cats as $data ) {
     482                if ( $val === $data['tab_title'] ) {
     483                    $matching_data[] = $data;
     484                }
     485            }
     486
     487            $tab_data[ $val ] = $matching_data;
     488        }
     489
     490        return $tab_data;
     491    }
     492}
     493
     494
     495/**
     496 * Get reading time
     497 *
     498 * @param int $words_per_minute
    241499 *
    242500 * @return string
    243  */
    244 if ( ! function_exists( 'spel_get_post_category_list' ) ) {
    245     function spel_get_post_category_list(): void
    246     {
    247         $categories = get_categories();
    248 
    249         if ( ! empty( $categories ) ) {
    250             echo '<span class="blog-category">';
    251 
    252             $category_names = array();
    253 
    254             if ( is_array( $categories ) ) {
    255                 foreach ( $categories as $category ) {
    256                     $category_link    = get_category_link( $category->term_id );
    257                     $category_names[] = '<a href="' . esc_url( $category_link ) . '">' . esc_html( $category->name ) . '</a>';
    258                 }
    259             }
    260 
    261             echo esc_html( implode( ', ', $category_names ) );
    262 
    263             echo '</span>';
    264         } else {
    265             echo esc_html__( 'No categories found.', 'spider-elements' );
    266         }
    267     }
    268 }
    269 
    270 
    271 /**
    272  * Get an author name array
    273  *
    274  * @param string $term
    275  *
    276  * @return array
    277  */
    278 if ( ! function_exists( 'spel_get_post_author_name' ) ) {
    279     function spel_get_post_author_name(): void
    280     {
    281         global $post;
    282         $byline = sprintf(
    283         /* translators: %s: post author. */
    284             esc_html_x( 'By: %s', 'post author', 'spider-elements' ),
    285             '<span class="author"><a class="url fn n" href="' . esc_url( get_author_posts_url( $post->post_author ) ) . '">' . esc_html( get_the_author_meta(
    286                 'display_name',
    287                 $post->post_author
    288             ) ) . '</a></span>'
    289         );
    290 
    291         echo wp_kses_post( $byline ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    292     }
    293 }
    294 
    295 /**
    296  * Get Default Image Elementor
    297  *
    298  * @param $settins_key
    299  * @param string $class
    300  * @param string $alt
    301  */
    302 if ( ! function_exists( 'spel_el_image' ) ) {
    303     function spel_el_image( $settings_key = [], $alt = '', $class = '', $atts = [] ): void {
    304         if ( ! empty( $settings_key['id'] ) ) {
    305             // WordPress handles escaping internally here
    306             echo wp_get_attachment_image( $settings_key['id'], 'full', false, [ 'class' => esc_attr( $class ) ] );
    307         } elseif ( ! empty( $settings_key['url'] ) && empty( $settings_key['id'] ) ) {
    308             $class_attr = ! empty( $class ) ? ' class="' . esc_attr( $class ) . '"' : '';
    309             $atts_str   = '';
    310 
    311             if ( ! empty( $atts ) ) {
    312                 foreach ( $atts as $k => $att ) {
    313                     $atts_str .= ' ' . esc_attr( $k ) . '="' . esc_attr( $att ) . '"';
    314                 }
    315             }
    316 
    317             printf(
    318                 '<img src="%1$s"%2$s alt="%3$s"%4$s />',
    319                 esc_url( $settings_key['url'] ),
    320                 wp_kses_post( $class_attr ), // Escape class attribute
    321                 esc_attr( $alt ),
    322                 wp_kses_post( $atts_str ) // Escape attributes string
    323             );
    324         }
    325     }
    326 }
    327 
    328 
    329 
    330 /**
    331  * Get Default Image Elementor
    332  *
    333  * @param $settins_key
    334  * @param string $class
    335  * @param string $alt
    336  */
    337 if ( ! function_exists( 'spel_el_image_caption' ) ) {
    338     function spel_el_image_caption( $image_id = '' ): array
    339     {
    340         $img_attachment = get_post( $image_id );
    341 
    342         return array(
    343             'alt'     => get_post_meta( $img_attachment->ID, '_wp_attachment_image_alt', true ),
    344             'caption' => $img_attachment->post_excerpt,
    345             'href'    => get_permalink( $img_attachment->ID ),
    346             'src'     => $img_attachment->guid,
    347             'title'   => $img_attachment->post_title
    348         );
    349     }
    350 }
    351 
    352 
    353 /**
    354  * @param string $content Text content to filter.
    355  *
    356  * @return string Filtered content containing only the allowed HTML.
    357  */
    358 if ( ! function_exists( 'spel_kses_post' ) ) {
    359     function spel_kses_post( $content ): string
    360     {
    361         $allowed_tag = array(
    362             'strong' => [],
    363             'br'     => [],
    364             'p'      => [
    365                 'class' => [],
    366                 'style' => [],
    367             ],
    368             'i'      => [
    369                 'class' => [],
    370                 'style' => [],
    371             ],
    372             'ul'     => [
    373                 'class' => [],
    374                 'style' => [],
    375             ],
    376             'li'     => [
    377                 'class' => [],
    378                 'style' => [],
    379             ],
    380             'span'   => [
    381                 'class' => [],
    382                 'style' => [],
    383             ],
    384             'a'      => [
    385                 'href'  => [],
    386                 'class' => [],
    387                 'title' => []
    388             ],
    389             'div'    => [
    390                 'class' => [],
    391                 'style' => [],
    392             ],
    393             'h1'     => [
    394                 'class' => [],
    395                 'style' => []
    396             ],
    397             'h2'     => [
    398                 'class' => [],
    399                 'style' => []
    400             ],
    401             'h3'     => [
    402                 'class' => [],
    403                 'style' => []
    404             ],
    405             'h4'     => [
    406                 'class' => [],
    407                 'style' => []
    408             ],
    409             'h5'     => [
    410                 'class' => [],
    411                 'style' => []
    412             ],
    413             'h6'     => [
    414                 'class' => [],
    415                 'style' => []
    416             ],
    417             'img'    => [
    418                 'class'  => [],
    419                 'style'  => [],
    420                 'height' => [],
    421                 'width'  => [],
    422                 'src'    => [],
    423                 'srcset' => [],
    424                 'alt'    => [],
    425             ],
    426 
    427         );
    428 
    429         return wp_kses( $content, $allowed_tag );
    430     }
    431 }
    432 
    433 
    434 /**
    435  * Tab data
    436  *
    437  * @param $getCats
    438  * @param $schedule_cats
    439  *
    440  * @return array
    441  */
    442 if ( ! function_exists( 'spel_get_tab_data' ) ) {
    443     function spel_get_tab_data( $getCats, $schedule_cats ): array
    444     {
    445         $tab_data = [];
    446 
    447         foreach ( $getCats as $val ) {
    448             $matching_data = [];
    449 
    450             foreach ( $schedule_cats as $data ) {
    451                 if ( $data['tab_title'] == $val ) {
    452                     $matching_data[] = $data;
    453                 }
    454             }
    455 
    456             $tab_data[ $val ] = $matching_data;
    457         }
    458 
    459         return $tab_data;
    460     }
    461 }
    462 
    463 
    464 /**
    465  * Get reading time
    466  *
    467  * @param string $term
    468  *
    469  * @return string
     501 * @since 1.0.0
    470502 */
    471503if ( ! function_exists( 'spel_get_reading_time' ) ) {
    472     function spel_get_reading_time( $words_per_minute = 200 ): string
    473     {
    474         $content      = get_post_field( 'post_content', get_the_ID() );
    475         $word_count   = str_word_count( wp_strip_all_tags( $content ) );
    476         $reading_time = ceil( $word_count / $words_per_minute );
    477         $timer        = _n( 'minute', 'minutes', $reading_time, 'spider-elements' );
    478 
    479         return sprintf( '%d %s', $reading_time, $timer );
    480     }
     504    function spel_get_reading_time( $words_per_minute = 200 ): string {
     505        $content      = get_post_field( 'post_content', get_the_ID() );
     506        $word_count   = str_word_count( wp_strip_all_tags( $content ) );
     507        $reading_time = ceil( $word_count / $words_per_minute );
     508        $timer        = _n( 'minute', 'minutes', $reading_time, 'spider-elements' );
     509
     510        return sprintf( '%d %s', $reading_time, $timer );
     511    }
    481512}
    482513
     
    484515 * Render Dynamic Image
    485516 * @param $key
    486  * @param $class
     517 * @param $size
     518 * @param $atts
    487519 * @return void
     520 * @since 1.0.0
    488521 */
    489522if ( ! function_exists( 'spel_dynamic_image' ) ) {
    490     function spel_dynamic_image( $key, $size = 'full', $atts = [] ): void
    491     {
    492         $image = wp_get_attachment_image( $key['id'], $size, '', $atts );
    493         echo wp_kses( $image, [
    494             'img'    => [
    495                 'class'  => [],
    496                 'style'  => [],
    497                 'height' => [],
    498                 'width'  => [],
    499                 'src'    => [],
    500                 'srcset' => [],
    501                 'alt'    => [],
    502             ],
    503         ]);
    504     }
    505 }
    506 
     523    function spel_dynamic_image( $key, $size = 'full', $atts = [] ): void {
     524        $image = wp_get_attachment_image( $key['id'], $size, '', $atts );
     525        echo wp_kses( $image, [
     526            'img'    => [
     527                'class'  => [],
     528                'style'  => [],
     529                'height' => [],
     530                'width'  => [],
     531                'src'    => [],
     532                'srcset' => [],
     533                'alt'    => [],
     534            ],
     535        ] );
     536    }
     537}
    507538
    508539
     
    515546 *
    516547 * @return array An associative array with post-IDs as keys and post-titles as values.
     548 * @since 1.0.0
    517549 */
    518550if ( ! function_exists( 'spel_get_query_post_list' ) ) {
    519     function spel_get_query_post_list( $post_type = 'any', $limit = -1, $search = '' ): array
    520     {
    521         $args = [
    522             'post_type' => $post_type,
    523             'post_status' => 'publish',
    524             'posts_per_page' => $limit,
    525             's' => $search, // Search term
    526         ];
    527 
    528         $query = new WP_Query( $args );
    529 
    530         $data = [];
    531         if ( $query->have_posts() ) {
    532             while ( $query->have_posts() ) {
    533                 $query->the_post();
    534                 $data[ get_the_ID() ] = get_the_title();
    535             }
    536         }
    537 
    538         wp_reset_postdata(); // Reset post data after custom query
    539 
    540         return $data;
    541     }
     551    function spel_get_query_post_list( $post_type = 'any', $limit = -1, $search = '' ): array {
     552        $args = [
     553            'post_type'      => $post_type,
     554            'post_status'    => 'publish',
     555            'posts_per_page' => $limit,
     556            's'              => $search, // Search term
     557        ];
     558
     559        $query = new WP_Query( $args );
     560
     561        $data = [];
     562        if ( $query->have_posts() ) {
     563            while ( $query->have_posts() ) {
     564                $query->the_post();
     565                $data[ get_the_ID() ] = get_the_title();
     566            }
     567        }
     568
     569        wp_reset_postdata(); // Reset post data after custom query
     570
     571        return $data;
     572    }
    542573}
    543574
     
    546577 * Get all elementor page templates
    547578 *
    548  * @param null $type
     579 * @param string|null $type
    549580 *
    550581 * @return array
     582 * @since 1.0.0
    551583 */
    552584if ( ! function_exists( 'spel_get_el_templates' ) ) {
    553     function spel_get_el_templates( $type = null ): array
    554     {
    555         $options = [];
    556 
    557         if ( $type ) {
    558 
    559             $args              = [
    560                 'post_type'      => 'elementor_library',
    561                 'posts_per_page' => -1,
    562             ];
    563 
    564             $args['tax_query'] = [
    565                 [
    566                     'taxonomy' => 'elementor_library_type',
    567                     'field'    => 'slug',
    568                     'terms'    => $type,
    569                 ],
    570             ];
    571 
    572             $page_templates = get_posts( $args );
    573 
    574             if ( ! empty( $page_templates ) && ! is_wp_error( $page_templates ) ) {
    575                 foreach ( $page_templates as $post ) {
    576                     $options[ $post->ID ] = $post->post_title;
    577                 }
    578             }
    579         } else {
    580             $options = spel_get_query_post_list( 'elementor_library' );
    581         }
    582 
    583         return $options;
    584     }
     585    function spel_get_el_templates( $type = null ): array {
     586        $options = [];
     587
     588        if ( $type ) {
     589
     590            $args = [
     591                'post_type'      => 'elementor_library',
     592                'posts_per_page' => -1,
     593            ];
     594
     595            $args['tax_query'] = [
     596                [
     597                    'taxonomy' => 'elementor_library_type',
     598                    'field'    => 'slug',
     599                    'terms'    => $type,
     600                ],
     601            ];
     602
     603            $page_templates = get_posts( $args );
     604
     605            if ( ! empty( $page_templates ) && ! is_wp_error( $page_templates ) ) {
     606                foreach ( $page_templates as $post ) {
     607                    $options[ $post->ID ] = $post->post_title;
     608                }
     609            }
     610        } else {
     611            $options = spel_get_query_post_list( 'elementor_library' );
     612        }
     613
     614        return $options;
     615    }
    585616}
    586617
     
    590621 *
    591622 * @return array Server environment information.
     623 * @since 1.0.0
    592624 */
    593625if ( ! function_exists( 'spel_get_environment_info' ) ) {
    594     function spel_get_environment_info(): array
    595     {
    596 
    597         // Figure out cURL version, if installed.
    598         $curl_version = '';
    599         if ( function_exists( 'curl_version' ) ) {
    600             $curl_version = curl_version();
    601             $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
    602         }
    603 
    604         // WP memory limit.
    605         $wp_memory_limit = spel_readable_number(WP_MEMORY_LIMIT);
    606         if ( function_exists( 'memory_get_usage' ) ) {
    607             $wp_memory_limit = max( $wp_memory_limit, spel_readable_number( @ini_get( 'memory_limit' ) ) );
    608         }
    609 
    610         return array(
    611             'home_url'                  => get_option( 'home' ),
    612             'site_url'                  => get_option( 'siteurl' ),
    613             'version'                   => SPEL_VERSION,
    614             'wp_version'                => get_bloginfo( 'version' ),
    615             'wp_multisite'              => is_multisite(),
    616             'wp_memory_limit'           => $wp_memory_limit,
    617             'wp_debug_mode'             => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
    618             'wp_cron'                   => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
    619             'language'                  => get_locale(),
    620             'external_object_cache'     => wp_using_ext_object_cache(),
    621             'server_info'               => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : '',
    622             'php_version'               => phpversion(),
    623             'php_post_max_size'         => spel_readable_number( ini_get( 'post_max_size' ) ),
    624             'php_max_execution_time'    => ini_get( 'max_execution_time' ),
    625             'php_max_input_vars'        => ini_get( 'max_input_vars' ),
    626             'curl_version'              => $curl_version,
    627             'suhosin_installed'         => extension_loaded( 'suhosin' ),
    628             'max_upload_size'           => wp_max_upload_size(),
    629             'default_timezone'          => date_default_timezone_get(),
    630             'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ),
    631             'soapclient_enabled'        => class_exists( 'SoapClient' ),
    632             'domdocument_enabled'       => class_exists( 'DOMDocument' ),
    633             'gzip_enabled'              => is_callable( 'gzopen' ),
    634             'mbstring_enabled'          => extension_loaded( 'mbstring' ),
    635         );
    636 
    637     }
     626    function spel_get_environment_info(): array {
     627
     628        // Figure out cURL version, if installed.
     629        $curl_version = '';
     630        if ( function_exists( 'curl_version' ) ) {
     631            $curl_version = curl_version();
     632            $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
     633        }
     634
     635        // WP memory limit.
     636        $wp_memory_limit = spel_readable_number( WP_MEMORY_LIMIT );
     637        if ( function_exists( 'memory_get_usage' ) ) {
     638            $wp_memory_limit = max( $wp_memory_limit, spel_readable_number( @ini_get( 'memory_limit' ) ) );
     639        }
     640
     641        return [
     642            'home_url'                  => get_option( 'home' ),
     643            'site_url'                  => get_option( 'siteurl' ),
     644            'version'                   => SPEL_VERSION,
     645            'wp_version'                => get_bloginfo( 'version' ),
     646            'wp_multisite'              => is_multisite(),
     647            'wp_memory_limit'           => $wp_memory_limit,
     648            'wp_debug_mode'             => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
     649            'wp_cron'                   => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
     650            'language'                  => get_locale(),
     651            'external_object_cache'     => wp_using_ext_object_cache(),
     652            'server_info'               => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : '',
     653            'php_version'               => phpversion(),
     654            'php_post_max_size'         => spel_readable_number( ini_get( 'post_max_size' ) ),
     655            'php_max_execution_time'    => ini_get( 'max_execution_time' ),
     656            'php_max_input_vars'        => ini_get( 'max_input_vars' ),
     657            'curl_version'              => $curl_version,
     658            'suhosin_installed'         => extension_loaded( 'suhosin' ),
     659            'max_upload_size'           => wp_max_upload_size(),
     660            'default_timezone'          => date_default_timezone_get(),
     661            'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ),
     662            'soapclient_enabled'        => class_exists( 'SoapClient' ),
     663            'domdocument_enabled'       => class_exists( 'DOMDocument' ),
     664            'gzip_enabled'              => is_callable( 'gzopen' ),
     665            'mbstring_enabled'          => extension_loaded( 'mbstring' ),
     666        ];
     667
     668    }
    638669}
    639670
     
    646677 */
    647678if ( ! function_exists( 'spel_readable_number' ) ) {
    648     function spel_readable_number($size): int
    649     {
    650 
    651         // Get the last character of the size string
    652         $suffix = substr($size, -1);
    653 
    654         // Remove the last character from the size string
    655         $value = substr($size, 0, -1);
    656 
    657         // Convert suffix to lowercase for case-insensitive comparison
    658         $suffix = strtolower($suffix);
    659 
    660         $multipliers = [
    661             'p' => 1024,
    662             't' => 1024,
    663             'g' => 1024,
    664             'm' => 1024,
    665             'k' => 1024,
    666         ];
    667 
    668         // Check if the suffix is a valid multiplier
    669         if (array_key_exists($suffix, $multipliers)) {
    670             $value *= $multipliers[$suffix];
    671         }
    672 
    673         // Return the result
    674         return (int)$value;
    675 
    676     }
    677 }
    678 
    679 
    680 if ( !function_exists('spel_pagination') ) {
    681     function spel_pagination($query, $class = 'spel-pagination', $prev = '', $next = ''): void
    682     {
    683 
    684         if ( $query->max_num_pages <= 1 ) {
    685             return; // No pagination needed if only one page
    686         }
    687 
    688         $default_prev = '<img src="' . esc_url(SPEL_IMG . '/icons/prev.svg') . '" alt="' . esc_attr__('arrow-left',  'spider-elements') . '" class="me-2" />' . esc_html__('Prev',  'spider-elements');
    689         $default_next = esc_html__('Next',  'spider-elements') . '<img src="' . esc_url(SPEL_IMG . '/icons/next.svg') . '" alt="' . esc_attr__('arrow-right',  'spider-elements') . '" class="ms-2" />';
    690 
    691         $prev_text = !empty($prev) ? $prev : $default_prev;
    692         $next_text = !empty($next) ? $next : $default_next;
    693 
    694         echo '<ul class="' . esc_attr($class) . '">';
    695 
    696             $big = 999999999; // need an unlikely integer
    697             $current = max(1, get_query_var('paged') ? get_query_var('paged') : (get_query_var('page') ? get_query_var('page') : 1));
    698 
    699             echo wp_kses_post(
    700                 paginate_links( array(
    701                     'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    702                     'format'    => '?paged=%#%',
    703                     'current'   => $current,
    704                     'total'     => $query->max_num_pages,
    705                     'prev_text' => $prev_text,
    706                     'next_text' => $next_text
    707                 ) )
    708             );
    709 
    710 
    711         echo '</ul>';
    712     }
    713 }
    714 
    715 /**
    716  * Jobus pagination
    717  */
    718 if ( !function_exists('spel_archive_query') ) {
    719     function spel_archive_query($query): void
    720     {
    721         if ( $query->is_main_query() && !is_admin() && !is_home() ) {
    722             $query->set('posts_per_page', -1);
    723         }
    724     }
    725     add_action('pre_get_posts', 'spel_archive_query');
    726 }
     679    function spel_readable_number( $size ): int {
     680
     681        // Get the last character of the size string
     682        $suffix = substr( $size, -1 );
     683
     684        // Remove the last character from the size string
     685        $value = substr( $size, 0, -1 );
     686
     687        // Convert suffix to lowercase for case-insensitive comparison
     688        $suffix = strtolower( $suffix );
     689
     690        $multipliers = [
     691            'p' => 1024,
     692            't' => 1024,
     693            'g' => 1024,
     694            'm' => 1024,
     695            'k' => 1024,
     696        ];
     697
     698        // Check if the suffix is a valid multiplier
     699        if ( array_key_exists( $suffix, $multipliers ) ) {
     700            $value *= $multipliers[ $suffix ];
     701        }
     702
     703        // Return the result
     704        return (int) $value;
     705
     706    }
     707}
     708
     709
     710if ( ! function_exists( 'spel_pagination' ) ) {
     711    /**
     712     * Pagination
     713     *
     714     * @param WP_Query $query
     715     * @param string   $class
     716     * @param string   $prev
     717     * @param string   $next
     718     * @return void
     719     */
     720    function spel_pagination( $query, $class = 'spel-pagination', $prev = '', $next = '' ): void {
     721
     722        if ( $query->max_num_pages <= 1 ) {
     723            return; // No pagination needed if only one page
     724        }
     725
     726        $default_prev = '<img src="' . esc_url( SPEL_IMG . '/icons/prev.svg' ) . '" alt="' . esc_attr__( 'arrow-left', 'spider-elements' ) . '" class="me-2" />' . esc_html__( 'Prev', 'spider-elements' );
     727        $default_next = esc_html__( 'Next', 'spider-elements' ) . '<img src="' . esc_url( SPEL_IMG . '/icons/next.svg' ) . '" alt="' . esc_attr__( 'arrow-right', 'spider-elements' ) . '" class="ms-2" />';
     728
     729        $prev_text = ! empty( $prev ) ? $prev : $default_prev;
     730        $next_text = ! empty( $next ) ? $next : $default_next;
     731
     732        echo '<ul class="' . esc_attr( $class ) . '">';
     733
     734        $big     = 999999999; // need an unlikely integer
     735        $current = max( 1, get_query_var( 'paged' ) ? get_query_var( 'paged' ) : ( get_query_var( 'page' ) ? get_query_var( 'page' ) : 1 ) );
     736
     737        echo wp_kses_post(
     738            paginate_links( [
     739                'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
     740                'format'    => '?paged=%#%',
     741                'current'   => $current,
     742                'total'     => $query->max_num_pages,
     743                'prev_text' => $prev_text,
     744                'next_text' => $next_text,
     745            ] )
     746        );
     747
     748
     749        echo '</ul>';
     750    }
     751}
     752
     753/**
     754 * Jobus pagination (Deprecated)
     755 *
     756 * @param WP_Query $query
     757 * @return void
     758 * @since 1.0.0
     759 * @deprecated 1.8.0 No longer needed as we rely on native query handling.
     760 */
     761if ( ! function_exists( 'spel_archive_query' ) ) {
     762    /**
     763     * Archive Query
     764     *
     765     * @param WP_Query $query
     766     * @return void
     767     */
     768    function spel_archive_query( $query ): void {
     769        // Optimization: Removed unbounded query override to prevent performance issues on archive pages
     770    }
     771
     772    add_action( 'pre_get_posts', 'spel_archive_query' );
     773}
  • spider-elements/trunk/readme.txt

    r3437647 r3464401  
    3434- [📚 Full Documentation](https://helpdesk.spider-themes.net/docs/spider-elements)
    3535- [🎥 Live Demo & Widget Showcase](https://spider-elements.spider-themes.net/#widgets)
     36- [🌐 Visit Spider Themes](https://spider-themes.net)
    3637- [⭐ Upgrade to Pro](https://spider-elements.spider-themes.net/pricing)
    37 - [🌐 Visit Spider Themes](https://spider-themes.net)
    3838
    3939**Essential Tools for Web Designers & Developers**
     
    4343## Core Widgets Available (Free Version)
    4444
    45 **Content & Layout Widgets**
     45***Content & Layout Widgets:***
     46
    4647- [**Accordion**](https://spider-elements.spider-themes.net/accordion) – Organize and manage content with smooth collapsible sections, perfect for FAQs, guides, and comprehensive resource documentation. Enhance user experience with elegant accordion functionality.
    4748- [**Blog Grid**](https://spider-elements.spider-themes.net/blog-grid) – Display your WordPress posts beautifully with multiple customizable layouts, built-in pagination, and responsive design. Perfect for showcasing blog content across all devices.
     
    5051- [**Icon Box**](https://spider-elements.spider-themes.net/icon-box) – Highlight key features and services with eye-catching custom icons and compelling text. Great for showcasing features, benefits, and value propositions elegantly.
    5152
    52 **Visual & Media Widgets**
     53***Visual & Media Widgets:***
     54
    5355- [**Video Popup**](https://spider-elements.spider-themes.net/video-popup) – Embed videos in sleek, professional pop-up windows without page reload. Enhance user engagement with smooth video experiences and modal presentation.
    5456- [**Team Carousel**](https://spider-elements.spider-themes.net/team-carousel) – Showcase team members in dynamic, interactive carousels with smooth transitions. Perfect for displaying staff, employees, and team introductions professionally.
     
    5961## Premium Widgets (Pro Version)
    6062
    61 **Interactive & Animation Widgets**
     63***Interactive & Animation Widgets:***
     64
    6265- [**Box Hover**](https://spider-elements.spider-themes.net/box-hover) – Add stylish hover effects with smooth animations and transitions. Enhance user engagement and interactivity with professional animation effects.
    6366- [**Flip Box**](https://spider-elements.spider-themes.net/flipbox) – Create dynamic flip effects that reveal hidden content on interaction. Perfect for showcasing before-after, features, or additional information creatively.
     
    6669- [**Hotspot**](https://spider-elements.spider-themes.net/hotspot) – Add interactive points on images to highlight details and provide information. Great for product demos, educational content, and interactive presentations.
    6770
    68 **Advanced Content Widgets**
     71***Advanced Content Widgets:***
     72
    6973- [**Image Slider**](https://spider-elements.spider-themes.net/image-slider) – Create beautiful, responsive image slideshows with smooth transitions. Perfect for galleries, portfolios, and showcasing multiple images effectively.
    7074- [**Video Playlist**](https://spider-elements.spider-themes.net/video-playlist) – Organize and play multiple videos in an interactive playlist. Ideal for tutorials, video content libraries, and multimedia presentations.
     
    7983### Quick Features Overview
    8084
    81 **User-Friendly Design**
     85***User-Friendly Design:***
     86
    8287- Intuitive controls and settings
    8388- Real-time preview while editing
    8489- Drag-and-drop simplicity
    8590
    86 **Performance Optimized**
     91***Performance Optimized:***
     92
    8793- Fast loading times
    8894- Lightweight code
    8995- Optimized for all devices
    9096
    91 **Developer Friendly**
     97***Developer Friendly:***
     98
    9299- Clean, well-documented code
    93100- Easy customization hooks
     
    1001074. Drag widgets onto your page
    1011085. Customize with live preview
    102 
    103 **Need Help?**
    104 - [📚 Full Documentation](https://helpdesk.spider-themes.net/docs/spider-elements)
    105 - [🎥 Video Tutorials](https://spider-elements.spider-themes.net/#widgets)
    106 - [🚀 Live Demo](https://spider-elements.spider-themes.net/#widgets)
    107 - [⭐ Upgrade to Pro](https://spider-elements.spider-themes.net/pricing)
    108109
    109110## WHAT’S NEXT?
     
    218219== Changelog ==
    219220
    220 = 1.8.0 (11 January 2026) =
    221 New: Revamped Dashboard UI with modern design system and quick stats
    222 New: Added Search functionality for Widgets and Features with real-time filtering
    223 New: Added Toast notification system for better user feedback on save
    224 New: Added keyboard shortcuts (Ctrl+S to save, Ctrl+F to search)
    225 Improved: System Requirements section with zebra striping and better visibility
    226 Improved: Sidebar navigation active states and hover effects
    227 Tweaked: Refined typography, spacing, and micro-interactions across the dashboard
     221= 1.8.0 (18 February 2026) =
     222*   New: Revamped Dashboard UI with modern design system and quick stats
     223*   New: Added Search functionality for Widgets and Features with real-time filtering
     224*   New: Added Toast notification system for better user feedback on save
     225*   New: Added keyboard shortcuts (Ctrl+S to save, Ctrl+F to search)
     226*   New: Added Antimanual and Jobus plugins to the recommended plugins list in the dashboard.
     227*   Improved: System Requirements section with zebra striping and better visibility
     228*   Improved: Sidebar navigation active states and hover effects
     229*   Improved: Refined typography, spacing, and micro-interactions across the dashboard
     230*   Improved: Dashboard page redesigned with enhanced UI and overall user experience.
     231*   Improved: Dashboard now remembers and keeps the last opened tab active for smoother navigation.
     232*   Improved: Admin classes now load conditionally to reduce unnecessary frontend overhead.
     233*   Improved: Plugin installer optimized to avoid heavy filesystem scans and reduce load time.
     234*   Improved: Removed unconditional Plugin_Installer loading on the frontend for better performance.
     235*   Improved: Archive queries optimized by removing unbounded posts_per_page overrides.
     236*   Improved: Extensive backend performance optimizations applied across core plugin components for faster execution and lower resource usage.
     237*   Fixed: XSS vulnerability in the image helper function by properly sanitizing attribute inputs.
     238*   Fixed: Logic issues resolved and internal documentation improved with WPCS coding standards compliance.
    228239
    229240= 1.7.0 (11 December 2025) =
    230 New: Added submenu items for improved dashboard navigation
    231 Fixed: Tab switcher functionality issue in the Spider Elements dashboard
    232 Tweaked: Minor UI enhancements and general performance improvements across the dashboard
    233 Improved: Enhanced RTL dashboard layout for better usability
    234 Security: Implemented LFI (Local File Inclusion) protection to prevent unauthorized file access
    235 Updated: Freemius SDK updated to 2.13.0
     241*   New: Added submenu items for improved dashboard navigation
     242*   Fixed: Tab switcher functionality issue in the Spider Elements dashboard
     243*   Tweaked: Minor UI enhancements and general performance improvements across the dashboard
     244*   Improved: Enhanced RTL dashboard layout for better usability
     245*   Security: Implemented LFI (Local File Inclusion) protection to prevent unauthorized file access
     246*   Updated: Freemius SDK updated to 2.13.0
    236247
    237248= 1.6.7 (11 November 2025) =
    238 Fixed: Blog title function issue resolved to ensure proper display
    239 Fixed: Nonce field name mismatch corrected in filters.php for secure form handling
    240 Fixed: Missing Elementor Utils class import causing fatal error in Video Playlist widget rendering
    241 Fixed: Video Playlist widget showing raw paragraph tags in description by replacing esc_html with wp_kses_post
    242 Tweaked: Adjusted alert margins in CSS for improved visual spacing
    243 Secured: Added nonce verification for form submissions to strengthen security
    244 Secured: Added proper sanitization in nonce verification for safer data validation
    245 Updated: Dashboard templates modified to maintain consistent field naming conventions
     249*   Fixed: Blog title function issue resolved to ensure proper display
     250*   Fixed: Nonce field name mismatch corrected in filters.php for secure form handling
     251*   Fixed: Missing Elementor Utils class import causing fatal error in Video Playlist widget rendering
     252*   Fixed: Video Playlist widget showing raw paragraph tags in description by replacing esc_html with wp_kses_post
     253*   Tweaked: Adjusted alert margins in CSS for improved visual spacing
     254*   Secured: Added nonce verification for form submissions to strengthen security
     255*   Secured: Added proper sanitization in nonce verification for safer data validation
     256*   Updated: Dashboard templates modified to maintain consistent field naming conventions
    246257
    247258= 1.6.6 (1 October 2025) =
    248 Fixed: Vulnerability issues
    249 Tweaked: Spider Elements widget prefix (SE) has been removed
    250 Updated: Freemius SDK updated to 2.12.2
     259*   Fixed: Vulnerability issues
     260*   Tweaked: Spider Elements widget prefix (SE) has been removed
     261*   Updated: Freemius SDK updated to 2.12.2
    251262
    252263= 1.6.5 (23 Jun 2025) =
    253 New: Added pagination and show/hide options to presets 1, 2, 3, and 4 of the Blog Grid widget
    254 Fixed: Free and Pro Widget and features checked issue on Dashboard
    255 Fixed: Testimonials ratting issue layout 3,4 and 6
    256 Fixed: Tabs widget dark mood issue
    257 Tweaked: Blog carousel nav arrow
    258 Tweaked: ID added in the sticky tabs
    259 Tweaked: SE prefix added before Widgets name
    260 
    261 = 1.6.4 (15 May 2025) =
    262 Fixed: Resolved Pagination issue of Blog grid widget
    263 Tweaked: Compatibility with docy dark mode
    264 Updated: Freemius SDK updated to 2.12.0
     264*   New: Added pagination and show/hide options to presets 1, 2, 3, and 4 of the Blog Grid widget
     265*   Fixed: Free and Pro Widget and features checked issue on Dashboard
     266*   Fixed: Testimonials ratting issue layout 3,4 and 6
     267*   Fixed: Tabs widget dark mood issue
     268*   Tweaked: Blog carousel nav arrow
     269*   Tweaked: ID added in the sticky tabs
     270*   Tweaked: SE prefix added before Widgets name
     271
     272[See changelog for all versions](https://spider-elements.spider-themes.net/changelog/)
  • spider-elements/trunk/spider-elements.php

    r3416399 r3464401  
    55 * Plugin URI: https://spider-elements.spider-themes.net
    66 * Description: Spider Elements is a hassle-free addon bundle with super useful widgets for building beautiful websites. Plug and play to create stunning designs effortlessly.
    7  * Version: 1.7.0
     7 * Version: 1.8.0
    88 * Requires at least: 5.0
    9  * Tested up to: 6.8
     9 * Tested up to: 6.9
    1010 * Requires PHP: 7.4
    1111 * Author: spider-themes
     
    102102         * @var string The plugin version.
    103103         */
    104         const VERSION = '1.7.0';
     104        const VERSION = '1.8.0';
    105105
    106106
     
    153153
    154154            // Init Plugin
    155             add_action( 'plugins_loaded', array( $this, 'init_plugin' ) );
     155            add_action( 'plugins_loaded', [ $this, 'init_plugin' ] );
    156156
    157157            // Load text domain for localization
     
    253253            require_once __DIR__ . '/includes/filters.php';
    254254
    255             require_once __DIR__ . '/includes/Admin/Module_Settings.php';
    256 
    257             // Admin and Frontend Scripts Loaded
    258             require_once __DIR__ . '/includes/Admin/Plugin_Installer.php';
    259 
    260255            $theme = wp_get_theme();
    261256            if ( spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] ) ) {
     
    266261            // Admin UI
    267262            if ( is_admin() ) {
     263                require_once __DIR__ . '/includes/Admin/Module_Settings.php';
     264
     265                // Admin Scripts Loaded
     266                require_once __DIR__ . '/includes/Admin/Plugin_Installer.php';
     267
    268268                require_once __DIR__ . '/includes/Admin/Assets.php';
    269269                require_once __DIR__ . '/includes/Admin/Dashboard.php';
     
    313313
    314314            // Frontend UI
    315             new SPEL\includes\Admin\Plugin_Installer();
    316315            new SPEL\includes\Frontend\Assets();
    317316        }
     
    378377
    379378        /**
     379         * Define Constants
     380         *
     381         * Define plugin constants.
     382         *
    380383         * @return void
    381          * @since  1.7.0
    382          * @access public
    383          * @static
    384384         */
    385385        public function define_constants(): void {
  • spider-elements/trunk/widgets/templates/video-playlist/video-playlist-1.php

    r3393425 r3464401  
    33    exit; // Exit if accessed directly.
    44}
     5$widget_id = $this->get_id();
    56?>
    67
     
    1011        <div class="ezd-lg-col-7">
    1112            <div class="video_player">
    12                 <div class="tab-content video_tabs" id="<?php esc_attr( get_the_ID() ); ?>">
     13                <div class="tab-content video_tabs" id="<?php echo esc_attr( get_the_ID() . '-' . $widget_id ); ?>">
    1314                    <?php
    1415                    $all_videos = $settings['tabs'] ?? '';
     
    2021                            ?>
    2122                            <div class="tab-pane ezd-tab-box pt-0 <?php echo esc_attr( $active ); ?>"
    22                                  id="video_<?php echo esc_attr( $i ++ ); ?>">
     23                                 id="video_<?php echo esc_attr( $widget_id . '_' . $i ++ ); ?>">
    2324                                <div class="artplayer-app"
    2425                                     data-src="<?php echo esc_url( $child_video['video_upload']['url'] ); ?>">
     
    6566                            ?>
    6667                            <div class="card accordion-panel spe_accordion_inner">
    67                                 <div class="card spe-accordion" id="configuration<?php echo esc_attr( $count ); ?>-tab">
     68                                <div class="card spe-accordion" id="configuration<?php echo esc_attr( $widget_id . '_' . $count ); ?>-tab">
    6869                                    <div class="card-header">
    6970                                        <button class="text-left accordion-header <?php echo esc_attr( $nav_collapse ); ?>">
     
    8990                                    </div>
    9091                                </div>
    91                                 <div id="configuration<?php echo esc_attr( $count ); ?>" class="accordion-content collapse">
     92                                <div id="configuration<?php echo esc_attr( $widget_id . '_' . $count ); ?>" class="accordion-content collapse">
    9293                                    <div class="card-body">
    9394                                        <ul class="nav nav-tabs ezd-tab-menu">
     
    99100                                                    <li class="nav-item">
    100101                                                        <a class="nav-link<?php esc_attr( $is_active ); ?>"
    101                                                            href="#video_<?php echo esc_attr( $i ++ ); ?>">
     102                                                           href="#video_<?php echo esc_attr( $widget_id . '_' . $i ++ ); ?>">
    102103                                                            <div class="media ezd-d-flex">
    103104                                                                <?php if ( ! empty( $child_video['thumbnail']['url'] ) ) : ?>
     
    200201
    201202    document.addEventListener('DOMContentLoaded', function() {
    202       let video = $('#video_0');
     203      let video = $('#video_<?php echo esc_attr( $widget_id ); ?>_0');
    203204      setTimeout(function() {
    204205        $('.video_slider_area').addClass('loaded').css('height', 'auto');
Note: See TracChangeset for help on using the changeset viewer.