/* Components CSS - Extracted from header.php inline styles */

/* Mobile Menu Styles */
.mobile-menu-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
}
.mobile-menu-overlay.active {
    opacity: 1;
    visibility: visible;
}
.mobile-menu {
    position: fixed;
    top: 0;
    left: 0;
    width: 280px;
    height: 100%;
    background: var(--bg-card);
    border-right: 3px solid var(--border-color);
    z-index: 1001;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    overflow-y: auto;
}
.mobile-menu.active {
    transform: translateX(0);
}
.mobile-menu-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    /* 40px close button + 0.75rem vertical padding ≈ 64px header band. */
    min-height: 64px;
    padding: 0.75rem 1.25rem;
    border-bottom: 2px solid var(--border-color);
}
.mobile-menu-close {
    /* In-flow part of .mobile-menu-header — sits on the side nearest the
       hamburger (left in RTL, right in LTR) so it still reads as the toggle. */
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}
.mobile-menu-close:hover {
    background: var(--primary-accent);
    color: var(--icon-color);
}
.mobile-menu-links {
    padding: 1rem 0;
}
.mobile-menu-links a {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1.25rem;
    color: var(--text-primary);
    font-weight: 600;
    transition: all 0.2s;
    border-right: 3px solid transparent;
}
.mobile-menu-links a:hover {
    background: var(--primary-accent);
    color: #202935;
    border-right-color: var(--border-color);
}
.mobile-menu-links a svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}
.hamburger-btn {
    display: flex;
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    cursor: pointer;
    transition: all 0.2s;
}
.hamburger-btn:hover {
    background: var(--primary-accent);
    color: var(--icon-color);
}
.menu-divider {
    height: 1px;
    background: var(--border-color);
    margin: 0.5rem 1.25rem;
}

/* PWA Install Instructions Modal */
.pwa-modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 10000;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.pwa-modal-overlay.show {
    display: flex;
}
.pwa-modal {
    background: var(--bg-card);
    border: 3px solid var(--border-color);
    border-radius: 16px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
    max-width: 400px;
    width: 100%;
    animation: modalIn 0.3s ease;
}
@keyframes modalIn {
    from { opacity: 0; transform: scale(0.9); }
    to { opacity: 1; transform: scale(1); }
}
.pwa-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    border-bottom: 2px solid var(--border-color);
}
.pwa-modal-header h3 {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 700;
}
.pwa-modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: var(--bg-card);
    border: 2px solid var(--border-color);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
}
.pwa-modal-close:hover {
    background: #fee2e2;
}
.pwa-modal-close svg {
    width: 18px;
    height: 18px;
}
.pwa-modal-body {
    padding: 20px;
}
.pwa-instructions-title {
    font-weight: 700;
    margin: 0 0 16px 0;
    color: var(--text-primary);
}
.pwa-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    counter-reset: step;
}
.pwa-steps li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border-color);
}
.pwa-steps li:last-child {
    border-bottom: none;
}
.step-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: var(--primary-accent);
    color: #202935;
    border: 2px solid var(--border-color);
    border-radius: 50%;
    font-size: 1rem;
    flex-shrink: 0;
}
.pwa-steps li span:last-child {
    padding-top: 6px;
    line-height: 1.5;
}

/* Menu Install Button */
.install-btn {
    display: none;
    align-items: center;
    gap: 0.75rem;
    margin: 0.75rem 1.25rem;
    padding: 0.875rem 1.25rem;
    background: var(--primary-accent);
    color: #202935;
    font-weight: 700;
    border: 2px solid var(--border-color);
    border-radius: 0.75rem;
    cursor: pointer;
    transition: all 0.2s;
}
.install-btn svg {
    width: 20px;
    height: 20px;
}
.install-btn.show {
    display: flex;
}

/* Toast Notification System */
.toast-container {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 20px;
    background: var(--bg-card, #fff);
    border: 2px solid var(--border-color, #202935);
    border-radius: 12px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
    font-weight: 600;
    pointer-events: auto;
    animation: toastIn 0.3s ease;
    width: max-content;
    max-width: min(90vw, 420px);
    line-height: 1.55;
    text-align: start;
}
.toast > span {
    flex: 1 1 auto;
    min-width: 0;
}
.toast .toast-icon {
    margin-top: 2px;
}
.toast.toast-out {
    animation: toastOut 0.3s ease forwards;
}
.toast-success {
    border-color: #22c55e;
}
.toast-success .toast-icon {
    color: #22c55e;
}
.toast-error {
    border-color: #ef4444;
}
.toast-error .toast-icon {
    color: #ef4444;
}
.toast-warning {
    border-color: #f59e0b;
}
.toast-warning .toast-icon {
    color: #f59e0b;
}
.toast-info {
    border-color: #3b82f6;
}
.toast-info .toast-icon {
    color: #3b82f6;
}
.toast-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}
@keyframes toastIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes toastOut {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(20px); }
}

/* Global Loading Overlay */
.neo-loading-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    opacity: 0;
    visibility: hidden;
    transition: all 0.2s ease;
}
.neo-loading-overlay.active {
    opacity: 1;
    visibility: visible;
}
.neo-loading-box {
    background: var(--bg-card, #fff);
    border: 3px solid var(--border-color, #202935);
    border-radius: 16px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
    padding: 32px 48px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}
.neo-spinner {
    width: 48px;
    height: 48px;
    border: 4px solid var(--border-color, #202935);
    border-top-color: var(--primary-accent, #fec007);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}
.neo-loading-text {
    font-weight: 700;
    font-size: 1rem;
    color: var(--text-primary);
}
@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Form Validation Styles */
.input-error {
    border-color: #ef4444 !important;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2) !important;
}
.input-success {
    border-color: #22c55e !important;
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2) !important;
}
.field-error {
    color: #ef4444;
    font-size: 0.875rem;
    margin-top: 4px;
    display: flex;
    align-items: center;
    gap: 4px;
}
.field-error svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* Fake-hole colour for multi-rect raw icons (QR, tank): tracks whatever the
   icon tile is filled with, so the cut-outs read as holes in both modes. */
:root { --icon-hole: var(--primary-accent); }
:root.dark { --icon-hole: var(--bg-input); }

/* ── Dark-mode tool cards ──────────────────────────────────────────────
   The solid-yellow icon tile vibrates against the dark cards. In dark mode
   swap it for a dark tile + yellow icon (far less yellow area) and drop the
   hard offset shadow. Light mode keeps the punchy yellow fill + shadow. */
:root.dark .tool-card .bg-accent {
    background-color: var(--bg-input);
    border: 1px solid var(--border-color);
}
:root.dark .tool-card .bg-accent .tool-icon,
:root.dark .tool-card .bg-accent .tool-icon-text {
    color: var(--primary-accent) !important;
}
/* The light-yellow halo only suited a black icon on a yellow tile. */
:root.dark .tool-card .bg-accent svg { filter: none; }
:root.dark .tool-card .bg-accent .tool-icon-text { text-shadow: none; }
/* Live widgets (calendar, IP, typing, game stats) get the same treatment —
   they use .tool-widget / .tool-widget-header-icon, not .tool-card. */
:root.dark .tool-widget-header-icon {
    background: var(--bg-input);
    border: 1px solid var(--border-color);
    color: var(--primary-accent);
}
/* Game widgets inject the tool's own icon, which carries .tool-icon
   (forced dark via !important) — re-assert yellow for it inside the tile. */
:root.dark .tool-widget-header-icon .tool-icon,
:root.dark .tool-widget-header-icon .tool-icon-text {
    color: var(--primary-accent) !important;
}
:root.dark .tool-widget-header-icon svg { filter: none; }
/* Card/widget shadow lives in the --card-shadow custom property (styles.css,
   :root + :root.dark) so light/dark resolve automatically — no override here. */

/* Promo Banner */
/* Desktop: fixed bottom-right card */
.promo-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    position: fixed;
    bottom: 1.25rem;
    right: 1.25rem;
    z-index: 999;
    width: 160px;
    background: var(--bg-card);
    border: 2px solid var(--border-color);
    border-radius: 1rem;
    text-decoration: none;
    color: var(--text-primary);
    overflow: hidden;
    transition: all 0.3s ease;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
}
.promo-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.promo-card-close {
    position: absolute;
    top: 0.3rem;
    right: 0.4rem;
    width: 1.6rem;
    height: 1.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.9);
    color: #111;
    border-radius: 50%;
    font-size: 1rem;
    cursor: pointer;
    line-height: 0;
    z-index: 1;
    opacity: 0;
    transition: opacity 0.2s;
}
:root[dir="rtl"] .promo-card-close { right: auto; left: 0.4rem; }
.promo-card:hover .promo-card-close { opacity: 1; }
.promo-card-img {
    width: 100%;
    height: 100px;
    object-fit: cover;
}
.promo-card-body {
    padding: 0.6rem 0.75rem 0.75rem;
    text-align: center;
    font-family: Yekan Bakh,'Vazirmatn', sans-serif;
}
.promo-card-text {
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.5;
    margin-bottom: 0.6rem;
    color: var(--text-secondary);
}
.promo-card-btn {
    display: inline-block;
    padding: 0.4rem 1.15rem;
    background: var(--primary-accent);
    color: #000;
    font-weight: 800;
    font-size: 0.85rem;
    font-family: Yekan Bakh,'Vazirmatn', sans-serif;
    border-radius: 0.5rem;
    border: none;
    transition: all 0.2s;
}
.promo-card:hover .promo-card-btn {
    filter: brightness(0.9);
}

/* Mobile: fixed bottom bar */
.promo-bar {
    display: none;
}
@media (max-width: 640px) {
    .promo-card { display: none; }
    .promo-bar {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.6rem;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 999;
        padding: 0.85rem 1.25rem;
        background: linear-gradient(135deg, #fff8e1 0%, #ffe082 50%, #ffd54f 100%);
        background-size: 200% 200%;
        border-top: 2.5px solid #f9a825;
        text-decoration: none;
        color: #4e342e;
        font-weight: 700;
        font-size: 0.95rem;
        box-shadow: 0 -4px 20px rgba(249,168,37,0.35);
        animation: promo-shimmer 3s ease-in-out infinite;
    }
    .promo-bar .promo-icon {
        font-size: 1.4rem;
        display: inline-block;
        animation: promo-coin 2s ease-in-out infinite;
    }
    .promo-bar .promo-arrow {
        font-size: 1.1rem;
        font-weight: 900;
        animation: promo-bounce-arrow 1.5s ease-in-out infinite;
    }
    :root[dir="ltr"] .promo-bar .promo-arrow {
        animation: promo-bounce-arrow-ltr 1.5s ease-in-out infinite;
    }
    .promo-bar .promo-close {
        position: absolute;
        left: 0.75rem;
        top: 50%;
        transform: translateY(-50%);
        color: #8d6e63;
        font-size: 1.1rem;
        cursor: pointer;
        padding: 0.25rem;
        line-height: 1;
        opacity: 0.6;
    }
    :root[dir="ltr"] .promo-bar .promo-close {
        left: auto;
        right: 0.75rem;
    }
    body.has-promo { padding-bottom: 3.5rem; }
}
@keyframes promo-shimmer {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}
@keyframes promo-coin {
    0%, 100% { transform: scale(1) rotate(0deg); }
    25% { transform: scale(1.2) rotate(-10deg); }
    50% { transform: scale(1) rotate(0deg); }
    75% { transform: scale(1.15) rotate(10deg); }
}
@keyframes promo-bounce-arrow {
    0%, 100% { transform: translateX(0); }
    50% { transform: translateX(-5px); }
}
@keyframes promo-bounce-arrow-ltr {
    0%, 100% { transform: rotate(180deg) translateX(0); }
    50% { transform: rotate(180deg) translateX(-5px); }
}

/* Favorite Button */
.favorite-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    font-family: inherit;
    color: var(--text-secondary);
    background: var(--bg-card);
    border: 2px solid var(--border-color);
    border-radius: 2rem;
    cursor: pointer;
    transition: all 0.2s;
}
.favorite-btn:hover {
    background: var(--bg-input);
    border-color: #ef4444;
    color: #ef4444;
}
.favorite-btn.is-favorite {
    background: #fef2f2;
    border-color: #ef4444;
    color: #ef4444;
}
:root.dark .favorite-btn.is-favorite {
    background: #450a0a;
    border-color: #f87171;
    color: #f87171;
}
.favorite-btn svg {
    width: 1.25rem;
    height: 1.25rem;
}
.favorite-btn.is-favorite svg {
    fill: currentColor;
}

/* Header favorite button */
.favorite-btn-header {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 2px solid var(--border-color);
    background: var(--bg-card);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s;
    color: var(--text-secondary);
}
.favorite-btn-header:hover {
    background: #fef2f2;
    border-color: #ef4444;
    color: #ef4444;
}
.favorite-btn-header.is-favorite {
    background: #fef2f2;
    border-color: #ef4444;
    color: #ef4444;
}
.favorite-btn-header.is-favorite svg {
    fill: #ef4444;
}
:root.dark .favorite-btn-header:hover,
:root.dark .favorite-btn-header.is-favorite {
    background: #450a0a;
    border-color: #f87171;
    color: #f87171;
}
:root.dark .favorite-btn-header.is-favorite svg {
    fill: #f87171;
}
.favorite-btn-header svg {
    width: 20px;
    height: 20px;
}

/* Theme Toggle Button in Menu */
.theme-toggle-btn {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: calc(100% - 2.5rem);
    margin: 0.75rem 1.25rem;
    padding: 0.875rem 1.25rem;
    background: var(--bg-card);
    color: var(--text-primary);
    font-weight: 600;
    font-family: inherit;
    font-size: 1rem;
    border: 2px solid var(--border-color);
    border-radius: 0.75rem;
    cursor: pointer;
    transition: all 0.2s;
}
.theme-toggle-btn:hover {
    background: var(--primary-accent);
    color: #202935;
}
.theme-toggle-btn svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

/* ===== Tool Card Layout ===== */
.tool-info {
    margin-inline-start: 1rem;
}

/* ===== LTR (English) Overrides ===== */
[dir="ltr"] .mobile-menu {
    left: auto;
    right: 0;
    border-right: none;
    border-left: 3px solid var(--border-color);
    transform: translateX(100%);
}
[dir="ltr"] .mobile-menu.active {
    transform: translateX(0);
}
[dir="ltr"] .mobile-menu-links a {
    border-right: none;
    border-left: 3px solid transparent;
}
[dir="ltr"] .mobile-menu-links a:hover {
    border-right-color: transparent;
    border-left-color: var(--border-color);
}
[dir="ltr"] .search-container input {
    text-align: left;
    direction: ltr;
}
[dir="ltr"] .back-link {
    direction: ltr;
}
[dir="ltr"] .seo-content {
    direction: ltr;
    text-align: left;
}

/* Category Nav Bar — full-bleed within container, fixed to header when stuck */
.category-chips-bar {
    position: relative;
    width: 100vw;
    margin: 0 calc(50% - 50vw) 1rem;
    padding: 0.5rem 1rem;
    background: transparent;
    transition: background-color 0.25s ease;
}
/* Placeholder keeps layout stable while chip bar is fixed */
.category-chips-placeholder {
    display: none;
    width: 100%;
}
.category-chips-placeholder.active {
    display: block;
}
.category-chips-bar.is-stuck {
    position: fixed;
    top: calc(var(--header-h, 56px) - 1px); /* -1px overlap to cover header's border & sub-pixel gaps */
    inset-inline: 0;
    width: 100vw;
    margin: 0;
    z-index: 998; /* above header (997) to seamlessly cover its border */
    background: var(--bg-card);
    border-bottom: 2px solid var(--border-color);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
}
:root.dark .category-chips-bar.is-stuck {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
}

/* Chip bar placed inside the header (desktop, on scroll) */
.category-chips-bar.in-header {
    position: static;
    width: auto;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0 0.75rem;
    padding: 0;
    background: transparent !important;
    box-shadow: none !important;
    border: none !important;
}
.header-sticky .category-chips-bar.in-header .category-chips {
    max-width: 100%;
    margin: 0;
    gap: 6px;
    flex-wrap: nowrap;
    justify-content: center;
    /* No overflow clipping here — 8 short chips fit easily in desktop header. */
}
.header-sticky .category-chips-bar.in-header .category-chip {
    padding: 6px 12px;
    font-size: 0.8rem;
    flex-shrink: 0;
}
.header-sticky .category-chips-bar.in-header .category-chip svg {
    width: 16px;
    height: 16px;
}
.header-sticky .category-chips-bar.in-header .chip-full { display: none; }
.header-sticky .category-chips-bar.in-header .chip-short { display: inline; }
.header-sticky .category-chips-bar.in-header .chip-count { display: none; }

.category-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    max-width: 800px;
    margin-inline: auto;
}
/* Forced 3-3 row break (mobile only — see the media query below). */
.chip-row-break { display: none; }

.category-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border: 2px solid var(--border-color);
    border-radius: 9999px;
    background: var(--bg-card);
    box-shadow: var(--card-shadow);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.2s, color 0.2s, box-shadow 0.2s, transform 0.2s;
    white-space: nowrap;
    font-family: inherit;
    color: var(--text-primary);
}
.category-chip svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
.chip-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    /* Top-only padding nudges the digit down: Persian digits sit high in the
       line box (empty descender space), so flex-centering alone reads as off. */
    padding: 0.14rem 0.34rem 0;
    box-sizing: border-box;
    border-radius: 9999px;
    background: var(--border-light);
    color: var(--text-secondary);
    font-weight: 700;
    font-size: 0.68rem;
    line-height: 1;
}
.category-chip.active {
    background: var(--primary-accent);
    color: #202935;
}
.category-chip.active .chip-count {
    background: rgba(0, 0, 0, 0.13);
    color: #202935;
}
@media (hover: hover) {
    .category-chip:hover {
        background: var(--primary-accent);
        color: #202935;
    }
    .category-chip:hover .chip-count {
        background: rgba(0, 0, 0, 0.13);
        color: #202935;
    }
}

/* Flat chips (no border/shadow) when chip bar is stuck or merged into header */
.category-chips-bar.is-stuck .category-chip,
.category-chips-bar.in-header .category-chip {
    border: none;
    background: var(--bg-input);
    box-shadow: none;
    padding: 7px 14px;
}
.category-chips-bar.is-stuck .category-chip.active,
.category-chips-bar.in-header .category-chip.active {
    background: var(--primary-accent);
    box-shadow: none;
}
@media (hover: hover) {
    .category-chips-bar.is-stuck .category-chip:hover,
    .category-chips-bar.in-header .category-chip:hover {
        background: var(--primary-accent);
        color: #202935;
        box-shadow: none;
    }
    .category-chips-bar.is-stuck .category-chip:hover .chip-count,
    .category-chips-bar.in-header .category-chip:hover .chip-count {
        background: rgba(0, 0, 0, 0.13);
        color: #202935;
    }
}

/* Full label on desktop, short label on mobile */
.chip-short { display: none; }

@media (max-width: 768px) {
    .category-chips-bar {
        padding: 0.4rem 0;
        margin-bottom: 0.75rem;
    }

    /* Mobile DEFAULT: wrap into multiple rows (like desktop), no horizontal
       scroll. Full chip labels wrap naturally + centered — no forced 4-4 split
       (the old break orphaned a wide chip alone on its own row). */
    .category-chips-bar:not(.is-stuck) .category-chips {
        flex-wrap: wrap;
        justify-content: center;
        max-width: 100%;
        column-gap: 4px;
        row-gap: 5px;
        padding: 0 0.5rem;
    }

    /* Mobile STUCK: horizontal scroll strip */
    .category-chips-bar.is-stuck .category-chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        justify-content: flex-start;
        max-width: 100%;
        gap: 6px;
        padding: 0 1rem;
        scrollbar-width: none;
        -ms-overflow-style: none;
        scroll-snap-type: x proximity;
    }
    .category-chips-bar.is-stuck .category-chips::-webkit-scrollbar { display: none; }
    .category-chips-bar.is-stuck .category-chip {
        scroll-snap-align: start;
    }

    /* Edge fade only when horizontally scrollable (stuck state) */
    .category-chips-bar.is-stuck::before,
    .category-chips-bar.is-stuck::after {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        width: 20px;
        pointer-events: none;
        z-index: 2;
    }
    .category-chips-bar.is-stuck::before {
        inset-inline-start: 0;
        background: linear-gradient(to right, var(--bg-card), transparent);
    }
    .category-chips-bar.is-stuck::after {
        inset-inline-end: 0;
        background: linear-gradient(to left, var(--bg-card), transparent);
    }
    [dir="rtl"] .category-chips-bar.is-stuck::before {
        background: linear-gradient(to left, var(--bg-card), transparent);
    }
    [dir="rtl"] .category-chips-bar.is-stuck::after {
        background: linear-gradient(to right, var(--bg-card), transparent);
    }

    /* Common chip sizing on mobile — sized for a forced 3+3 layout (see
       .chip-row-break below). Slightly roomier than the old 4-per-row probe. */
    .category-chip {
        padding: 6px 10px;
        font-size: 0.75rem;
        gap: 5px;
        flex-shrink: 0;
    }
    .category-chip svg { width: 13px; height: 13px; }
    /* Force a flex line break after the 3rd chip → 3+3 instead of 4+2. */
    .category-chips-bar:not(.is-stuck) .chip-row-break {
        display: block;
        flex-basis: 100%;
        height: 0;
    }
    /* Short labels on mobile — drops the "ابزار " prefix so chips stay narrow
       and wrap evenly instead of orphaning a wide chip on its own row. */
    .chip-full { display: none; }
    .chip-short { display: inline; }
    /* Hide count on mobile to save space */
    .chip-count { display: none; }
}

/* Page-load intro: the floating icons are pre-hidden in the markup (.intro-armed
   set server-side) so they never flash before the JS intro stashes them in the
   box. Only opacity is zeroed — the icons keep their natural layout positions so
   the intro's fly-vector measurement stays accurate. JS removes .intro-armed once
   it runs; a <noscript> rule in the markup restores opacity when JS is disabled. */
.hero-section.intro-armed .hero-shapes svg {
    opacity: 0;
}

/* Hero Logo */
.hero-logo {
    width: 80px;
    height: 80px;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    outline: none;
    overflow: visible;
    transition: transform 0.2s ease;
}
.hero-logo:hover {
    transform: scale(1.06);
}
.hero-logo:focus { outline: none; }
.hero-logo:focus-visible {
    outline: 2px solid var(--primary-accent, #fec007);
    outline-offset: 4px;
    border-radius: 8px;
}
/* Box interior — a dark diamond sitting behind the lid. When the lid is closed,
   the (yellow) lid covers it. When the lid morphs into the open position above the
   box, the interior is revealed, showing a black opening into the box. */
.hero-logo .box-interior {
    fill: #202935;
    stroke: #202935;
    stroke-width: 1.5px;
    stroke-linejoin: round;
}
/* Lid morphs via CSS `d` property: closed diamond → open tall parallelogram hinged
   on the back-left edge (line from back-vertex 12,2.25 to left-vertex 3,7.5).
   Fill transitions from yellow (outer surface) to near-black (inside of the lid). */
.hero-logo .box-lid {
    d: path("M 12 2.25 L 3 7.5 L 12 12.75 L 21 7.5 Z");
    /* Closing transition — smooth ease-out, no overshoot */
    transition: d 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                fill 0.4s ease;
    will-change: d, fill;
}
.hero-section.lid-open .hero-logo .box-lid {
    /* Lid stands straight up from the back-left hinge. The two non-hinge vertices
       move STRAIGHT UP by ~10.4 units (matching the 3D depth of the lid in
       isometric projection), keeping the top edge parallel to the hinge edge. */
    d: path("M 12 2.25 L 3 7.5 L 3 -2.9 L 12 -8.15 Z");
    fill: #202935;
    /* Opening transition — bouncy overshoot for the "popping open" feel */
    transition: d 0.55s cubic-bezier(0.34, 1.56, 0.64, 1),
                fill 0.4s ease;
}
.hero-section.lid-bounce .hero-logo .box-lid {
    transform: translate(0.5px, 0.5px) rotate(2deg);
    transition-duration: 0.2s;
}
/* While the lid is open and icons are clustering inside / flying out, bring the
   hero-shapes layer ABOVE the logo so the cluster is visible (it would otherwise
   render behind the box body / interior since .hero-shapes has z-index 0). */
.hero-section.suck-in .hero-shapes,
.hero-section.release .hero-shapes {
    z-index: 2 !important;
}
/* During suck-in the icons stay saturated until they "enter" the box; during
   release they start saturated (visible inside the box) and gradually fade back
   to the default background tint as they reach their scattered positions. The
   color values animate inside the iconSuck / iconRelease keyframes themselves. */
.hero-section.suck-in .hero-shapes svg {
    color: rgba(254, 192, 7, 1) !important;
}
:root.dark .hero-section.suck-in .hero-shapes svg {
    color: rgba(254, 192, 7, 1) !important;
}
/* Suck-in: scattered icons first GATHER directly above the box opening, then drop
   straight DOWN into it through the lid — they enter from the top, not slide in
   from the sides. They stay fully opaque the whole way so you watch them go in. */
.hero-section.suck-in .hero-shapes svg {
    animation: iconSuck 0.85s cubic-bezier(0.5, 0, 0.5, 1) both !important;
    animation-delay: var(--fly-delay, 0ms) !important;
    will-change: transform, opacity;
}
@keyframes iconSuck {
    0% {
        transform: translate(0, 0) scale(1) rotate(0deg);
        opacity: 1;
    }
    55% {
        /* Gathered in a tight cluster directly ABOVE the box opening */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) - 72px)) scale(0.62) rotate(70deg);
        opacity: 1;
    }
    82% {
        /* Dropping straight down (x held constant) through the opening */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) - 4px)) scale(0.34) rotate(110deg);
        opacity: 1;
    }
    100% {
        /* Sunk deep into the box and faded out — the closing lid then hides it */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) + 6px)) scale(0.16) rotate(130deg);
        opacity: 0;
    }
}
/* Box full, lid closed (after suck-in, before release): the icons are FULLY
   hidden — they're a separate layer from the logo SVG, so they can't be tucked
   "behind the lid but in front of the interior". opacity:0 is the only clean way
   to keep them from poking past the closed lid. They re-appear on release by
   emerging UP out of the opening the instant the lid pops open. */
.hero-section.icons-stored .hero-shapes svg {
    animation: none !important;
    transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) + 6px)) scale(0.16);
    opacity: 0;
}
/* Release: the icons are hidden inside the closed box. The lid pops open first
   (release() gives it a ~150ms head start), then the cluster emerges UP out of
   the opening — fading in fast (over the first 10%) WHILE rising, so it reads as
   one continuous "lid opens → tools stream out" motion with no empty-box beat.
   Phases:
     0-10%:   fast fade-in at the opening, just as the lid finishes popping
     10-34%:  cluster sits visibly inside the open box
     34-56%:  cluster rises straight up out of the opening (x held constant)
     56-100%: icons spread out + fade to the default background tint
*/
.hero-section.release .hero-shapes svg {
    animation: iconRelease 1.2s cubic-bezier(0.34, 1.4, 0.64, 1) both !important;
    animation-delay: var(--fly-delay, 0ms) !important;
}
@keyframes iconRelease {
    0% {
        /* Identical to the .icons-stored state — seamless hand-off, no jump */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) + 6px)) scale(0.16) rotate(0deg);
        opacity: 0;
        color: #fec007;
    }
    10% {
        /* Snapped into view at the opening — fast fade so there's no faint blur */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) - 2px)) scale(0.42) rotate(5deg);
        opacity: 1;
        color: #fec007;
    }
    34% {
        /* Cluster sits visibly inside the open box, grown enough to read */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) - 6px)) scale(0.5) rotate(10deg);
        opacity: 1;
        color: rgba(254, 192, 7, 1);
    }
    56% {
        /* Rises straight up out of the opening — x held at fly-x-top */
        transform: translate(var(--fly-x-top, var(--fly-x, 0px)), calc(var(--fly-y-top, 0px) - 52px)) scale(0.78) rotate(24deg);
        opacity: 1;
        color: rgba(254, 192, 7, 1);
    }
    80% {
        /* Spreading toward scattered positions — gentle fade begins */
        transform: translate(calc(var(--fly-x, 0px) * 0.4), calc(var(--fly-y, 0px) * 0.4)) scale(0.95) rotate(12deg);
        opacity: 0.9;
        color: rgba(254, 192, 7, 0.7);
    }
    100% {
        /* Fully back to scattered, faded to match the default heroFloat tint */
        transform: translate(0, 0) scale(1) rotate(0deg);
        opacity: 0.55;
        color: rgba(254, 192, 7, 0.42);
    }
}
@media (prefers-reduced-motion: reduce) {
    .hero-logo {
        animation: none;
    }
    .hero-logo .box-lid,
    .hero-section.suck-in .hero-shapes svg,
    .hero-section.release .hero-shapes svg {
        transition: none;
        animation: none !important;
    }
}

/* Hero Section */
.hero-section {
    position: relative;
    margin-top: -2.5rem;
    overflow-x: clip;
    overflow-y: visible;
}
.hero-section > * {
    position: relative;
    z-index: 1;
}
.hero-shapes {
    position: absolute !important;
    inset: 0;
    overflow-x: clip;
    overflow-y: visible;
    z-index: 0 !important;
}
.hero-shapes svg {
    position: absolute;
    display: block;
    width: var(--s);
    height: var(--s);
    left: var(--x);
    top: var(--y);
    color: rgba(254, 192, 7, 0.42);
    animation-name: heroFloat;
    animation-duration: var(--d);
    animation-delay: var(--del);
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
}
.hero-shapes svg:nth-child(3n+2) {
    animation-name: heroFloat2;
}
.hero-shapes svg:nth-child(3n) {
    animation-name: heroFloat3;
}
:root.dark .hero-shapes svg {
    color: rgba(254, 192, 7, 0.2);
}
@keyframes heroFloat {
    0%   { transform: translate(0, 0) rotate(-8deg); opacity: 0.55; }
    100% { transform: translate(2px, -32px) rotate(14deg); opacity: 1; }
}
@keyframes heroFloat2 {
    0%   { transform: translate(0, 0) rotate(10deg) scale(1); opacity: 0.5; }
    100% { transform: translate(-7px, -24px) rotate(-12deg) scale(1.06); opacity: 0.95; }
}
@keyframes heroFloat3 {
    0%   { transform: translate(0, 0) rotate(0deg); opacity: 0.6; }
    100% { transform: translate(-9px, -20px) rotate(20deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .hero-shapes svg {
        animation: none;
    }
}
@media (max-width: 480px) {
    .hero-shapes svg {
        width: calc(var(--s) * 0.5);
        height: calc(var(--s) * 0.5);
        left: min(var(--x), calc(100% - var(--s) * 0.5 - 6px));
    }
}

/* Sticky Header */
/* Pre-set body padding so the fixed header doesn't overlap content before the
   JS in header.php has run (which measures the live header height and overrides
   this). Without this, slow JS execution causes a visible content shift (CLS). */

.header-sticky {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 997;
    border-bottom: 2px solid transparent;
    transition: background-color 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, transform 0.25s ease;
}
.header-sticky.header-hidden {
    transform: translateY(-100%);
}
.header-sticky > div {
    transition: padding 0.3s ease;
}
/* Index page pre-scroll: push nav to inline-end, minimal padding */
.header-sticky:not(.header-has-title):not(.header-scrolled) nav {
    margin-inline-start: auto;
}
.header-sticky:not(.header-has-title):not(.header-scrolled) > div {
    padding-top: 0.75rem;
    padding-bottom: 0.5rem;
}
/* Index page: hide logo+title until scrolled */
.header-sticky .header-title,
.header-sticky .header-logo {
    opacity: 0;
    max-width: 0;
    max-height: 0;
    overflow: hidden;
    transition: opacity 0.3s ease, max-width 0.3s ease, max-height 0.3s ease;
}
.header-scrolled .header-title,
.header-scrolled .header-logo {
    opacity: 1;
    max-width: 300px;
    max-height: 3rem;
}
/* Non-index pages: always show logo, title and border */
.header-sticky.header-has-title .header-title,
.header-sticky.header-has-title .header-logo {
    opacity: 1;
    max-width: 300px;
    max-height: 3rem;
}
.header-sticky.header-has-title {
    background-color: var(--bg-card);
    border-bottom-color: var(--border-color);
}
.header-scrolled {
    background-color: var(--bg-card);
    border-bottom-color: var(--border-color);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
:root.dark .header-scrolled {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
/* Dark mode: index page header transparent before scroll */
:root.dark .header-sticky:not(.header-has-title):not(.header-scrolled) {
    background-color: transparent;
    border-color: transparent;
}
@media (prefers-reduced-motion: reduce) {
    .header-sticky,
    .header-sticky > div {
        transition-duration: 0.01s;
    }
}

/* Tools Picker Drawer */
.tools-picker-btn,
.header-search-btn {
    display: flex;
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-primary);
    cursor: pointer;
    transition: all 0.2s;
}
.tools-picker-btn:hover,
.header-search-btn:hover {
    background: var(--primary-accent);
    color: var(--icon-color);
}
/* Homepage header search icon — hidden until the on-page search box scrolls
   out of view behind the sticky header (JS toggles .visible). */
.header-search-btn { display: none; }
.header-search-btn.visible {
    display: flex;
    animation: headerSearchIn 0.18s ease-out;
}
@keyframes headerSearchIn {
    from { opacity: 0; transform: scale(0.85); }
    to   { opacity: 1; transform: scale(1); }
}
.tools-picker-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1001;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
}
.tools-picker-overlay.active {
    opacity: 1;
    visibility: visible;
}
.tools-picker-drawer {
    position: fixed;
    top: 0;
    inset-inline-end: 0;
    width: 360px;
    max-width: 100%;
    height: 100%;
    background: var(--bg-card);
    border-inline-start: 3px solid var(--border-color);
    z-index: 1002;
    transform: translateX(100%);
    transition: transform 0.3s ease;
    display: flex;
    flex-direction: column;
}
[dir="rtl"] .tools-picker-drawer {
    transform: translateX(-100%);
}
.tools-picker-drawer.active,
[dir="rtl"] .tools-picker-drawer.active {
    transform: translateX(0);
}
.tools-picker-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    border-bottom: 2px solid var(--border-color);
    flex-shrink: 0;
}
.tools-picker-title {
    font-weight: 700;
    color: var(--text-primary);
}
.tools-picker-close {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-card);
    color: var(--text-primary);
    cursor: pointer;
    transition: all 0.2s;
}
.tools-picker-close:hover {
    background: var(--primary-accent);
    color: var(--icon-color);
}
.tools-picker-body {
    flex: 1;
    overflow-y: auto;
    padding: 0.5rem 0.75rem 0.75rem;
}
.tools-picker-category {
    margin-top: 0.75rem;
}
.tools-picker-category:first-child {
    margin-top: 0;
}
.tools-picker-cat-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.25rem;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.tools-picker-cat-header svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}
.tools-picker-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.25rem;
}
.tools-picker-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    border-radius: 0.6rem;
    background: var(--bg-input);
    color: var(--text-primary);
    text-decoration: none;
    font-size: 0.82rem;
    font-weight: 600;
    transition: all 0.15s ease;
    min-height: 44px;
}
.tools-picker-item:hover {
    background: var(--primary-accent);
    color: #202935;
}
.tools-picker-item.is-current {
    background: color-mix(in srgb, var(--primary-accent) 20%, var(--bg-input));
    cursor: default;
    pointer-events: none;
}
.tools-picker-item-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    /* Force monochrome: icons that embed var(--primary-accent) render in item text color */
    --primary-accent: currentColor;
}
.tools-picker-item-icon svg {
    width: 20px;
    height: 20px;
}
.tools-picker-text-icon {
    font-weight: 900;
    font-size: 11px;
    line-height: 1;
}
.tools-picker-item-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.25;
    min-width: 0;
    word-break: break-word;
}
.tools-picker-see-all {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding: 0.55rem 1rem;
    border: 2px dashed var(--border-color);
    border-radius: 0.6rem;
    background: transparent;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 600;
    transition: all 0.15s ease;
}
.tools-picker-see-all:hover {
    background: var(--bg-input);
    color: var(--text-primary);
    border-style: solid;
}
.tools-picker-see-all svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* Bottom sheet on small screens */
@media (max-width: 640px) {
    .tools-picker-drawer {
        top: auto;
        inset-inline-end: 0;
        inset-inline-start: 0;
        bottom: 0;
        width: 100%;
        max-width: 100%;
        height: auto;
        max-height: 92vh;
        border-inline-start: none;
        border-top: 3px solid var(--border-color);
        border-radius: 1rem 1rem 0 0;
        transform: translateY(100%);
    }
    [dir="rtl"] .tools-picker-drawer {
        transform: translateY(100%);
    }
    .tools-picker-drawer.active,
    [dir="rtl"] .tools-picker-drawer.active {
        transform: translateY(0);
    }
}

/* Free up header space on narrow phones when the tool-picker button is present */
@media (max-width: 640px) {
    .header-sticky.header-has-title .header-title {
        font-size: 0.85rem;
        line-height: 1.45;
        white-space: normal;
        max-width: 110px;
        max-height: 3rem;
        word-break: break-word;
        overflow: hidden;
    }
}
.header-title-brand {
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .tools-picker-drawer,
    .tools-picker-overlay {
        transition-duration: 0.01s;
    }
}

/* ==========================================================================
   Tool Card Enhancements — favorite heart, popular pill, hover arrow
   ========================================================================== */
.tool-fav-btn {
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.35;
    transition: opacity 0.18s ease-out, color 0.18s ease-out, background-color 0.18s ease-out, transform 0.18s ease-out;
    flex-shrink: 0;
}
.tool-fav-btn svg { width: 16px; height: 16px; }
.tool-card:hover .tool-fav-btn,
.tool-widget:hover .tool-fav-btn,
.tool-fav-btn:hover,
.tool-fav-btn:focus-visible,
.tool-fav-btn.is-fav {
    opacity: 1;
}
@media (hover: none) {
    .tool-fav-btn { opacity: 1; }
}
.tool-fav-btn:hover {
    background: #fef2f2;
    color: #ef4444;
    transform: scale(1.15);
}
.tool-fav-btn.is-fav { color: #ef4444; }
.tool-fav-btn.is-fav svg { fill: currentColor; }
:root.dark .tool-fav-btn:hover,
:root.dark .tool-fav-btn.is-fav {
    background: transparent;
    color: #f87171;
}

.widget-badge-group {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.card-arrow {
    position: absolute;
    bottom: 12px;
    inset-inline-end: 14px;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--text-muted);
    opacity: 0;
    transform: translateX(4px);
    transition: opacity 0.25s ease-out, transform 0.25s ease-out, color 0.25s ease-out;
    line-height: 1;
    pointer-events: none;
}
[dir="rtl"] .card-arrow { transform: translateX(-4px); }
.tool-card:hover .card-arrow {
    opacity: 1;
    transform: translateX(0);
    color: var(--primary-accent);
}
.tool-card:hover { border-color: var(--primary-accent); }

/* Site-wide: slightly smaller base font on mobile so dense layouts feel
   proportionate. Subtle (1rem → 0.95rem) so we don't shrink interactive
   targets or break tool pages that hard-code sizes. */
@media (max-width: 639px) {
    html { font-size: 0.95rem; }
}

/* ==========================================================================
   Tool Editor Scaffold — shared input/output editor layout used by base64,
   code-beautifier, json-formatter, diff-checker. The responsive column count
   differs per tool, so each page keeps its own `@media` override on
   `.editor-container`; the base (single-column) grid lives here.
   ========================================================================== */
.editor-container {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}
.editor-box {
    display: flex;
    flex-direction: column;
}
.editor-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.editor-label {
    font-weight: 700;
    color: var(--text-primary);
}
.editor-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.btn-small {
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    font-weight: 600;
    border: 1px solid var(--border-color);
    border-radius: 0.375rem;
    background: var(--bg-card);
    color: var(--text-primary);
    cursor: pointer;
    transition: all 0.2s;
}
.btn-small:hover {
    background: var(--primary-accent);
}

/* ==========================================================================
   Upload drop-zone — shared dashed-border file-upload box.
   Used by image-optimizer, favicon-generator, image-to-pdf, pdf-merge.
   Tools keep their own icon / text / loading styling locally.
   The active-drag state is `.drop-zone.drag-over`.
   ========================================================================== */
.drop-zone {
    border: 2px dashed var(--border-color);
    border-radius: 1rem;
    padding: 3rem 2rem;
    text-align: center;
    cursor: pointer;
    transition: all 0.2s;
    background-color: var(--bg-card);
}
.drop-zone:hover,
.drop-zone.drag-over {
    border-color: var(--primary-accent);
    background-color: var(--bg-input);
}

/* ==========================================================================
   Drop-zone placeholder — shared file-drop target overlaid on an input.
   Used by base64, code-beautifier, code-compressor, json-formatter,
   diff-checker. Supports two label conventions: `.hint` (single line) and
   `.main-text`/`.sub-text`/`.formats-text` (multi-line).
   ========================================================================== */
.drop-zone-placeholder {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    border: 2px dashed var(--border-color);
    border-radius: 0.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    background-color: var(--bg-input);
    padding: 1rem;
    cursor: text;
}
.drop-zone-placeholder.drag-over {
    border-color: var(--primary-accent);
    background-color: var(--primary-accent);
    opacity: 0.3;
}
.drop-zone-placeholder svg {
    width: 48px;
    height: 48px;
    color: var(--text-secondary);
    opacity: 0.5;
    margin-bottom: 0.75rem;
}
.drop-zone-placeholder p {
    color: var(--text-secondary);
    margin: 0.25rem 0;
}
.drop-zone-placeholder .main-text {
    font-weight: 600;
}
.drop-zone-placeholder .sub-text {
    font-size: 0.9rem;
    opacity: 0.8;
}
.drop-zone-placeholder .formats-text {
    font-size: 0.8rem;
    opacity: 0.6;
    margin-top: 0.75rem;
}
.drop-zone-placeholder .hint {
    font-size: 0.8rem;
    opacity: 0.7;
    margin-top: 0.5rem;
}

/* ============================================================
   Shared tooltip — desktop hover, mobile tap.
   Markup:  <span class="tooltip-container">
              <chip/>
              <span class="tooltip-text">Tooltip body</span>
            </span>
   JS auto-toggle lives in footer.php (delegated click).
   ============================================================ */
.tooltip-container {
    position: relative;
    display: inline-block;
}
.tooltip-text {
    visibility: hidden;
    width: max-content;
    max-width: 240px;
    background-color: #1e293b;
    color: #fff;
    text-align: center;
    border-radius: 6px;
    padding: 8px;
    position: absolute;
    z-index: 10;
    bottom: 125%;
    left: 50%;
    transform: translateX(-50%);
    opacity: 0;
    transition: opacity 0.3s;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.6;
    pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
    .tooltip-container:hover .tooltip-text {
        visibility: visible;
        opacity: 1;
    }
}
@media (hover: none), (pointer: coarse) {
    .tooltip-text {
        max-width: min(240px, 70vw);
        white-space: normal;
    }
    .tooltip-text.show {
        visibility: visible;
        opacity: 1;
    }
}
