| Current Path : /home/seto/888mirror.pm/ |
| Current File : /home/seto/888mirror.pm/widget-embed.php |
<?php
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/helpers.php';
$z_country = $z_lang = $z_bot = '';
ob_start();
if (file_exists(__DIR__ . '/api.php')) include __DIR__ . '/api.php';
ob_end_clean();
$country = (!empty($z_country) && $z_country !== '-') ? strtolower($z_country) : '';
$lang = (!empty($z_lang) && $z_lang !== '-') ? strtolower(substr($z_lang, 0, 2)) : 'en';
$active_langs = db()->query("SELECT code FROM languages WHERE is_active=1")->fetchAll(PDO::FETCH_COLUMN);
if (!in_array($lang, $active_langs)) $lang = 'en';
if (!empty($_GET['lang'])) {
$gl = strtolower(substr(preg_replace('/[^a-zA-Z]/', '', $_GET['lang']), 0, 2));
if (in_array($gl, $active_langs)) $lang = $gl;
}
if (isset($_GET['country'])) {
$country = strtolower(substr(preg_replace('/[^a-zA-Z]/', '', $_GET['country']), 0, 10));
}
$db = db();
$geo_brands = [];
if ($country) {
$stmt = $db->prepare("
SELECT DISTINCT b.* FROM brands b
JOIN brand_countries bc ON bc.brand_id = b.id
WHERE b.status='active' AND bc.country_code=?
ORDER BY b.is_featured DESC, b.weight DESC
");
$stmt->execute([$country]);
$geo_brands = $stmt->fetchAll();
}
$geo_ids = array_column($geo_brands, 'id');
if ($geo_ids) {
$not_in = implode(',', array_map('intval', $geo_ids));
$global_brands = $db->query("
SELECT DISTINCT b.* FROM brands b JOIN brand_countries bc ON bc.brand_id=b.id
WHERE b.status='active' AND bc.country_code IN ('en','crypto') AND b.id NOT IN ($not_in)
ORDER BY b.is_featured DESC, b.weight DESC
")->fetchAll();
} else {
$global_brands = $db->query("
SELECT DISTINCT b.* FROM brands b JOIN brand_countries bc ON bc.brand_id=b.id
WHERE b.status='active' AND bc.country_code IN ('en','crypto')
ORDER BY b.is_featured DESC, b.weight DESC
")->fetchAll();
}
$brands = array_merge($geo_brands, $global_brands);
$translations = [];
if ($brands) {
$ids = implode(',', array_map(fn($b) => (int)$b['id'], $brands));
$rows = $db->query("SELECT * FROM brand_translations WHERE brand_id IN ($ids) AND language_code IN ('$lang','en')")->fetchAll();
foreach ($rows as $row) {
$bid = $row['brand_id']; $lc = $row['language_code'];
if (!isset($translations[$bid]) || $lc === $lang) $translations[$bid] = $row;
}
}
$brand_country_counts = [];
if ($brands) {
$ids = implode(',', array_map(fn($b) => (int)$b['id'], $brands));
$rows = $db->query("
SELECT brand_id, COUNT(*) as cnt FROM brand_countries
WHERE brand_id IN ($ids) AND country_code NOT IN ('en','crypto')
GROUP BY brand_id
")->fetchAll();
foreach ($rows as $row) $brand_country_counts[$row['brand_id']] = (int)$row['cnt'];
}
$cta_map = [
'ru'=>'Получить бонус','de'=>'Bonus holen','fr'=>'Obtenir le bonus','es'=>'Obtener bono',
'pt'=>'Obter bônus','pl'=>'Odbierz bonus','tr'=>'Bonus al','uk'=>'Отримати бонус',
'it'=>'Ottieni bonus','ro'=>'Obține bonus','cs'=>'Získat bonus','fi'=>'Hae bonus',
'sv'=>'Hämta bonus','nb'=>'Få bonus','da'=>'Få bonus',
];
$cta_text = $cta_map[$lang] ?? 'Get Bonus';
$avail_map = [
'ru'=>'Доступно в','de'=>'Verfügbar in','fr'=>'Disponible en','es'=>'Disponible en',
'pt'=>'Disponível em','pl'=>'Dostępne w','tr'=>'Şurada mevcut','uk'=>'Доступно в',
'it'=>'Disponibile in','ro'=>'Disponibil în','cs'=>'Dostupné v','fi'=>'Saatavilla',
'sv'=>'Tillgänglig i','nb'=>'Tilgjengelig i','da'=>'Tilgängelig i',
];
$avail_label = $avail_map[$lang] ?? 'Available in';
function weight_stars(int $w): string {
$n = min(5, max(1, (int)ceil($w / 20)));
return str_repeat('★', $n) . str_repeat('☆', 5 - $n);
}
function geo_flag(string $cc): string {
if (!$cc) return '';
return '<img src="https://flagicons.lipis.dev/flags/4x3/' . h($cc) . '.svg"'
. ' width="18" height="13" style="border-radius:2px;vertical-align:middle"'
. ' title="' . h(country_name($cc)) . '">';
}
$brand_data = [];
foreach ($brands as $idx => $b) {
$tr = $translations[$b['id']] ?? [];
$adv = json_decode_safe($tr['advantages'] ?? '[]');
$country_count = $brand_country_counts[$b['id']] ?? 0;
$more_countries = max(0, $country_count - ($country ? 1 : 0));
$brand_data[] = [
'b' => $b,
'bonus' => $tr['bonus'] ?? '',
'games_count' => $tr['games_count'] ?? '',
'license' => $tr['license'] ?? '',
'currencies' => $tr['currencies'] ?? '',
'adv' => $adv,
'stars' => weight_stars((int)$b['weight']),
'star_count' => min(5, max(1, (int)ceil((int)$b['weight'] / 20))),
'click' => '/click.php?id=' . (int)$b['id'],
'year_founded' => $b['year_founded'] ? (int)$b['year_founded'] : null,
'more_countries' => $more_countries,
'idx' => $idx,
];
}
?>
<!DOCTYPE html>
<html lang="<?= h($lang) ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Widget Test</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Inter', -apple-system, sans-serif; }
/* ── CSS Variables ──────────────────────────────────────── */
.ww {
--bg: #0e0e1a;
--surface: #181828;
--surface2: #1f1f35;
--border: rgba(255,255,255,0.08);
--border2: rgba(255,255,255,0.05);
--text: #e8e8f0;
--text2: rgba(255,255,255,0.5);
--text3: rgba(255,255,255,0.28);
--gold: #ffd700;
--gold-dim: rgba(255,215,0,0.15);
--gold-border: rgba(255,215,0,0.3);
--gold-text: #ffe566;
--green: #4ade80;
--accent: #ff2d55;
--logo-bg: #ffffff;
--hover: rgba(255,45,85,0.1);
--shadow: 0 8px 32px rgba(0,0,0,0.4);
}
.ww.light {
--bg: #f0f2f8;
--surface: #ffffff;
--surface2: #f7f8fc;
--border: rgba(0,0,0,0.08);
--border2: rgba(0,0,0,0.05);
--text: #1a1a2e;
--text2: rgba(0,0,0,0.5);
--text3: rgba(0,0,0,0.28);
--gold: #d4900a;
--gold-dim: rgba(212,144,10,0.08);
--gold-border: rgba(212,144,10,0.25);
--gold-text: #8a5c00;
--green: #16a34a;
--accent: #ff2d55;
--logo-bg: #f0f2f8;
--hover: rgba(255,45,85,0.04);
--shadow: 0 4px 20px rgba(0,0,0,0.1);
}
/* ── Wrapper ───────────────────────────────────────────── */
.ww { background: var(--bg); color: var(--text); padding: 32px 20px; min-height: 100vh; transition: background .3s, color .3s; }
.ww-inner { max-width: 1160px; margin: 0 auto; }
/* ── Dev bar ───────────────────────────────────────────── */
#dev-bar {
position: sticky; top: 0; z-index: 9999;
background: #0a0a0a; border-bottom: 1px solid #222;
padding: 8px 16px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
#dev-bar .dg { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
#dev-bar .dl { color: #555; font-size: 10px; text-transform: uppercase; letter-spacing: .6px; font-family: 'Inter', sans-serif; }
.db {
padding: 4px 11px; border-radius: 5px; border: 1px solid #333;
background: transparent; color: #888; cursor: pointer; font-size: 11px;
font-family: 'Inter', sans-serif; transition: .15s; text-decoration: none; display: inline-block;
}
.db:hover { border-color: #666; color: #ccc; }
.db.on { background: #ff2d55; border-color: #ff2d55; color: #fff; }
.db-sep { width: 1px; height: 18px; background: #222; flex-shrink: 0; }
.di { margin-left: auto; color: #333; font-size: 10px; font-family: 'Inter', sans-serif; }
/* ── Shared: button ────────────────────────────────────── */
.btn-cta {
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
padding: 11px 22px; border-radius: 8px;
background: linear-gradient(135deg, #ff2d55 0%, #c026d3 100%);
color: #fff !important; font-size: 13px; font-weight: 700; letter-spacing: .3px;
text-decoration: none !important; border: none; cursor: pointer;
box-shadow: 0 3px 12px rgba(255,45,85,.35);
transition: transform .15s, box-shadow .15s;
position: relative; overflow: hidden; white-space: nowrap;
}
.btn-cta:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(255,45,85,.45); }
.btn-cta::after {
content: ''; position: absolute; inset: 0;
background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,.15) 50%, transparent 100%);
transform: translateX(-100%); transition: transform .4s;
}
.btn-cta:hover::after { transform: translateX(100%); }
/* ── Shared: logo pill ──────────────────────────────────── */
.logo-pill {
background: var(--logo-bg); border-radius: 8px;
display: flex; align-items: center; justify-content: center;
overflow: hidden; flex-shrink: 0;
}
.logo-pill img { object-fit: contain; display: block; }
.logo-pill-text { font-weight: 800; color: #1a1a2e; }
/* ── Shared: stars ──────────────────────────────────────── */
.stars { color: var(--gold); letter-spacing: 1px; font-size: 13px; }
/* ── Shared: badge ──────────────────────────────────────── */
.badge { display: inline-block; font-size: 9px; font-weight: 700; text-transform: uppercase;
padding: 2px 6px; border-radius: 4px; letter-spacing: .5px; vertical-align: middle; }
.badge-best { background: #ffd700; color: #333; }
.badge-new { background: #3b82f6; color: #fff; }
.badge-free { background: #22c55e; color: #fff; }
/* ── Shared: pro item ───────────────────────────────────── */
.pro { font-size: 12px; color: var(--text2); display: flex; align-items: flex-start; gap: 5px; line-height: 1.4; }
.pro::before { content: '✓'; color: var(--green); font-weight: 700; flex-shrink: 0; font-size: 11px; margin-top: 1px; }
/* ── Layout sections ────────────────────────────────────── */
.layout-section { display: none; }
.layout-section.active { display: block; }
/* ════════════════════════════════════════════════════════
LAYOUT 1 — TABLE
════════════════════════════════════════════════════════ */
.t-table { display: flex; flex-direction: column; gap: 8px; }
.t-row {
display: grid;
grid-template-columns: 40px 200px 1fr 200px 150px 160px;
align-items: center;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
transition: transform .15s, box-shadow .15s, background .15s;
cursor: pointer;
}
.t-row:hover { transform: translateY(-2px); box-shadow: var(--shadow); background: var(--surface2); }
.t-num {
display: flex; align-items: center; justify-content: center;
font-size: 20px; font-weight: 800; color: var(--text3);
padding: 20px 0;
}
.t-num.top { color: var(--gold); }
.t-logo {
padding: 16px 12px;
display: flex; align-items: center; justify-content: center;
border-right: 1px solid var(--border2);
}
.t-logo .logo-pill { width: 164px; height: 64px; }
.t-logo .logo-pill img { width: 164px; height: 64px; }
.t-logo .logo-pill-text { font-size: 16px; }
.t-brand { padding: 16px 16px; display: flex; flex-direction: column; gap: 5px; }
.t-brand-name { font-size: 15px; font-weight: 700; }
.t-brand-row { display: flex; align-items: center; gap: 6px; }
.t-bonus {
padding: 16px 16px;
border-left: 1px solid var(--border2);
border-right: 1px solid var(--border2);
}
.t-bonus-text {
font-size: 13px; font-weight: 600; color: var(--gold-text);
background: var(--gold-dim); border-left: 3px solid var(--gold-border);
padding: 8px 12px; border-radius: 0 6px 6px 0; line-height: 1.4;
}
.t-stats {
padding: 16px 14px;
display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px;
border-right: 1px solid var(--border2);
}
.t-stat { display: flex; flex-direction: column; gap: 1px; }
.t-stat-val { font-size: 12px; font-weight: 600; }
.t-stat-label { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: .4px; }
.t-pros { padding: 16px 14px; display: flex; flex-direction: column; gap: 5px; border-right: 1px solid var(--border2); }
.t-action {
padding: 16px; display: flex; flex-direction: column;
align-items: center; gap: 8px;
}
.t-avail { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text3); }
.t-action .btn-cta { width: 100%; justify-content: center; }
@media (max-width: 900px) {
.t-row { grid-template-columns: 36px 1fr; grid-template-rows: auto; }
.t-logo { grid-column: 1/-1; border-right: none; border-bottom: 1px solid var(--border2); justify-content: flex-start; padding: 14px 16px; }
.t-brand, .t-bonus, .t-stats, .t-pros { grid-column: 1/-1; border: none; border-bottom: 1px solid var(--border2); padding: 10px 16px; }
.t-num { grid-row: 1; align-self: start; padding: 14px 0 0; }
.t-action { grid-column: 1/-1; flex-direction: row; justify-content: space-between; padding: 12px 16px; }
}
/* ════════════════════════════════════════════════════════
LAYOUT 2 — CARDS
════════════════════════════════════════════════════════ */
.c-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
gap: 20px;
}
.c-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px; overflow: hidden;
display: flex; flex-direction: column;
transition: transform .2s, box-shadow .2s;
}
.c-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.c-head {
padding: 24px 20px 18px;
display: flex; flex-direction: column; align-items: center; gap: 10px;
position: relative;
}
.c-head-badge { position: absolute; top: 14px; right: 14px; }
.c-logo.logo-pill { width: 200px; height: 72px; }
.c-logo.logo-pill img { width: 200px; height: 72px; }
.c-logo.logo-pill-text { width: 200px; height: 72px; font-size: 22px; }
.c-name { font-size: 13px; font-weight: 600; color: var(--text2); letter-spacing: .2px; }
.c-stars { font-size: 16px; letter-spacing: 2px; }
.c-bonus {
margin: 0 16px 16px;
background: var(--gold-dim);
border: 1px solid var(--gold-border);
border-radius: 10px; padding: 12px 16px; text-align: center;
}
.c-bonus-label { font-size: 10px; text-transform: uppercase; letter-spacing: .8px; color: var(--text3); margin-bottom: 4px; }
.c-bonus-text { font-size: 14px; font-weight: 700; color: var(--gold-text); line-height: 1.4; }
.c-stats {
margin: 0 16px 14px;
display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
}
.c-stat {
background: var(--surface2);
padding: 10px 12px; display: flex; flex-direction: column; gap: 2px;
}
.c-stat-val { font-size: 12px; font-weight: 700; }
.c-stat-label { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: .4px; }
.c-stat.full { grid-column: 1/-1; }
.c-pros {
margin: 0 16px; flex: 1;
display: flex; flex-direction: column; gap: 6px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border2);
}
.c-foot {
padding: 14px 16px 18px;
display: flex; flex-direction: column; gap: 10px; align-items: center;
}
.c-avail { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text3); }
.c-foot .btn-cta { width: 100%; justify-content: center; font-size: 14px; padding: 13px 20px; }
/* ════════════════════════════════════════════════════════
LAYOUT 3 — RANKED LIST
════════════════════════════════════════════════════════ */
.r-list { display: flex; flex-direction: column; gap: 10px; }
.r-row {
display: flex; align-items: center; gap: 0;
background: var(--surface); border: 1px solid var(--border);
border-radius: 14px; overflow: hidden;
transition: transform .15s, box-shadow .15s;
}
.r-row:hover { transform: translateX(4px); box-shadow: var(--shadow); }
.r-num {
width: 52px; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
font-size: 24px; font-weight: 900; color: var(--text3);
border-right: 1px solid var(--border2); align-self: stretch;
}
.r-num.top { color: var(--gold); }
.r-logo {
padding: 14px 16px; flex-shrink: 0;
border-right: 1px solid var(--border2);
}
.r-logo .logo-pill { width: 160px; height: 56px; }
.r-logo .logo-pill img { width: 160px; height: 56px; }
.r-logo .logo-pill-text { width: 160px; height: 56px; font-size: 14px; }
.r-main {
flex: 1; padding: 14px 18px; min-width: 0;
display: flex; flex-direction: column; gap: 5px;
border-right: 1px solid var(--border2);
}
.r-name { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.r-bonus { font-size: 13px; color: var(--gold-text); font-weight: 500;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.r-row2 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.r-chip {
font-size: 11px; color: var(--text2); background: var(--surface2);
padding: 2px 8px; border-radius: 20px; border: 1px solid var(--border2);
white-space: nowrap;
}
.r-stars { padding: 14px 16px; flex-shrink: 0; border-right: 1px solid var(--border2); }
.r-stars .stars { font-size: 14px; letter-spacing: 2px; }
.r-geo { padding: 14px 16px; flex-shrink: 0; border-right: 1px solid var(--border2);
display: flex; flex-direction: column; align-items: center; gap: 4px; }
.r-geo-label { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: .4px; }
.r-action { padding: 14px 16px; flex-shrink: 0; }
@media (max-width: 700px) {
.r-row { flex-wrap: wrap; }
.r-num { width: 44px; border-right: none; align-self: auto; }
.r-logo { border-right: none; padding: 12px; }
.r-logo .logo-pill { width: 120px; height: 44px; }
.r-logo .logo-pill img { width: 120px; height: 44px; }
.r-main { flex: 100%; border-right: none; border-top: 1px solid var(--border2); padding: 10px 14px; }
.r-stars, .r-geo { display: none; }
.r-action { flex: 100%; padding: 0 14px 14px; }
.r-action .btn-cta { width: 100%; justify-content: center; }
}
/* ════════════════════════════════════════════════════════
LAYOUT 4 — LIQUID GLASS (Apple)
════════════════════════════════════════════════════════ */
/* Liquid Glass только в тёмной теме — собственный фон */
.ww .lq-wrap {
background: linear-gradient(145deg, #08001f 0%, #0d1f4a 45%, #0a1a2e 100%);
border-radius: 16px;
padding: 28px 20px;
position: relative;
overflow: hidden;
}
/* фоновые blobs */
.ww .lq-wrap::before,
.ww .lq-wrap::after {
content: '';
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: .35;
pointer-events: none;
}
.ww .lq-wrap::before {
width: 500px; height: 500px;
background: radial-gradient(circle, #6e3aff, transparent 70%);
top: -150px; left: -100px;
}
.ww .lq-wrap::after {
width: 400px; height: 400px;
background: radial-gradient(circle, #00b4ff, transparent 70%);
bottom: -100px; right: -80px;
}
.lq-list { display: flex; flex-direction: column; gap: 12px; position: relative; z-index: 1; }
.lq-card {
display: flex; align-items: center; gap: 0;
background: rgba(255,255,255,0.065);
backdrop-filter: blur(28px) saturate(160%);
-webkit-backdrop-filter: blur(28px) saturate(160%);
border-radius: 18px;
border: 1px solid rgba(255,255,255,0.13);
box-shadow:
0 8px 32px rgba(0,0,0,0.35),
inset 0 1px 0 rgba(255,255,255,0.18),
inset 0 -1px 0 rgba(0,0,0,0.2);
overflow: hidden;
transition: transform .2s ease, box-shadow .2s ease, background .2s;
position: relative;
}
.lq-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg,
rgba(255,255,255,0.07) 0%,
rgba(255,255,255,0.02) 40%,
transparent 100%);
pointer-events: none;
border-radius: 18px;
}
.lq-card:hover {
transform: translateY(-3px) scale(1.005);
background: rgba(255,255,255,0.1);
box-shadow:
0 16px 48px rgba(0,0,0,0.45),
inset 0 1px 0 rgba(255,255,255,0.22),
0 0 0 1px rgba(120,80,255,0.25);
}
/* Rank */
.lq-num {
width: 48px; flex-shrink: 0; align-self: stretch;
display: flex; align-items: center; justify-content: center;
font-size: 18px; font-weight: 900;
background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
border-right: 1px solid rgba(255,255,255,0.08);
color: rgba(255,255,255,0.25);
}
.lq-num.top {
background: linear-gradient(180deg, rgba(255,215,0,0.12), rgba(255,180,0,0.05));
color: #ffd700;
text-shadow: 0 0 12px rgba(255,215,0,0.5);
}
/* Logo */
.lq-logo {
padding: 14px 16px; flex-shrink: 0;
border-right: 1px solid rgba(255,255,255,0.07);
position: relative; z-index: 1;
}
.lq-logo .logo-pill {
background: rgba(255,255,255,0.92);
border-radius: 10px;
box-shadow: 0 2px 12px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,1);
}
/* Main */
.lq-main {
flex: 1; padding: 14px 18px; min-width: 0;
display: flex; flex-direction: column; gap: 4px;
border-right: 1px solid rgba(255,255,255,0.07);
}
.lq-name {
font-size: 15px; font-weight: 700; color: #fff;
display: flex; align-items: center; gap: 7px;
letter-spacing: -.1px;
}
.lq-bonus {
font-size: 12px; font-weight: 500;
background: linear-gradient(90deg, #ffd700, #ffaa00);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lq-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.lq-chip {
font-size: 10px; color: rgba(255,255,255,0.55);
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.1);
padding: 2px 8px; border-radius: 20px;
backdrop-filter: blur(8px);
}
/* Stars */
.lq-stars {
padding: 14px 14px; flex-shrink: 0;
border-right: 1px solid rgba(255,255,255,0.07);
display: flex; align-items: center;
}
.lq-stars .stars {
font-size: 13px; letter-spacing: 2px;
filter: drop-shadow(0 0 4px rgba(255,215,0,0.5));
}
/* Geo */
.lq-geo {
padding: 14px 14px; flex-shrink: 0;
border-right: 1px solid rgba(255,255,255,0.07);
display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.lq-geo-label { font-size: 9px; color: rgba(255,255,255,0.3); text-transform: uppercase; letter-spacing: .6px; }
/* Action */
.lq-action { padding: 14px 16px; flex-shrink: 0; }
.lq-btn {
display: inline-flex; align-items: center; justify-content: center;
padding: 10px 20px; border-radius: 100px;
background: linear-gradient(135deg,
rgba(120,80,255,0.9) 0%,
rgba(60,140,255,0.9) 100%);
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.25);
box-shadow:
0 4px 20px rgba(100,60,255,0.45),
inset 0 1px 0 rgba(255,255,255,0.3);
color: #fff; font-size: 13px; font-weight: 700;
text-decoration: none; white-space: nowrap;
transition: transform .15s, box-shadow .15s;
position: relative; overflow: hidden;
}
.lq-btn::after {
content: '';
position: absolute; inset: 0; border-radius: 100px;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
transform: translateX(-100%); transition: transform .5s;
}
.lq-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(100,60,255,0.6), inset 0 1px 0 rgba(255,255,255,0.35);
color: #fff; text-decoration: none;
}
.lq-btn:hover::after { transform: translateX(100%); }
/* ── Light theme overrides ──────────────────────────────── */
.ww.light .lq-wrap {
background: linear-gradient(145deg, #e8eeff 0%, #f0f4ff 50%, #e4f0ff 100%);
}
.ww.light .lq-wrap::before {
background: radial-gradient(circle, rgba(110,58,255,0.15), transparent 70%);
}
.ww.light .lq-wrap::after {
background: radial-gradient(circle, rgba(0,140,255,0.15), transparent 70%);
}
.ww.light .lq-card {
background: rgba(255,255,255,0.7);
border-color: rgba(0,0,0,0.08);
box-shadow: 0 4px 20px rgba(0,0,0,0.1),
inset 0 1px 0 rgba(255,255,255,0.9),
inset 0 -1px 0 rgba(0,0,0,0.04);
}
.ww.light .lq-card::before {
background: linear-gradient(135deg, rgba(255,255,255,0.6) 0%, transparent 60%);
}
.ww.light .lq-card:hover {
background: rgba(255,255,255,0.85);
box-shadow: 0 8px 32px rgba(0,0,0,0.15),
inset 0 1px 0 rgba(255,255,255,1),
0 0 0 1px rgba(100,60,255,0.15);
}
.ww.light .lq-num { color: rgba(0,0,0,0.2); background: rgba(0,0,0,0.03); border-right-color: rgba(0,0,0,0.06); }
.ww.light .lq-num.top { color: #b8860b; background: rgba(255,180,0,0.08); text-shadow: none; }
.ww.light .lq-logo { border-right-color: rgba(0,0,0,0.06); }
.ww.light .lq-logo .logo-pill { background: rgba(255,255,255,0.95); box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
.ww.light .lq-main { border-right-color: rgba(0,0,0,0.06); }
.ww.light .lq-name { color: #1a1a2e; }
.ww.light .lq-bonus {
background: linear-gradient(90deg, #b8860b, #d4a017);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.ww.light .lq-chip { color: rgba(0,0,0,0.5); background: rgba(0,0,0,0.05); border-color: rgba(0,0,0,0.08); }
.ww.light .lq-stars { border-right-color: rgba(0,0,0,0.06); }
.ww.light .lq-stars .stars { filter: none; }
.ww.light .lq-geo { border-right-color: rgba(0,0,0,0.06); }
.ww.light .lq-geo-label { color: rgba(0,0,0,0.35); }
.ww.light .lq-geo span { color: rgba(0,0,0,0.45) !important; }
/* Mobile */
@media (max-width: 700px) {
.ww .lq-wrap { padding: 16px 12px; }
.lq-card { flex-wrap: wrap; }
.lq-num { display: none; }
.lq-logo { border-right: none; padding: 12px; flex: 100%; justify-content: center; display: flex; }
.lq-logo .logo-pill { width: 160px; height: 56px; }
.lq-logo .logo-pill img { width: 160px; height: 56px; }
.lq-main { flex: 100%; border-right: none; border-top: 1px solid rgba(255,255,255,0.07); padding: 10px 14px; }
.lq-stars, .lq-geo { display: none; }
.lq-action { flex: 100%; padding: 0 14px 14px; }
.lq-action .lq-btn { width: 100%; justify-content: center; }
}
</style>
</head>
<body>
<!-- Dev bar -->
<div id="dev-bar">
<div class="dg">
<span class="dl">Layout:</span>
<button class="db on" data-layout="table">⊞ Table</button>
<button class="db" data-layout="cards">▦ Cards</button>
<button class="db" data-layout="ranked">☰ Ranked</button>
<button class="db" data-layout="liquid">◈ Liquid</button>
</div>
<div class="db-sep"></div>
<div class="dg">
<span class="dl">Theme:</span>
<button class="db on" data-theme="auto">Auto</button>
<button class="db" data-theme="dark">Dark</button>
<button class="db" data-theme="light">Light</button>
</div>
<div class="db-sep"></div>
<div class="dg">
<span class="dl">GEO:</span>
<?php foreach (['de'=>'🇩🇪','ru'=>'🇷🇺','pl'=>'🇵🇱','tr'=>'🇹🇷','ua'=>'🇺🇦','fr'=>'🇫🇷'] as $cc=>$flag): ?>
<a href="?country=<?= $cc ?>&lang=<?= $cc==='ua'?'uk':$cc ?>"
class="db <?= $country===$cc?'on':'' ?>"><?= $flag ?> <?= strtoupper($cc) ?></a>
<?php endforeach ?>
<a href="?" class="db <?= !$country?'on':'' ?>">Auto</a>
</div>
<div class="di"><?= count($brands) ?> brands · <?= h($country?:'auto') ?> · <?= h($lang) ?></div>
</div>
<div class="ww" id="ww">
<div class="ww-inner">
<?php if (empty($brand_data)): ?>
<div style="text-align:center;padding:80px 20px;opacity:.3;font-size:15px">No brands for this GEO</div>
<?php endif ?>
<!-- ══════════════════════════════════════════
LAYOUT 1: TABLE
══════════════════════════════════════════ -->
<div data-layout="table" class="layout-section active">
<div class="t-table">
<?php foreach ($brand_data as $d):
$is_top = $d['idx'] < 3;
?>
<div class="t-row" onclick="window.open('<?= h($d['click']) ?>','_blank')">
<!-- # -->
<div class="t-num <?= $is_top ? 'top' : '' ?>"><?= $d['idx']+1 ?></div>
<!-- Logo -->
<div class="t-logo">
<div class="logo-pill" style="width:164px;height:64px">
<?php if ($d['b']['logo']): ?>
<img src="<?= h($d['b']['logo']) ?>" alt="<?= h($d['b']['name']) ?>" style="width:164px;height:64px;object-fit:contain">
<?php else: ?>
<span class="logo-pill-text" style="font-size:15px;padding:8px"><?= h($d['b']['name']) ?></span>
<?php endif ?>
</div>
</div>
<!-- Brand -->
<div class="t-brand">
<div class="t-brand-name">
<?= h($d['b']['name']) ?>
<?php if ($d['b']['badge']): ?>
<span class="badge badge-<?= h($d['b']['badge']) ?>"><?= badge_label($d['b']['badge']) ?></span>
<?php endif ?>
</div>
<div class="t-brand-row">
<span class="stars"><?= $d['stars'] ?></span>
</div>
<?php if ($d['adv']): ?>
<?php foreach (array_slice($d['adv'], 0, 2) as $item): ?>
<div class="pro"><?= h($item) ?></div>
<?php endforeach ?>
<?php endif ?>
</div>
<!-- Bonus -->
<div class="t-bonus">
<?php if ($d['bonus']): ?>
<div class="t-bonus-text"><?= h($d['bonus']) ?></div>
<?php else: ?>
<span style="color:var(--text3);font-size:12px">—</span>
<?php endif ?>
</div>
<!-- Stats -->
<div class="t-stats">
<?php if ($d['year_founded']): ?>
<div class="t-stat">
<span class="t-stat-val"><?= $d['year_founded'] ?></span>
<span class="t-stat-label">Est.</span>
</div>
<?php endif ?>
<?php if ($d['games_count']): ?>
<div class="t-stat">
<span class="t-stat-val"><?= h($d['games_count']) ?></span>
<span class="t-stat-label">Games</span>
</div>
<?php endif ?>
<?php if ($d['license']): ?>
<div class="t-stat">
<span class="t-stat-val"><?= h($d['license']) ?></span>
<span class="t-stat-label">License</span>
</div>
<?php endif ?>
<?php if ($d['more_countries'] > 0): ?>
<div class="t-stat">
<span class="t-stat-val">+<?= $d['more_countries'] ?></span>
<span class="t-stat-label">Countries</span>
</div>
<?php endif ?>
</div>
<!-- Action -->
<div class="t-action" onclick="event.stopPropagation()">
<?php if ($country): ?>
<div class="t-avail">
<?= geo_flag($country) ?>
<span><?= h(strtoupper($country)) ?></span>
</div>
<?php endif ?>
<a href="<?= h($d['click']) ?>" class="btn-cta" target="_blank" rel="noopener">
<?= h($cta_text) ?>
</a>
</div>
</div>
<?php endforeach ?>
</div>
</div>
<!-- ══════════════════════════════════════════
LAYOUT 2: CARDS
══════════════════════════════════════════ -->
<div data-layout="cards" class="layout-section">
<div class="c-grid">
<?php foreach ($brand_data as $d): ?>
<div class="c-card">
<div class="c-head">
<?php if ($d['b']['badge']): ?>
<div class="c-head-badge">
<span class="badge badge-<?= h($d['b']['badge']) ?>"><?= badge_label($d['b']['badge']) ?></span>
</div>
<?php endif ?>
<div class="logo-pill c-logo" style="width:200px;height:72px">
<?php if ($d['b']['logo']): ?>
<img src="<?= h($d['b']['logo']) ?>" alt="<?= h($d['b']['name']) ?>" style="width:200px;height:72px;object-fit:contain">
<?php else: ?>
<span class="logo-pill-text" style="font-size:18px;padding:10px"><?= h($d['b']['name']) ?></span>
<?php endif ?>
</div>
<div class="c-stars stars"><?= $d['stars'] ?></div>
<div class="c-name"><?= h($d['b']['name']) ?></div>
</div>
<?php if ($d['bonus']): ?>
<div class="c-bonus">
<div class="c-bonus-label">Welcome Bonus</div>
<div class="c-bonus-text"><?= h($d['bonus']) ?></div>
</div>
<?php endif ?>
<?php
$stats = [];
if ($d['year_founded']) $stats[] = ['Est.', $d['year_founded'], false];
if ($d['games_count']) $stats[] = ['Games', $d['games_count'], false];
if ($d['license']) $stats[] = ['License', $d['license'], false];
if ($d['currencies']) $stats[] = ['Currency', $d['currencies'], false];
if ($d['more_countries']>0) $stats[] = ['+Countries', '+' . $d['more_countries'] . ' more', true];
?>
<?php if ($stats): ?>
<div class="c-stats">
<?php foreach ($stats as [$label, $val, $full]): ?>
<div class="c-stat <?= $full ? 'full' : '' ?>">
<span class="c-stat-val"><?= h($val) ?></span>
<span class="c-stat-label"><?= h($label) ?></span>
</div>
<?php endforeach ?>
</div>
<?php endif ?>
<?php if ($d['adv']): ?>
<div class="c-pros">
<?php foreach (array_slice($d['adv'], 0, 3) as $item): ?>
<div class="pro"><?= h($item) ?></div>
<?php endforeach ?>
</div>
<?php endif ?>
<div class="c-foot">
<?php if ($country): ?>
<div class="c-avail">
<?= geo_flag($country) ?>
<span><?= h($avail_label) ?> <?= h(country_name($country)) ?></span>
</div>
<?php endif ?>
<a href="<?= h($d['click']) ?>" class="btn-cta" target="_blank" rel="noopener">
<?= h($cta_text) ?>
</a>
</div>
</div>
<?php endforeach ?>
</div>
</div>
<!-- ══════════════════════════════════════════
LAYOUT 3: RANKED LIST
══════════════════════════════════════════ -->
<div data-layout="ranked" class="layout-section">
<div class="r-list">
<?php foreach ($brand_data as $d):
$is_top = $d['idx'] < 3;
?>
<div class="r-row">
<div class="r-num <?= $is_top ? 'top' : '' ?>"><?= $d['idx']+1 ?></div>
<div class="r-logo">
<div class="logo-pill" style="width:160px;height:56px">
<?php if ($d['b']['logo']): ?>
<img src="<?= h($d['b']['logo']) ?>" alt="<?= h($d['b']['name']) ?>" style="width:160px;height:56px;object-fit:contain">
<?php else: ?>
<span class="logo-pill-text" style="font-size:13px;padding:6px"><?= h($d['b']['name']) ?></span>
<?php endif ?>
</div>
</div>
<div class="r-main">
<div class="r-name">
<?= h($d['b']['name']) ?>
<?php if ($d['b']['badge']): ?>
<span class="badge badge-<?= h($d['b']['badge']) ?>"><?= badge_label($d['b']['badge']) ?></span>
<?php endif ?>
</div>
<?php if ($d['bonus']): ?>
<div class="r-bonus"><?= h($d['bonus']) ?></div>
<?php endif ?>
<div class="r-row2">
<?php if ($d['games_count']): ?>
<span class="r-chip">🎮 <?= h($d['games_count']) ?></span>
<?php endif ?>
<?php if ($d['license']): ?>
<span class="r-chip">🪪 <?= h($d['license']) ?></span>
<?php endif ?>
<?php if ($d['year_founded']): ?>
<span class="r-chip">📅 <?= $d['year_founded'] ?></span>
<?php endif ?>
<?php if ($d['more_countries'] > 0): ?>
<span class="r-chip">🌍 +<?= $d['more_countries'] ?> countries</span>
<?php endif ?>
</div>
</div>
<div class="r-stars"><span class="stars"><?= $d['stars'] ?></span></div>
<?php if ($country): ?>
<div class="r-geo">
<span class="r-geo-label"><?= h($avail_label) ?></span>
<?= geo_flag($country) ?>
<span style="font-size:11px;color:var(--text2)"><?= h(strtoupper($country)) ?></span>
</div>
<?php endif ?>
<div class="r-action">
<a href="<?= h($d['click']) ?>" class="btn-cta" target="_blank" rel="noopener">
<?= h($cta_text) ?>
</a>
</div>
</div>
<?php endforeach ?>
</div>
</div>
<!-- ══════════════════════════════════════════
LAYOUT 4: LIQUID GLASS
══════════════════════════════════════════ -->
<div data-layout="liquid" class="layout-section">
<div class="lq-wrap">
<div class="lq-list">
<?php foreach ($brand_data as $d): $is_top = $d['idx'] < 3; ?>
<div class="lq-card">
<div class="lq-num <?= $is_top ? 'top' : '' ?>"><?= $d['idx']+1 ?></div>
<div class="lq-logo">
<div class="logo-pill" style="width:140px;height:52px">
<?php if ($d['b']['logo']): ?>
<img src="<?= h($d['b']['logo']) ?>" alt="<?= h($d['b']['name']) ?>" style="width:140px;height:52px;object-fit:contain">
<?php else: ?>
<span class="logo-pill-text" style="font-size:13px;padding:6px"><?= h($d['b']['name']) ?></span>
<?php endif ?>
</div>
</div>
<div class="lq-main">
<div class="lq-name">
<?= h($d['b']['name']) ?>
<?php if ($d['b']['badge']): ?>
<span class="badge badge-<?= h($d['b']['badge']) ?>"><?= badge_label($d['b']['badge']) ?></span>
<?php endif ?>
</div>
<?php if ($d['bonus']): ?>
<div class="lq-bonus"><?= h($d['bonus']) ?></div>
<?php endif ?>
<div class="lq-chips">
<?php if ($d['games_count']): ?><span class="lq-chip">🎮 <?= h($d['games_count']) ?></span><?php endif ?>
<?php if ($d['license']): ?><span class="lq-chip">🪪 <?= h($d['license']) ?></span><?php endif ?>
<?php if ($d['year_founded']): ?><span class="lq-chip">📅 <?= $d['year_founded'] ?></span><?php endif ?>
<?php if ($d['more_countries'] > 0): ?><span class="lq-chip">🌍 +<?= $d['more_countries'] ?></span><?php endif ?>
</div>
</div>
<div class="lq-stars"><span class="stars"><?= $d['stars'] ?></span></div>
<?php if ($country): ?>
<div class="lq-geo">
<span class="lq-geo-label"><?= h($avail_label) ?></span>
<?= geo_flag($country) ?>
<span style="font-size:10px;color:rgba(255,255,255,.45)"><?= h(strtoupper($country)) ?></span>
</div>
<?php endif ?>
<div class="lq-action">
<a href="<?= h($d['click']) ?>" class="lq-btn" target="_blank" rel="noopener">
<?= h($cta_text) ?>
</a>
</div>
</div>
<?php endforeach ?>
</div>
</div>
</div>
</div><!-- /ww-inner -->
</div><!-- /ww -->
<script>
(function () {
function detectTheme() {
var el = document.body, bg = getComputedStyle(el).backgroundColor;
while ((bg==='rgba(0, 0, 0, 0)'||bg==='transparent') && el.parentElement) {
el = el.parentElement; bg = getComputedStyle(el).backgroundColor;
}
var m = bg.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
if (m) return (parseInt(m[1])*299+parseInt(m[2])*587+parseInt(m[3])*114)/1000 < 128 ? 'dark' : 'light';
return 'dark';
}
var ww = document.getElementById('ww');
var cur = {
layout: localStorage.getItem('wt_layout') || 'table',
theme: localStorage.getItem('wt_theme') || 'auto'
};
function applyLayout(l) {
document.querySelectorAll('.layout-section').forEach(function(el) {
el.classList.toggle('active', el.dataset.layout === l);
});
document.querySelectorAll('[data-layout].db').forEach(function(b) {
b.classList.toggle('on', b.dataset.layout === l);
});
}
function applyTheme(t) {
ww.classList.remove('light');
if (t === 'light') ww.classList.add('light');
else if (t === 'auto' && detectTheme() === 'light') ww.classList.add('light');
document.querySelectorAll('[data-theme].db').forEach(function(b) {
b.classList.toggle('on', b.dataset.theme === t);
});
}
document.querySelectorAll('[data-layout].db').forEach(function(btn) {
btn.addEventListener('click', function() {
cur.layout = btn.dataset.layout;
applyLayout(cur.layout);
localStorage.setItem('wt_layout', cur.layout);
});
});
document.querySelectorAll('[data-theme].db').forEach(function(btn) {
btn.addEventListener('click', function() {
cur.theme = btn.dataset.theme;
applyTheme(cur.theme);
localStorage.setItem('wt_theme', cur.theme);
});
});
applyLayout(cur.layout);
applyTheme(cur.theme);
})();
</script>
</body>
</html>