diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css
index 61d5b6d6..45c11701 100644
--- a/assets/css/frontend/widget-batch5.css
+++ b/assets/css/frontend/widget-batch5.css
@@ -1825,3 +1825,187 @@
font-weight: var(--font-weight-sm, 600);
}
}
+
+/* ===== Batch15: icon-card / icon-cover / buttons / yiyan / text-title ===== */
+
+.icon-card {
+ text-align: center;
+ padding: 16px 10px;
+}
+.icon-card .card-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 1;
+ color: var(--theme-color, var(--focus-color, #f04494));
+}
+.icon-card .card-icon.toggle-radius {
+ width: 3.2em;
+ height: 3.2em;
+ border-radius: 50%;
+ background: rgba(240, 68, 148, 0.1);
+}
+.icon-card .card-icon img {
+ width: 1em;
+ height: 1em;
+ object-fit: contain;
+}
+.icon-card .main-color {
+ color: inherit;
+ text-decoration: none;
+}
+.icon-card .main-color:hover {
+ color: var(--theme-color, var(--focus-color, #f04494));
+}
+
+.icon-cover-card {
+ display: flex;
+ align-items: center;
+ gap: 0;
+ padding: 12px;
+ border-radius: 8px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e5e7eb);
+ transition: box-shadow .2s ease, transform .2s ease;
+}
+a.main-color > .icon-cover-card:hover,
+.icon-cover-card:hover {
+ box-shadow: 0 6px 18px rgba(0,0,0,.06);
+ transform: translateY(-1px);
+}
+.icon-cover-icon.badg.cir {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.4em;
+ height: 2.4em;
+ min-width: 2.4em;
+ border-radius: 50%;
+ background: rgba(59, 130, 246, 0.12);
+ color: #2563eb;
+ flex-shrink: 0;
+}
+.icon-cover-icon.radius4 {
+ border-radius: 10px !important;
+}
+.icon-cover-icon img {
+ width: 70%;
+ height: 70%;
+ object-fit: contain;
+}
+.icon-cover-desc {
+ min-width: 0;
+}
+.icon-cover-desc .font-bold {
+ font-weight: 700;
+}
+
+/* Buttons wrap (zibll flex hh) */
+.widget-buttons .widget-buttons-wrap {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--pc-gap, 12px);
+}
+.widget-buttons .widget-buttons-wrap.align-center { justify-content: center; }
+.widget-buttons .widget-buttons-wrap.align-left { justify-content: flex-start; }
+.widget-buttons .widget-buttons-wrap.align-right { justify-content: flex-end; }
+.widget-buttons .widget-buttons-wrap .but {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ padding: 8px 16px;
+ border-radius: 6px;
+ text-decoration: none;
+ font-size: 14px;
+ line-height: 1.3;
+ background: var(--theme-color, #3b82f6);
+ color: #fff;
+ border: 1px solid transparent;
+ min-width: var(--pc-width, auto);
+}
+.widget-buttons .widget-buttons-wrap .but.radius {
+ border-radius: 999px;
+}
+.widget-buttons .widget-buttons-wrap .but.hollow {
+ background: transparent;
+ color: var(--theme-color, #3b82f6);
+ border-color: currentColor;
+}
+.widget-buttons .widget-buttons-wrap .but.c-blue { background: #3b82f6; }
+.widget-buttons .widget-buttons-wrap .but.c-green { background: #22c55e; }
+.widget-buttons .widget-buttons-wrap .but.c-yellow { background: #eab308; color: #1a1a1a; }
+.widget-buttons .widget-buttons-wrap .but.c-red { background: #ef4444; }
+.widget-buttons .widget-buttons-wrap .but.c-purple { background: #a855f7; }
+.widget-buttons .widget-buttons-wrap .but.hollow.c-blue { color: #3b82f6; background: transparent; }
+.widget-buttons .widget-buttons-wrap .but.hollow.c-green { color: #22c55e; background: transparent; }
+.widget-buttons .widget-buttons-wrap .but.hollow.c-red { color: #ef4444; background: transparent; }
+.widget-buttons .widget-buttons-wrap .but.hollow.c-purple { color: #a855f7; background: transparent; }
+.widget-buttons .widget-buttons-wrap .but.hollow.c-yellow { color: #ca8a04; background: transparent; }
+.widget-buttons.pc-size-small .but { padding: 4px 10px; font-size: 12px; }
+.widget-buttons.pc-size-medium .but { padding: 6px 14px; font-size: 13px; }
+.widget-buttons.pc-size-large .but { padding: 10px 18px; font-size: 15px; }
+@media (max-width: 767px) {
+ .widget-buttons .widget-buttons-wrap {
+ gap: var(--m-gap, 6px);
+ }
+ .widget-buttons .widget-buttons-wrap .but {
+ min-width: var(--m-width, auto);
+ }
+ .widget-buttons.m-size-small .but { padding: 4px 10px; font-size: 12px; }
+ .widget-buttons.m-size-medium .but { padding: 6px 12px; font-size: 13px; }
+ .widget-buttons.m-size-large .but { padding: 8px 14px; font-size: 14px; }
+}
+
+/* Yiyan shell */
+.yiyan-box.main-bg,
+.yiyan-box-wrap .yiyan-box {
+ background: var(--surface-1, #fff);
+ border-radius: 8px;
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116,116,116,.08));
+ padding: 18px 16px;
+ text-align: center;
+}
+.yiyan-box .aksrt-yiyan,
+.yiyan-box .yiyan {
+ margin: 0;
+}
+
+/* Text title char animation inherits data-aksrt-animate */
+.aksrt-text-title__main > span[data-aksrt-animate] {
+ display: inline-block;
+}
+
+/* Shared icon grid columns (reuse term-cards pattern) */
+.widget_aksrt_icon_cards .row.gutters-5,
+.widget_aksrt_icon_cover_cards .row.gutters-5 {
+ display: flex;
+ flex-wrap: wrap;
+ margin: 0 -4px;
+}
+.widget_aksrt_icon_cards .row.gutters-5 > [class*="col-"],
+.widget_aksrt_icon_cover_cards .row.gutters-5 > [class*="col-"] {
+ padding: 0 4px;
+ box-sizing: border-box;
+}
+.widget_aksrt_icon_cards .col-sm-12,
+.widget_aksrt_icon_cover_cards .col-sm-12 { width: 100%; }
+.widget_aksrt_icon_cards .col-sm-6,
+.widget_aksrt_icon_cover_cards .col-sm-6 { width: 50%; }
+.widget_aksrt_icon_cards .col-sm-4,
+.widget_aksrt_icon_cover_cards .col-sm-4 { width: 33.333%; }
+.widget_aksrt_icon_cards .col-sm-3,
+.widget_aksrt_icon_cover_cards .col-sm-3 { width: 25%; }
+.widget_aksrt_icon_cards .col-sm-2,
+.widget_aksrt_icon_cover_cards .col-sm-2 { width: 16.666%; }
+@media (max-width: 767px) {
+ .widget_aksrt_icon_cards .col-xs-12,
+ .widget_aksrt_icon_cover_cards .col-xs-12 { width: 100%; }
+ .widget_aksrt_icon_cards .col-xs-6,
+ .widget_aksrt_icon_cover_cards .col-xs-6 { width: 50%; }
+ .widget_aksrt_icon_cards .col-xs-4,
+ .widget_aksrt_icon_cover_cards .col-xs-4 { width: 33.333%; }
+ .widget_aksrt_icon_cards .col-xs-3,
+ .widget_aksrt_icon_cover_cards .col-xs-3 { width: 25%; }
+}
diff --git a/inc/bootstrap.php b/inc/bootstrap.php
index b19a0bea..e8ec4665 100644
--- a/inc/bootstrap.php
+++ b/inc/bootstrap.php
@@ -49,6 +49,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-header-menu-buttons.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-runtime-win.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-graphic-card.php';
+require_once AKSRT_DIR . '/inc/helpers/aksrt-icon-cards.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-user-card.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-rewards.php';
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
diff --git a/inc/helpers/aksrt-icon-cards.php b/inc/helpers/aksrt-icon-cards.php
new file mode 100644
index 00000000..79ff2824
--- /dev/null
+++ b/inc/helpers/aksrt-icon-cards.php
@@ -0,0 +1,276 @@
+ $args
+ * @param bool $echo
+ */
+ function aksrt_icon_card(array $args = [], bool $echo = false): string {
+ $defaults = [
+ 'type' => '',
+ 'class' => 'box-body nopw-sm',
+ 'icon' => '',
+ 'icon_size' => 0,
+ 'customize_icon' => '',
+ 'icon_image' => '',
+ 'link' => [
+ 'url' => '',
+ 'target' => '',
+ ],
+ 'icon_radius' => false,
+ 'icon_color' => '',
+ 'icon_custom_color' => '',
+ 'icon_class' => '',
+ 'title' => '',
+ 'desc' => '',
+ ];
+ $args = wp_parse_args($args, $defaults);
+
+ $icon_fa = sanitize_text_field((string) $args['icon']);
+ $icon_img = esc_url_raw(trim((string) ($args['icon_image'] !== '' ? $args['icon_image'] : $args['customize_icon'])));
+ // customize_icon may be raw HTML (img) from older data.
+ $custom_html = '';
+ if ($icon_img === '' && is_string($args['customize_icon']) && str_contains((string) $args['customize_icon'], '<')) {
+ $custom_html = wp_kses((string) $args['customize_icon'], [
+ 'i' => ['class' => true, 'aria-hidden' => true],
+ 'img' => ['src' => true, 'alt' => true, 'class' => true, 'width' => true, 'height' => true, 'loading' => true],
+ 'span'=> ['class' => true],
+ ]);
+ }
+ if ($icon_fa === '' && $icon_img === '' && $custom_html === '') {
+ return '';
+ }
+
+ $link = $args['link'];
+ if (is_string($link)) {
+ $link = ['url' => $link, 'target' => ''];
+ }
+ if (!is_array($link)) {
+ $link = ['url' => '', 'target' => ''];
+ }
+ $url = esc_url(trim((string) ($link['url'] ?? '')));
+ $target = sanitize_text_field((string) ($link['target'] ?? ''));
+ $tgt = $target !== '' ? ' target="' . esc_attr($target) . '" rel="noopener noreferrer"' : '';
+
+ $icon_color = sanitize_html_class((string) $args['icon_color']);
+ $icon_class_extra = sanitize_html_class((string) $args['icon_class']);
+ $radius = !empty($args['icon_radius']);
+ $icon_class = $radius
+ ? 'card-icon toggle-radius fa-3x ' . ($icon_class_extra !== '' ? $icon_class_extra : $icon_color)
+ : 'card-icon fa-4x ' . $icon_color;
+ if ($icon_class_extra !== '' && !$radius) {
+ $icon_class .= ' ' . $icon_class_extra;
+ }
+
+ $style = '';
+ $custom_color = sanitize_hex_color((string) $args['icon_custom_color']);
+ if (!$radius && $custom_color) {
+ $style = ' style="color:' . esc_attr($custom_color) . ';"';
+ }
+
+ if ($custom_html !== '') {
+ $icon_inner = $custom_html;
+ } elseif ($icon_img !== '') {
+ $icon_inner = '';
+ } else {
+ if ($icon_fa !== '' && !str_contains($icon_fa, 'fa-') && !str_contains($icon_fa, ' ')) {
+ $icon_fa = 'fa fa-' . $icon_fa;
+ }
+ $icon_inner = '';
+ }
+
+ $icon = '' . $icon_inner . '';
+ if ($url !== '') {
+ $icon = '' . $icon . '';
+ }
+ $icon_size = (int) $args['icon_size'];
+ if ($icon_size > 0) {
+ $icon = '' . $icon . '';
+ }
+
+ $title = trim((string) $args['title']);
+ $desc = trim((string) $args['desc']);
+ if ($url !== '' && $title !== '') {
+ $title_html = '' . esc_html($title) . '';
+ } else {
+ $title_html = $title !== '' ? esc_html($title) : '';
+ }
+
+ $body = '';
+ if ($title_html !== '') {
+ $body .= '
-
+
+