<!DOCTYPE html> <!
-- HTML5 document type declaration -->
<html lang="tr"> <!-- Set document language to Turkish -->
<head> <!-- Document head starts -->
<meta charset="utf-8" /> <!-- Use UTF-8 character encoding -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- Make
layout responsive on mobile -->
<title>20× Searchbars — Smooth Slider, Per-Card Themes, Keyboard Nav</title> <!--
Browser tab title -->
<style> /* Begin embedded CSS */
:root{ /* Global design tokens on the root element */
--bg:#0b0f1a; /* Body background base color */
--bg-2:#0e1424; /* Secondary background gradient color */
--edge:#ffffff22; /* Generic border color with alpha */
--text:#eaf1ff; /* Base text color */
--muted:#9db1ce; /* Muted text color */
--r:18px; /* Generic border radius */
--shadow:0 14px 40px #0009; /* Soft drop shadow */
} /* End root tokens */
*{box-sizing:border-box} /* Include padding/border inside element width/height
*/
body{ /* Body layout and background */
margin:0; /* Remove default margin */
min-height:100svh; /* Ensure body fills the small viewport height */
overflow-x:hidden; /* Hide horizontal overflow */
font-family:Inter, system-ui, Segoe UI, Roboto, Arial, sans-serif; /* Font
stack */
color:var(--text); /* Set default text color */
background: /* Layered background for depth */
radial-gradient(1200px 600px at 10% -10%, #13203a66, transparent),
linear-gradient(180deg, var(--bg), #050811);
} /* End body */
.topbar{ /* Sticky header bar */
position:sticky; top:0; z-index:10; /* Pin to top and bring above content */
display:flex; align-items:center; justify-content:space-between; gap:12px; /*
Flex layout */
padding:16px clamp(14px,4vw,32px); /* Responsive padding */
background:#0b0f1a80; /* Translucent background */
border-bottom:1px solid var(--edge); /* Bottom divider */
backdrop-filter:blur(8px); /* Frosted glass effect */
} /* End topbar */
.brand{display:flex; align-items:center; gap:10px; font-weight:800} /* Logo +
title style */
.dot{ /* Animated color dot in brand */
width:12px; height:12px; border-radius:50%; /* Circle shape */
background:conic-gradient(from 120deg, #60e5ff, #a78bfa); /* Conic color
sweep */
box-shadow:0 0 0 4px #60e5ff1a, 0 0 22px #60e5ff80; /* Glow rings */
animation:pulse 2.2s ease-in-out infinite; /* Breathing animation */
} /* End dot */
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.25)}} /*
Breathing keyframes */
.controls{display:flex; gap:8px; align-items:center} /* Container for nav
buttons */
.ctrl{ /* Navigation button style */
width:44px; height:44px; border-radius:12px; /* Rounded square */
border:1px solid var(--edge); background:#0f1733; /* Button colors */
display:grid; place-items:center; cursor:pointer; /* Center icon and pointer
cursor */
transition:transform .2s, border-color .2s; /* Hover transitions */
} /* End ctrl */
.ctrl:hover{transform:translateY(-2px); border-color:#7dd3fc66} /* Lift and
highlight on hover */
.ctrl svg{width:18px; height:18px; fill:#bfe8ff} /* Icon size and color */
.shell{position:relative; z-index:1; padding:24px clamp(12px,4vw,32px) 40px} /*
Content wrapper with spacing */
.slider{ /* Horizontal slider rail */
position:relative; /* Needed for decorative line */
display:grid; grid-auto-flow:column; /* Flow cards in columns horizontally */
grid-auto-columns:clamp(280px, 42vw, 420px); /* Card width responsive clamp
*/
gap:16px; padding:16px; /* Space around cards */
border:1px solid var(--edge); border-radius:var(--r); /* Outer border and
radius */
background:linear-gradient(180deg, var(--bg-2), #0a1122); /* Slider
background */
box-shadow:var(--shadow); /* Depth shadow */
overflow-x:auto; scroll-snap-type:x mandatory; /* Snap scrolling per card */
scrollbar-width:none; /* Hide Firefox scrollbar */
mask-image:linear-gradient(to right, transparent 0, #000 40px, #000 calc(100%
- 40px), transparent 100%); /* Fade edges */
} /* End slider */
.slider::-webkit-scrollbar{display:none} /* Hide WebKit scrollbar */
.slider::before{ /* Decorative animated glow baseline */
content:""; position:absolute; left:10%; right:10%; bottom:0; height:1px; /*
Position and size */
background:linear-gradient(90deg, transparent, #7dd3fc, transparent); /*
Gradient line */
opacity:.25; transform-origin:left; animation:glowline 4s ease-in-out
infinite; /* Scale animation */
} /* End decorative line */
@keyframes glowline{0%{transform:scaleX(0)}50%{transform:scaleX(1)}100%
{transform:scaleX(0)}} /* Line animation keyframes */
.[Link]-hover .card{transition:transform .35s, filter .35s,
opacity .35s} /* Smooth sibling reaction when hovering a card */
.[Link]-hover .card:not(.is-hover){transform:scale(.9); filter:blur(1px);
opacity:.7} /* Shrink and blur non-hovered cards */
.card{ /* Individual card container */
/* Per-card theme CSS variables with sensible defaults */
--c-bg:#101a33cc; --c-edge:#ffffff24; --c-text:#eaf1ff; --c-muted:#9db1ce; --
c-accent:#60e5ff; --c-accent2:#a78bfa; /* Defaults */
scroll-snap-align:center; /* Snap this card to center when scrolling */
background:var(--c-bg); border:1px solid var(--c-edge); border-radius:var(--
r); /* Themed background/border/radius */
padding:14px; display:flex; flex-direction:column; gap:12px; /* Internal
layout spacing */
position:relative; isolation:isolate; /* Ensure pseudo elements stay inside
*/
color:var(--c-text); /* Inherit themed text color */
transition:transform .35s cubic-bezier(.2,.8,.2,1), box-shadow .35s,
background .35s, border-color .35s; /* Hover transitions */
animation:pop .6s both; /* Entrance animation */
} /* End card */
.card:nth-child(odd){animation-delay:.06s} /* Stagger odd cards slightly */
.card:nth-child(3n){animation-delay:.1s} /* Stagger each third card */
@keyframes pop{from{transform:translateY(10px) scale(.98); opacity:0}
to{transform:none; opacity:1}} /* Pop-in animation */
.card::after{ /* Gradient border sheen on hover */
content:""; position:absolute; inset:-1px; padding:1px; border-
radius:inherit; /* Overlay border area */
background:linear-gradient(130deg, #ffffff12, transparent 30%, var(--c-
accent) 70%, var(--c-accent2)); /* Sheen gradient */
-webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0
0); /* Mask to edges only */
-webkit-mask-composite:xor; mask-composite:exclude; /* Exclude content area
*/
opacity:0; transition:opacity .35s; /* Fade in on hover */
} /* End sheen */
.card:hover{transform:translateY(-8px) scale(1.06); box-shadow:0 24px 60px
#000c; border-color:#ffffff2a; background:#0f1b35cc} /* Lift card on hover */
.card:hover::after{opacity:.6} /* Reveal sheen on hover */
.head{display:flex; align-items:center; gap:10px} /* Card header row */
.badge{ /* Small gradient badge icon */
width:28px; height:28px; border-radius:10px; display:grid; place-
items:center; /* Rounded square badge */
background:linear-gradient(180deg, color-mix(in oklab, var(--c-accent), #fff
18%), var(--c-accent)); /* Vertical gradient */
box-shadow:0 6px 18px color-mix(in oklab, var(--c-accent), #000 50%); /* Glow
shadow */
} /* End badge */
.badge svg{width:16px; height:16px; fill:#061018} /* Badge icon color and size
*/
.meta{opacity:.75; font-size:12px} /* Small metadata under title */
.themes{ /* Per-card theme switch (icon-only) */
position:absolute; right:8px; top:8px; z-index:2; /* Place at top-right of
the card */
display:flex; gap:6px; padding:6px; /* Compact spacing */
background:#0c1222a6; border:1px solid #ffffff25; border-radius:12px;
backdrop-filter:blur(6px); /* Frosted mini bar */
} /* End themes bar */
.tbtn{ /* Theme icon button */
width:26px; height:26px; border-radius:8px; border:1px solid #ffffff20; /*
Shape and border */
background:#0b1222; display:grid; place-items:center; cursor:pointer; /*
Center emoji and pointer */
color:#d8e8ff; font-size:14px; line-height:1; /* Emoji size */
transition:transform .2s, border-color .2s, background .2s; /* Hover and
active transitions */
} /* End theme button */
.tbtn:hover{transform:translateY(-1px); border-color:var(--c-accent)} /* Lift
and highlight on hover */
.tbtn[data-active="true"]{background:linear-gradient(180deg, color-mix(in
oklab, var(--c-accent), #fff 20%), var(--c-accent)); color:#0a0f18} /* Active state
*/
.sb{display:flex; align-items:center; gap:10px} /* Shared searchbar row */
.sb input{flex:1; min-width:0; outline:none} /* Make search input flexible */
.sb button{cursor:pointer} /* Pointer for buttons in searchbars */
/* Searchbar visual variants (kept concise; reused across 20 cards) */
.s1{padding:10px; background:#0d1a33cc; border:1px solid #ffffff22; border-
radius:999px; backdrop-filter:blur(10px)} /* Glass pill field */
.s1 .i{width:18px; height:18px; color:var(--c-muted)} /* Icon color in s1 */
.s1 .i svg{width:100%; height:100%; fill:currentColor} /* SVG inherits color */
.s1 input{background:transparent; border:0; color:var(--c-text)} /* Transparent
input text */
.s1 input::placeholder{color:var(--c-muted)} /* Placeholder muted color */
.s1 button{border:1px solid #2b445c; background:linear-gradient(180deg, color-
mix(in oklab, var(--c-accent), #fff 20%), var(--c-accent)); color:#0a1620; border-
radius:999px; padding:8px 14px; font-weight:700} /* Gradient button */
.s2{padding-top:4px} /* Minimal underline variant */
.s2 .i{width:20px; height:20px; color:var(--c-accent)} /* Accent icon color */
.s2 input{background:transparent; border:0; border-bottom:2px solid #ffffff26;
color:var(--c-text); padding:8px 2px 10px} /* Underline input */
.s2 input:focus{border-bottom-color:var(--c-accent)} /* Accent underline on
focus */
.s3{background:#0e1a2c; border:1px solid #ffffff22; border-radius:14px;
padding:8px 10px} /* Chip+Mic container */
.s3 .chip{width:34px; height:34px; border-radius:10px; display:grid; place-
items:center; background:linear-gradient(#0000,#0000) padding-box, conic-
gradient(from 120deg, var(--c-accent), var(--c-accent2)) border-box; border:2px
solid transparent} /* Gradient ring chip */
.s3 .chip svg{width:18px; height:18px; fill:#dff} /* Chip icon color */
.s3 input{background:transparent; border:0; color:var(--c-text)} /* Transparent
text input */
.s3 .mic{width:36px; height:36px; border-radius:10px; border:1px solid
#ffffff28; background:#0d1a28; display:grid; place-items:center} /* Mic button */
.s3 .mic svg{width:16px; height:16px; fill:var(--c-accent)} /* Mic icon color
*/
.s4{gap:10px} /* Card with GO button */
.s4 input{background:#0e111a; border:1px solid #ffffff22; border-radius:10px;
color:var(--c-text); padding:10px 12px} /* Boxed input */
.s4 .go{width:40px; height:40px; border-radius:10px; border:1px solid
#ffffff28; background:#0d0f18; display:grid; place-items:center} /* Square go
button */
.s4 .go svg{width:18px; height:18px; fill:var(--c-accent2)} /* Go arrow color
*/
.s5{background:#0e1228; border:1px solid #ffffff1f; border-radius:14px;
padding:8px} /* Compact navbar style */
.s5 .cat{display:flex; align-items:center; gap:8px; padding:8px 10px; border-
radius:10px; border:1px solid #ffffff1a; background:#0c1022} /* Category button */
.s5 .cat svg{width:16px; height:16px; fill:var(--c-accent2)} /* Category icon
*/
.s5 .sep{width:1px; height:20px; background:#ffffff1f} /* Vertical separator */
.s5 input{background:transparent; border:0; color:var(--c-text)} /* Transparent
input */
.s5 .submit{width:40px; height:40px; border-radius:10px; border:1px solid
#ffffff22; background:linear-gradient(180deg,#121633,#0d1028); display:grid; place-
items:center} /* Submit square */
.s5 .submit svg{width:18px; height:18px; fill:var(--c-accent)} /* Submit icon
color */
/* Per-card theme palettes (apply by data-theme) */
.card[data-theme="light"] {--c-bg:#172033cc; --c-edge:#ffffff28; --c-
text:#f8fbff; --c-muted:#cbd7e8; --c-accent:#ffd84d; --c-accent2:#ffb347} /* Light
palette */
.card[data-theme="dark"] {--c-bg:#0c0f1acc; --c-edge:#ffffff22; --c-
text:#eaf1ff; --c-muted:#9db1ce; --c-accent:#60e5ff; --c-accent2:#a78bfa} /* Dark
palette */
.card[data-theme="love"] {--c-bg:#1a0e16cc; --c-edge:#ffffff22; --c-
text:#fff1f8; --c-muted:#f3c4de; --c-accent:#ff6aa9; --c-accent2:#ff9ed1} /* Love
(pink) */
.card[data-theme="forest"]{--c-bg:#0c1512cc; --c-edge:#ffffff20; --c-
text:#eafff7; --c-muted:#a4dbc7; --c-accent:#41f5a5; --c-accent2:#27c79a} /* Forest
(green) */
.card[data-theme="mist"] {--c-bg:#0d1316cc; --c-edge:#ffffff22; --c-
text:#eef7fb; --c-muted:#b8c9d3; --c-accent:#7ad1e6; --c-accent2:#c1d7e6} /* Mist
(grey/teal) */
.card[data-theme="space"] {--c-bg:#0b0a18cc; --c-edge:#ffffff22; --c-text:#eef;
--c-muted:#b9b9e0; --c-accent:#8a7bff; --c-accent2:#3de0ff} /* Space (violet/blue)
*/
.card[data-theme="ocean"] {--c-bg:#0a1622cc; --c-edge:#ffffff22; --c-
text:#eaf6ff; --c-muted:#b5d4ea; --c-accent:#28d0ff; --c-accent2:#52f0ff} /* Ocean
(blue) */
</style> <!-- End CSS -->
</head> <!-- End head -->
<body> <!-- Document body starts -->
<header class="topbar"> <!-- Sticky header container -->
<div class="brand"> <!-- Brand container -->
<span class="dot"></span> <!-- Animated conic dot -->
20× Searchbars <!-- Title text -->
</div> <!-- End brand -->
<div class="controls"> <!-- Control buttons wrapper -->
<button class="ctrl" id="prev" title="Previous"> <!-- Previous slide button
-->
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15.41 7.41 14 6 8.59
11 14 16 15.41 14.59 11.83 11z"/></svg> <!-- Left arrow icon -->
</button> <!-- End previous button -->
<button class="ctrl" id="next" title="Next"> <!-- Next slide button -->
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8.59 16.59 10
18l5.41-5L10 8.59 8.59 10l4.58 4z"/></svg> <!-- Right arrow icon -->
</button> <!-- End next button -->
<button class="ctrl" id="play" title="Autoplay / Pause"> <!-- Autoplay toggle
button -->
<svg id="playIcon" viewBox="0 0 24 24" aria-hidden="true"><path d="M8
5v14l11-7z"/></svg> <!-- Play icon (triangle) -->
</button> <!-- End autoplay button -->
</div> <!-- End controls -->
</header> <!-- End header -->
<main class="shell"> <!-- Main content wrapper -->
<section class="slider" id="slider" aria-label="Searchbar Slider"> <!--
Horizontal slider rail -->
<!-- Cards will be injected by JavaScript for compactness and reusability -->
<!-- JS will populate 20 cards -->
</section> <!-- End slider -->
<br>
</main> <!-- End main -->
<script> // Begin JavaScript
// ---------- Utility: create an element with classes and optional HTML
----------
const el = (tag, cls = "", html = "") => { /* Helper function to create
elements quickly */
const node = [Link](tag); /* Create the DOM element */
if(cls) [Link] = cls; /* Assign class list if provided */
if(html) [Link] = html; /* Set inner HTML if provided */
return node; /* Return the element */
}; /* End helper */
// ---------- Data: 20 cards configuration (title, meta, variant, placeholder,
initial theme) ----------
const CARDS = [ /* Array describing each card */
{t:"Glass Pill", m:"Ocean glow", v:"s1", p:"Search anything…", theme:"dark"},
/* Card #1 config */
{t:"Underline Minimal", m:"Focus spark", v:"s2", p:"Quick search…",
theme:"light"}, /* Card #2 config */
{t:"Chip + Mic", m:"Gradient ring", v:"s3", p:"Search docs, issues…",
theme:"love"}, /* Card #3 config */
{t:"Card Header", m:"Go arrow", v:"s4", p:"Discover datasets…",
theme:"forest"}, /* Card #4 config */
{t:"Compact Navbar", m:"Categories + search", v:"s5", p:"Search products…",
theme:"mist"}, /* Card #5 config */
{t:"Outline Dashed", m:"CTA split", v:"s4", p:"Find tutorials…",
theme:"space"}, /* Card #6 config (reuse s4) */
{t:"Soft Rounded", m:"Pill focus", v:"s1", p:"Search settings…",
theme:"ocean"}, /* Card #7 config (reuse s1) */
{t:"Focus Ring", m:"Elevated", v:"s4", p:"Search tasks…", theme:"dark"}, /*
Card #8 config */
{t:"Split Button", m:"Dashboard UX", v:"s5", p:"Search analytics…",
theme:"forest"}, /* Card #9 config */
{t:"Tags + Hint", m:"Assistive", v:"s1", p:"Type to filter…",
theme:"mist"}, /* Card #10 config */
{t:"Keyword Finder", m:"chips", v:"s1", p:"Filter keywords…", theme:"light"},
/* Card #11 config */
{t:"Run Query", m:"play", v:"s5", p:"Search jobs…", theme:"space"}, /* Card
#12 config */
{t:"Tickets", m:"search tasks", v:"s4", p:"Find tickets by id…",
theme:"ocean"}, /* Card #13 config */
{t:"Commands", m:"palette", v:"s3", p:"Run command…", theme:"love"}, /* Card
#14 config */
{t:"Datasets", m:"find", v:"s1", p:"Search datasets…", theme:"forest"}, /*
Card #15 config */
{t:"Quick Jump", m:"smart", v:"s2", p:"Go to page…", theme:"space"}, /* Card
#16 config */
{t:"Dash Search", m:"split-btn", v:"s5", p:"Search dashboards…",
theme:"ocean"}, /* Card #17 config */
{t:"Settings", m:"rounded", v:"s1", p:"Search settings…", theme:"love"}, /*
Card #18 config */
{t:"Catalog", m:"input+btn", v:"s4", p:"Search catalog…", theme:"mist"}, /*
Card #19 config */
{t:"Snippets", m:"chips", v:"s1", p:"Filter snippets…", theme:"light"}, /*
Card #20 config */
]; /* End card data */
// ---------- Icons (inline SVG paths) ----------
const ICONS = { /* Small reusable SVG snippets */
search:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15.5
14h-.79l-.28-.27a6.5 6.5 0 1 0-1.41 1.41l.27.28v.79L20 21l1-1-5.5-5z"/></svg>', /*
Magnifier icon */
star:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2l2 6 6 2-6 2-
2 6-2-6-6-2 6-2 2-6z"/></svg>', /* Starburst icon */
doc:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 4h16v4H4zm0
6h10v10H4z"/></svg>', /* Page icon */
go:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4l1.41 1.41L8.83
10H20v2H8.83l4.58 4.59L12 18l-8-8z"/></svg>', /* Arrow right icon */
play:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8
5v14l11-7z"/></svg>', /* Play triangle icon */
pause:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 5h4v14H6zm8
0h4v14h-4z"/></svg>', /* Pause bars icon */
}; /* End icon map */
// ---------- Build one searchbar DOM for a given variant ----------
function buildSearchbar(variant, placeholder){ /* Create the specific searchbar
UI */
if(variant === 's1'){ /* Glass pill variant path */
const label = el('label', 'sb s1'); /* Create label wrapper with classes */
[Link](el('span', 'i', [Link])); /* Add leading search icon */
const input = el('input'); [Link] = 'search'; [Link] =
placeholder; /* Make input type=search and set placeholder */
[Link](input); /* Append input into label */
const btn = el('button', '', 'Search'); /* Create Search button */
[Link](btn); /* Append button */
return label; /* Return the assembled searchbar */
} /* End s1 */
if(variant === 's2'){ /* Minimal underline variant path */
const label = el('label', 'sb s2'); /* Create label wrapper */
[Link](el('span', 'i', [Link])); /* Add spark icon */
const input = el('input'); [Link]='search';
[Link]=placeholder; /* Configure input */
[Link](input); /* Place input */
return label; /* Return the label */
} /* End s2 */
if(variant === 's3'){ /* Chip + Mic variant path */
const wrap = el('div', 'sb s3'); /* Create container div */
[Link](el('span', 'chip', [Link])); /* Add gradient ring chip with
doc icon */
const input = el('input'); [Link]='search';
[Link]=placeholder; /* Configure input */
[Link](input); /* Append input */
const mic = el('button', 'mic', [Link]); /* Use play triangle as mic
placeholder icon */
[Link](mic); /* Append mic button */
return wrap; /* Return composite */
} /* End s3 */
if(variant === 's4'){ /* Boxed input + Go button variant */
const form = el('form', 'sb s4'); [Link] =
(e)=>[Link](); /* Prevent default submit */
const input = el('input'); [Link]='search';
[Link]=placeholder; /* Configure input */
[Link](input); /* Add input into form */
const go = el('button', 'go', [Link]); /* Create Go button with arrow
icon */
[Link](go); /* Append button */
return form; /* Return form */
} /* End s4 */
if(variant === 's5'){ /* Compact navbar + split button variant */
const bar = el('div', 'sb s5'); /* Create bar container */
const cat = el('button', 'cat', '<svg viewBox="0 0 24 24" aria-
hidden="true"><path d="M4 6h16v2H4zm0 5h16v2H4zm0 5h10v2H4z"/></svg>'); /* Category
button with menu icon */
[Link](cat); /* Append category button */
[Link](el('span','sep')); /* Vertical separator between category and
input */
const input = el('input'); [Link]='search';
[Link]=placeholder; /* Configure input */
[Link](input); /* Append input */
const sub = el('button','submit', [Link]); /* Create submit button
with magnifier icon */
[Link](sub); /* Append submit button */
return bar; /* Return bar */
} /* End s5 */
return el('div','sb', ''); /* Fallback empty bar if unknown variant */
} /* End buildSearchbar */
// ---------- Build one card DOM ----------
function buildCard(cfg){ /* Compose a card using cfg object */
const card = el('article', 'card'); /* Create card element */
[Link]('data-theme', [Link]); /* Apply initial per-card theme
*/
const themes = el('div','themes'); /* Create theme switcher strip */
// Add icon-only theme buttons (emoji as simple iconography)
const THEME_KEYS =
['light','dark','love','forest','mist','space','ocean']; /* Supported theme keys */
const THEME_EMOJI = {light:'☀️', dark:'', love:'💖', forest:'🌲', mist:'🌫️
',
space:'🪐', ocean:'🌊'}; /* Emoji map */
THEME_KEYS.forEach(k=>{ /* Loop through themes to add buttons */
const b = el('button','tbtn', THEME_EMOJI[k]); /* Create theme button with
emoji */
[Link]='button'; [Link] = k[0].toUpperCase()+[Link](1); /* Set button
type and tooltip */
[Link] = k; /* Store theme key on data attribute */
if(k===[Link]) [Link] = 'true'; /* Mark current theme as
active */
[Link](b); /* Append theme button into strip */
}); /* End theme buttons loop */
[Link](themes); /* Attach theme strip to card */
const head = el('div','head'); /* Create card header row */
[Link](el('span','badge', [Link])); /* Add small gradient badge
with icon */
[Link](el('div','', `<strong>${cfg.t}</strong><div class="meta">$
{cfg.m}</div>`)); /* Add title and meta */
[Link](head); /* Attach header to card */
const sb = buildSearchbar(cfg.v, cfg.p); /* Build the chosen searchbar
variant */
[Link](sb); /* Append searchbar to card */
return card; /* Return complete card element */
} /* End buildCard */
// ---------- Populate slider with 20 cards ----------
const slider = [Link]('slider'); /* Reference to the slider
rail */
[Link](cfg => [Link](buildCard(cfg))); /* Create and insert each
configured card */
// ---------- Per-card theme switching (only affect that card) ----------
[Link]('click', (e)=>{ /* Delegate click events within the
slider */
const btn = [Link]('.tbtn'); /* Find the nearest theme button */
if(!btn) return; /* Exit if click is not on a theme button */
const card = [Link]('.card'); /* Find the owning card */
const theme = [Link]; /* Read requested theme key */
[Link]('data-theme', theme); /* Apply theme to this card only */
[Link]('.tbtn').forEach(b=>[Link]('data-
active')); /* Clear previous active state */
[Link] = 'true'; /* Mark clicked theme as active */
}); /* End theme switch handler */
// ---------- Hover focus: enlarge hovered card, shrink siblings + trigger
burst ----------
[Link]('mouseover', (e)=>{ /* When pointer enters inside
slider */
const card = [Link]('.card'); /* Find hovered card if any */
if(!card) return; /* Ignore if not over a card */
[Link]('has-hover'); /* Enable sibling reaction mode */
[Link]('.card').forEach(c=>[Link]('is-hover',
c===card)); /* Mark only hovered card */
burst(card); /* Trigger particle burst on this card */
}); /* End mouseover */
[Link]('mouseout', (e)=>{ /* When pointer leaves slider area
*/
if(![Link] || ){ /* Check pointer
truly left the slider */
[Link]('has-hover'); /* Disable sibling reaction mode */
[Link]('.card').forEach(c=>[Link]('is-
hover')); /* Clear hover flag */
} /* End contains check */
}); /* End mouseout */
// ---------- Autoplay: smooth infinite scroll using requestAnimationFrame
----------
const playBtn = [Link]('play'); /* Get autoplay toggle button
*/
const playIcon = [Link]('playIcon'); /* Get SVG icon inside
button */
let playing = true; /* Track autoplay state (default on) */
let rafId = null; /* Store RAF id to cancel later */
let last = 0; /* Keep last frame timestamp for delta time */
function loop(ts){ /* Animation loop callback (ts = high-res timestamp) */
if(!playing){rafId=null; return;} /* Stop loop if not playing */
if(!last) last = ts; /* Initialize last timestamp */
const dt = ts - last; last = ts; /* Compute delta time */
const cycle = ([Link]()/1000) % 6; /* 6s breathing cycle */
const ease = 0.6 + 0.4*[Link](cycle*[Link]*2); /* Eased speed factor */
const dx = dt * (0.22) * (1+ease); /* Pixels to scroll this frame */
const max = [Link] - [Link]; /* Max scroll offset */
const nextX = [Link] + dx; /* Compute next scroll position */
[Link] = nextX >= max ? 0 : nextX; /* Wrap back to start at end */
rafId = requestAnimationFrame(loop); /* Request next frame */
} /* End loop */
function setPlaying(v){ /* Toggle autoplay on/off */
playing = v; /* Update flag */
if(playing){ /* If playing is enabled */
[Link] = [Link]('<svg','<svg'); /* Show pause icon
*/
if(!rafId) rafId = requestAnimationFrame(loop); /* Start RAF loop if not
already */
}else{ /* If playing is disabled */
[Link] = [Link]('<svg','<svg'); /* Show play icon
*/
if(rafId){cancelAnimationFrame(rafId); rafId=null;} /* Stop RAF loop */
} /* End condition */
} /* End setPlaying */
[Link]('click', ()=> setPlaying(!playing)); /* Click to
toggle autoplay */
['mousedown','touchstart','wheel','keydown'].forEach(ev =>
[Link](ev, ()=> setPlaying(false), {passive:true})); /* Pause on
user interaction */
setPlaying(true); /* Start autoplay initially */
// ---------- Keyboard navigation: ArrowLeft/ArrowRight and A/D ----------
const step = ()=> [Link] * 0.85; /* Compute one navigation step
based on viewport */
const goLeft = ()=> [Link]({left:-step(), behavior:'smooth'}); /*
Smoothly scroll left by one step */
const goRight = ()=> [Link]({left: step(), behavior:'smooth'}); /*
Smoothly scroll right by one step */
[Link]('prev').addEventListener('click', goLeft); /* Bind
previous button to goLeft */
[Link]('next').addEventListener('click', goRight); /* Bind
next button to goRight */
[Link]('keydown', (e)=>{ /* Listen for global key presses */
const tag = [Link]?.tagName || ""; /* Get currently focused
tag name */
if(/INPUT|TEXTAREA/.test(tag)) return; /* Do not intercept when typing in
inputs/areas */
if([Link] === 'ArrowLeft' || [Link]() === 'a'){ /* Check for left
arrow or 'a' */
[Link](); setPlaying(false); goLeft(); /* Stop autoplay and move
left */
} /* End left keys */
if([Link] === 'ArrowRight' || [Link]() === 'd'){ /* Check for right
arrow or 'd' */
[Link](); setPlaying(false); goRight(); /* Stop autoplay and move
right */
} /* End right keys */
}); /* End keyboard handler */
// ---------- “/” shortcut: focus first visible search input ----------
[Link]('keydown', (e)=>{ /* Listen for slash key */
if([Link] === '/' && !/INPUT|TEXTAREA/.test([Link]))
{ /* When not currently typing */
[Link](); /* Prevent browser quick find */
const cards = [Link]([Link]('.card')); /* Collect all
cards */
const vw = innerWidth; /* Get viewport width */
const target = [Link](c=>{const r=[Link](); return
[Link]<vw && [Link]>0;}); /* Find first visible card */
target?.querySelector('input[type="search"]')?.focus(); /* Focus its search
input if available */
} /* End slash check */
}); /* End slash shortcut */
// ---------- Burst particles: create quick sparkles on hovered card ----------
function burst(card){ /* Create radial sparkles relative to a card */
const r = [Link](); /* Measure card screen rectangle */
const cx = [Link] + [Link]/2; /* Compute center X */
const cy = [Link] + [Link]/3; /* Compute slightly upper center Y */
const styles = getComputedStyle(card); /* Read computed styles for theme
colors */
const c1 = [Link]('--c-accent').trim() || '#60e5ff'; /*
Primary accent color */
const c2 = [Link]('--c-accent2').trim() || '#a78bfa'; /*
Secondary accent color */
const count = 12; /* Number of particles to emit */
for(let i=0;i<count;i++){ /* Loop to create each particle */
const p = [Link]('span'); /* Create particle element */
[Link]='fixed'; [Link] = cx+'px'; [Link] = cy+'px'; /*
Position particle at origin */
[Link] = [Link] = (3+[Link]()*5)+'px'; /* Random
particle size */
[Link]='50%'; /* Make particle circular */
const col = i%2 ? c1 : c2; /* Alternate between two theme colors */
[Link] = col; /* Fill with color */
[Link] = `0 0 10px ${col}88`; /* Soft glow shadow */
[Link]='none'; [Link]=30; /* Prevent interaction and
bring above UI */
[Link]='translate(-50%,-50%)'; /* Center transform origin */
[Link](p); /* Add particle to the document */
const ang = ([Link]*2)*(i/count) + ([Link]()*0.6-0.3); /* Spread
angle with jitter */
const dist = 18 + [Link]()*36; /* Random travel distance */
const tx = [Link](ang)*dist; const ty = [Link](ang)*dist; /* Compute
travel offset */
[Link]([ /* Animate particle movement and fade */
{transform:'translate(-50%,-50%) translate(0,0) scale(1)', opacity:1}, /*
Start at origin fully visible */
{transform:`translate(-50%,-50%) translate(${tx}px,${ty}px) scale(0.6)`,
opacity:0} /* Move out and fade */
], {duration:600+[Link]()*400, easing:'cubic-
bezier(.2,.8,.2,1)'}).onfinish = ()=> [Link](); /* Remove at end */
} /* End loop */
} /* End burst */
</script> <!-- End JavaScript -->
</body> <!-- End body -->
</html> <!-- End HTML document -->