/* ==========================================================================
   Landing page (home) — static mock UI. Mobile first, no external requests.

   Theming: the layout writes data-theme="light|dark" on <html> before paint,
   so every token below resolves from an explicit attribute. The
   prefers-color-scheme block only covers the no-JS case.
   ========================================================================== */

:root {
    /* Surfaces */
    --lp-bg: #ffffff;
    --lp-bg-tint-a: rgba(99, 102, 241, .10);
    --lp-bg-tint-b: rgba(192, 38, 211, .08);
    --lp-surface: #ffffff;
    --lp-surface-2: #f7f8fb;
    --lp-surface-3: #eef0f6;
    --lp-header-bg: rgba(255, 255, 255, .82);
    --lp-border: #e9ebf2;
    --lp-border-2: #dfe2ec;

    /* Text */
    --lp-text: #12141c;
    --lp-text-2: #39404f;
    --lp-muted: #6b7280;
    --lp-muted-2: #9aa1ae;

    /* Brand */
    --lp-blue: #2f6bff;
    --lp-blue-2: #1d4ed8;
    --lp-violet: #7c3aed;
    --lp-fuchsia: #c026d3;
    --lp-pink: #db2777;
    --lp-green: #16a34a;
    --lp-amber: #f59e0b;

    /* Darkened variants for small text on the matching tint. The display colours
       above are too light to clear 4.5:1 at body sizes. */
    --lp-green-ink: #107a3f;
    --lp-amber-ink: #8a5200;

    --lp-grad-brand: linear-gradient(135deg, #6366f1 0%, #8b5cf6 45%, #c026d3 100%);
    --lp-grad-btn: linear-gradient(135deg, #4f5bf5 0%, #7c3aed 55%, #a21caf 100%);
    --lp-grad-head: linear-gradient(90deg, #7c3aed 0%, #b02ec9 55%, #db2777 100%);
    --lp-grad-ring: linear-gradient(120deg, #4f8bff, #8b5cf6 55%, #d946ef);

    /* Tinted icon tiles */
    --lp-tile-violet: #f0eafe;
    --lp-tile-blue: #e6efff;
    --lp-tile-green: #e3f8ec;
    --lp-tile-amber: #fdf0dc;

    /* Video thumbnail scene — sky reads top → horizon */
    --thumb-sky-top: #c6dcea;
    --thumb-sky-mid: #f8d6ac;
    --thumb-sky-low: #f2ac7d;
    --thumb-sun: #fff4d2;
    --thumb-hill-1: #86aec0;
    --thumb-hill-2: #4a7891;
    --thumb-water-1: #8ec8e2;
    --thumb-water-2: #2f6a89;
    --thumb-glow: rgba(255, 232, 180, .9);

    /* Effects */
    --lp-shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .07);
    --lp-shadow: 0 2px 6px rgba(16, 24, 40, .05), 0 12px 28px -12px rgba(16, 24, 40, .16);
    --lp-shadow-lg: 0 24px 60px -24px rgba(38, 24, 92, .30);
    --lp-glow: 0 0 0 4px rgba(124, 58, 237, .10);

    --lp-radius: 12px;
    --lp-radius-lg: 18px;
    --lp-radius-xl: 24px;

    /* Single source of truth for how wide a content row is. 1130 minus the
       container padding gives the 1090px used by the download box, and every
       section below lines up with it. */
    --lp-container: 1130px;
    --lp-font: "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system,
        "Inter", Roboto, "Helvetica Neue", Arial, sans-serif;
}

:root[data-theme="dark"] {
    --lp-bg: #05060d;
    --lp-bg-tint-a: rgba(79, 70, 229, .30);
    --lp-bg-tint-b: rgba(168, 26, 200, .20);
    --lp-surface: #0f1220;
    --lp-surface-2: #12162a;
    --lp-surface-3: #1a1f36;
    --lp-header-bg: rgba(8, 10, 20, .80);
    --lp-border: #1e2338;
    --lp-border-2: #2a3050;

    --lp-text: #f2f4fb;
    --lp-text-2: #ccd2e4;
    --lp-muted: #98a1b8;
    --lp-muted-2: #6f7893;

    --lp-blue: #6d8bff;
    --lp-blue-2: #93a8ff;
    --lp-violet: #a78bfa;
    --lp-fuchsia: #e879f9;
    --lp-pink: #f472b6;
    --lp-green: #4ade80;
    --lp-amber: #fbbf24;
    /* On dark tints the display colours already clear contrast. */
    --lp-green-ink: #4ade80;
    --lp-amber-ink: #fbbf24;

    --lp-grad-head: linear-gradient(90deg, #a78bfa 0%, #c77bf5 50%, #e879f9 100%);

    --lp-tile-violet: rgba(139, 92, 246, .16);
    --lp-tile-blue: rgba(59, 130, 246, .16);
    --lp-tile-green: rgba(34, 197, 94, .16);
    --lp-tile-amber: rgba(245, 158, 11, .16);

    --thumb-sky-top: #1d1442;
    --thumb-sky-mid: #6a3382;
    --thumb-sky-low: #c1638f;
    --thumb-sun: #ffd2a0;
    --thumb-hill-1: #40275f;
    --thumb-hill-2: #1f1440;
    --thumb-water-1: #7c4593;
    --thumb-water-2: #180f31;
    --thumb-glow: rgba(255, 175, 140, .6);

    --lp-shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
    --lp-shadow: 0 2px 8px rgba(0, 0, 0, .45), 0 18px 40px -20px rgba(0, 0, 0, .8);
    --lp-shadow-lg: 0 30px 70px -30px rgba(0, 0, 0, .9);
    --lp-glow: 0 0 0 4px rgba(139, 92, 246, .18);
}

/* No-JS fallback: follow the OS unless the user pinned light. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --lp-bg: #05060d;
        --lp-bg-tint-a: rgba(79, 70, 229, .30);
        --lp-bg-tint-b: rgba(168, 26, 200, .20);
        --lp-surface: #0f1220;
        --lp-surface-2: #12162a;
        --lp-surface-3: #1a1f36;
        --lp-header-bg: rgba(8, 10, 20, .80);
        --lp-border: #1e2338;
        --lp-border-2: #2a3050;
        --lp-text: #f2f4fb;
        --lp-text-2: #ccd2e4;
        --lp-muted: #98a1b8;
        --lp-muted-2: #6f7893;
        --lp-blue: #6d8bff;
        --lp-violet: #a78bfa;
        --lp-fuchsia: #e879f9;
        --lp-green: #4ade80;
        --lp-amber: #fbbf24;
        --lp-green-ink: #4ade80;
        --lp-amber-ink: #fbbf24;
        --lp-grad-head: linear-gradient(90deg, #a78bfa 0%, #c77bf5 50%, #e879f9 100%);
        --lp-tile-violet: rgba(139, 92, 246, .16);
        --lp-tile-blue: rgba(59, 130, 246, .16);
        --lp-tile-green: rgba(34, 197, 94, .16);
        --lp-tile-amber: rgba(245, 158, 11, .16);
        --thumb-sky-top: #1d1442;
        --thumb-sky-mid: #6a3382;
        --thumb-sky-low: #c1638f;
        --thumb-sun: #ffd2a0;
        --thumb-hill-1: #40275f;
        --thumb-hill-2: #1f1440;
        --thumb-water-1: #7c4593;
        --thumb-water-2: #180f31;
        --thumb-glow: rgba(255, 175, 140, .6);
    }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

/* The `hidden` attribute always wins.
   ----------------------------------
   HTML says a hidden element is not rendered, but that is only a default
   `display: none` — any rule that sets an explicit display silently overrides
   it. That has bitten this file three separate times: a download button hidden
   behind `display: inline-flex`, the cover image behind `display: block`, and
   the empty-state hint behind the `-webkit-box` used to clamp the meta line to
   one row. Each was patched on its own, and the next one broke the same way.

   One rule ends the class of bug. `!important` is deliberate: nothing should
   ever out-rank a request to not show an element. */
[hidden] { display: none !important; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body.lp {
    margin: 0;
    min-height: 100vh;
    background: var(--lp-bg);
    color: var(--lp-text);
    font-family: var(--lp-font);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    display: flex;
    flex-direction: column;
    overflow-x: hidden;
}

/* Ambient colour wash behind the hero, matching the mock's soft corner glows. */
body.lp::before {
    content: "";
    position: fixed;
    inset: -20% -10% auto -10%;
    height: 900px;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(46% 42% at 22% 18%, var(--lp-bg-tint-a), transparent 70%),
        radial-gradient(46% 42% at 78% 14%, var(--lp-bg-tint-b), transparent 70%);
}

/* Set while the loading overlay is up, so the page behind it cannot scroll. */
body.lp-locked { overflow: hidden; }

img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }

a {
    color: inherit;
    text-decoration: none;
}

:focus-visible {
    outline: 2px solid var(--lp-violet);
    outline-offset: 2px;
    border-radius: 6px;
}

.lp-container {
    width: 100%;
    max-width: var(--lp-container);
    margin-inline: auto;
    padding-inline: 20px;
}

/* Chrome sits wider than the content rows, as in the mock. */
.lp-header .lp-container,
.lp-footer .lp-container { max-width: 1240px; }

.lp-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--lp-surface);
    color: var(--lp-text);
    padding: 10px 16px;
    border-radius: 8px;
}
.lp-skip:focus { left: 12px; top: 12px; }

.lp-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.lp-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--lp-header-bg);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--lp-border);
}

.lp-header-inner {
    display: flex;
    align-items: center;
    gap: 16px;
    height: 72px;
}

.lp-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
    margin-right: auto;
}

.lp-brand-mark {
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
    border-radius: 13px;
    background: var(--lp-grad-brand);
    color: #fff;
    display: grid;
    place-items: center;
    box-shadow: 0 6px 16px -6px rgba(124, 58, 237, .7);
}

/*
 * An uploaded logo replaces the gradient mark and the wordmark both — that is
 * what Settings → Thương hiệu promises. Height is fixed so any aspect ratio
 * lines up with the 72px header; width follows the image.
 */
.lp-brand-logo {
    height: 40px;
    width: auto;
    max-width: 200px;
    display: block;
    object-fit: contain;
}

/* Only present when a separate dark-theme logo was uploaded. */
.lp-brand-logo-dark { display: none; }

:root[data-theme="dark"] .lp-brand-logo-light { display: none; }
:root[data-theme="dark"] .lp-brand-logo-dark { display: block; }

.lp-footer .lp-brand-logo { height: 36px; }

.lp-brand-text { display: flex; flex-direction: column; line-height: 1.1; }

.lp-brand-name {
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -.02em;
}

.lp-brand-tag {
    font-size: 12px;
    color: var(--lp-muted);
    letter-spacing: .01em;
}

.lp-nav ul {
    display: flex;
    align-items: center;
    gap: 6px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.lp-nav a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 15px;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 500;
    color: var(--lp-text-2);
    transition: background-color .15s ease, color .15s ease;
}

.lp-nav a:hover { background: var(--lp-surface-2); color: var(--lp-text); }

/* Menu labels are page titles, so their length is an editing decision. Cap and
   ellipsis them here rather than letting a long one wrap the header onto two
   lines or push the actions off the end. */
.lp-nav-label {
    display: block;
    max-width: 15ch;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.lp-nav a[aria-current="page"] {
    background: color-mix(in srgb, var(--lp-blue) 12%, transparent);
    color: var(--lp-blue);
    font-weight: 600;
}

/* "Xem thêm" dropdown ----------------------------------------------------- */

.lp-nav-item { position: relative; }

.lp-nav-trigger {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 9px 15px;
    border: 0;
    border-radius: 10px;
    background: none;
    font-size: 15px;
    font-weight: 500;
    color: var(--lp-text-2);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.lp-nav-trigger:hover { background: var(--lp-surface-2); color: var(--lp-text); }
.lp-nav-trigger .lp-caret { transition: transform .18s ease; }
.lp-nav-trigger[aria-expanded="true"] { background: var(--lp-surface-2); color: var(--lp-violet); }
.lp-nav-trigger[aria-expanded="true"] .lp-caret { transform: rotate(180deg); }

.lp-menu {
    position: absolute;
    /* Clears the 72px header rather than the 42px trigger, so the panel starts
       just below the header's bottom border instead of overlapping it. */
    top: calc(100% + 17px);
    left: 50%;
    transform: translateX(-50%);
    width: 520px;
    max-width: calc(100vw - 32px);
    padding: 10px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: 16px;
    box-shadow: var(--lp-shadow-lg), var(--lp-shadow);
    display: none;
}

:root[data-theme="dark"] .lp-menu { background: #121628; }

.lp-menu[data-open="true"] { display: block; }

.lp-menu-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
}

.lp-menu-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px;
    border-radius: 11px;
    transition: background-color .15s ease;
}

.lp-menu-item:hover { background: var(--lp-surface-2); }
:root[data-theme="dark"] .lp-menu-item:hover { background: rgba(255, 255, 255, .05); }

.lp-menu-icon {
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    display: grid;
    place-items: center;
    border-radius: 10px;
}

.lp-menu-text { min-width: 0; line-height: 1.3; }

.lp-menu-text strong {
    display: block;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--lp-text);
}

.lp-menu-text span { font-size: 12.5px; color: var(--lp-muted); }

/* Platform mark beside a tool entry. Sized down from the 36–38px marks the
   platform strip uses, so it reads as a label icon rather than a logo. */
.lp-nav-icon {
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
}

.lp-nav-icon > svg { width: 100%; height: auto; }

.lp-header-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    margin-left: auto;
}

.lp-icon-btn {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--lp-border-2);
    border-radius: 12px;
    background: var(--lp-surface);
    color: var(--lp-text-2);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.lp-icon-btn:hover {
    background: var(--lp-surface-2);
    border-color: var(--lp-violet);
    color: var(--lp-violet);
}

/* Only one of the two glyphs shows, depending on the active theme. */
.lp-theme-toggle .lp-icon-moon { display: none; }
:root[data-theme="dark"] .lp-theme-toggle .lp-icon-sun { display: none; }
:root[data-theme="dark"] .lp-theme-toggle .lp-icon-moon { display: block; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .lp-theme-toggle .lp-icon-sun { display: none; }
    :root:not([data-theme="light"]) .lp-theme-toggle .lp-icon-moon { display: block; }
}

.lp-lang { position: relative; }

.lp-lang-btn,
.lp-login {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    padding: 0 16px;
    border: 1px solid var(--lp-border-2);
    border-radius: 12px;
    background: var(--lp-surface);
    color: var(--lp-text-2);
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.lp-lang-btn:hover,
.lp-login:hover {
    background: var(--lp-surface-2);
    border-color: var(--lp-violet);
    color: var(--lp-violet);
}

.lp-lang-btn .lp-caret { transition: transform .18s ease; }
.lp-lang-btn[aria-expanded="true"] .lp-caret { transform: rotate(180deg); }

.lp-lang-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 168px;
    padding: 6px;
    margin: 0;
    list-style: none;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: 14px;
    box-shadow: var(--lp-shadow);
    display: none;
}

.lp-lang-menu[data-open="true"] { display: block; }

.lp-lang-menu a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: 9px;
    font-size: 14px;
    color: var(--lp-text-2);
}

.lp-lang-menu a:hover { background: var(--lp-surface-2); }
.lp-lang-menu a[aria-current="true"] { color: var(--lp-violet); font-weight: 600; }

.lp-burger { display: none; }

/* Mobile drawer */
.lp-mobile-nav {
    display: none;
    border-top: 1px solid var(--lp-border);
    background: var(--lp-surface);
    padding: 10px 0 16px;
}

.lp-mobile-nav[data-open="true"] { display: block; }

.lp-mobile-nav ul {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
    display: grid;
    gap: 2px;
}

.lp-mobile-nav a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-radius: 10px;
    font-weight: 500;
    color: var(--lp-text-2);
}

.lp-mobile-nav .lp-nav-icon { width: 24px; height: 24px; flex-basis: 24px; }

/* "Xem thêm" group in the drawer — a <details>, so it folds without JavaScript. */
.lp-mobile-group summary {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 12px 14px;
    border-radius: 10px;
    font-weight: 500;
    color: var(--lp-text-2);
    cursor: pointer;
    list-style: none;
}

.lp-mobile-group summary::-webkit-details-marker { display: none; }
.lp-mobile-group summary .lp-caret { margin-left: auto; transition: transform .18s ease; }
.lp-mobile-group[open] summary { color: var(--lp-violet); }
.lp-mobile-group[open] summary .lp-caret { transform: rotate(180deg); }

.lp-mobile-group ul {
    margin: 2px 0 6px;
    padding-left: 10px;
    border-left: 2px solid var(--lp-border);
}

/* Scoped under .lp-mobile-nav so it outranks the generic `.lp-mobile-nav a`
   rule above, which sets its own padding and font weight. */
.lp-mobile-nav .lp-mobile-tool {
    gap: 10px;
    padding: 8px 10px;
    font-size: 14.5px;
}

.lp-mobile-tool .lp-menu-icon { width: 32px; height: 32px; flex-basis: 32px; border-radius: 9px; }

.lp-mobile-nav a[aria-current="page"] {
    background: color-mix(in srgb, var(--lp-blue) 12%, transparent);
    color: var(--lp-blue);
}

/*
 * Language picker inside the drawer. The header-bar one is hidden below 880px
 * and this is its replacement, so a phone can still switch language.
 */
.lp-mobile-langs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
    padding-top: 14px;
    border-top: 1px solid var(--lp-border);
}

/* `.lp-mobile-nav a` sets display:flex and full-width padding; these are chips. */
.lp-mobile-nav .lp-mobile-langs a {
    display: inline-flex;
    padding: 9px 16px;
    border: 1px solid var(--lp-border-2);
    border-radius: 999px;
    font-size: 14.5px;
}

.lp-mobile-nav .lp-mobile-langs a[aria-current="true"] {
    border-color: var(--lp-violet);
    background: var(--lp-tile-violet);
    color: var(--lp-violet);
    font-weight: 600;
}

.lp-mobile-nav-foot { display: flex; gap: 10px; }

/* `.lp-mobile-nav a` above is more specific than `.lp-login`, so it would
   otherwise force display:block here and drop the label out of the button. */
.lp-mobile-nav-foot .lp-login {
    display: inline-flex;
    flex: 1;
    justify-content: center;
    padding: 0 16px;
    border-radius: 12px;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.lp-main { flex: 1; }

.lp-hero {
    padding: 44px 0 8px;
    text-align: center;
}

.lp-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 20px;
    border-radius: 999px;
    background: var(--lp-surface-3);
    border: 1px solid var(--lp-border);
    font-size: 15px;
    font-weight: 500;
    color: var(--lp-text-2);
}

:root[data-theme="dark"] .lp-badge { background: rgba(255, 255, 255, .05); }

.lp-title {
    margin: 22px 0 0;
    font-size: clamp(1.75rem, 4.2vw, 3.15rem);
    font-weight: 800;
    line-height: 1.14;
    letter-spacing: -.03em;
}

.lp-title .lp-word-blue { color: var(--lp-blue); }

.lp-title .lp-word-grad {
    background: var(--lp-grad-head);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.lp-subtitle {
    margin: 14px auto 0;
    max-width: 720px;
    font-size: clamp(1rem, 1.4vw, 1.125rem);
    color: var(--lp-muted);
}

/* Download form ---------------------------------------------------------- */

.lp-download {
    margin: 30px auto 0;
    padding: 3px;
    border-radius: var(--lp-radius-xl);
    background: var(--lp-grad-ring);
    box-shadow: var(--lp-shadow-lg);
}

:root[data-theme="dark"] .lp-download {
    box-shadow: 0 0 34px -6px rgba(124, 58, 237, .55), 0 0 70px -20px rgba(59, 130, 246, .45);
}

.lp-download-inner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border-radius: 21px;
    background: var(--lp-surface);
}

.lp-field {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    padding-left: 12px;
    color: var(--lp-muted-2);
}

.lp-field input {
    flex: 1;
    min-width: 0;
    height: 48px;
    border: 0;
    background: none;
    color: var(--lp-text);
    font-family: inherit;
    font-size: 17px;
}

.lp-field input::placeholder { color: var(--lp-muted-2); }
.lp-field input:focus { outline: none; }

.lp-paste {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 48px;
    padding: 0 20px;
    border: 1px solid var(--lp-border-2);
    border-radius: 12px;
    background: var(--lp-surface);
    color: var(--lp-text-2);
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color .15s ease, border-color .15s ease;
}

.lp-paste:hover { background: var(--lp-surface-2); border-color: var(--lp-violet); }

.lp-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    height: 56px;
    padding: 0 34px;
    border: 0;
    border-radius: 14px;
    background: var(--lp-grad-btn);
    color: #fff;
    font-size: 17px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    box-shadow: 0 10px 24px -10px rgba(124, 58, 237, .85);
    transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}

.lp-cta:hover {
    transform: translateY(-1px);
    filter: brightness(1.05);
    box-shadow: 0 14px 30px -10px rgba(124, 58, 237, .95);
}

.lp-cta:active { transform: translateY(0); }

/* Platform strip --------------------------------------------------------- */

.lp-platforms {
    margin: 14px auto 0;
    padding: 16px 10px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-platforms { background: rgba(255, 255, 255, .03); }

.lp-platform-track {
    display: flex;
    align-items: flex-start;
    gap: 4px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}

.lp-platform-track::-webkit-scrollbar { display: none; }

.lp-platform {
    flex: 1 0 auto;
    min-width: 104px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 8px 6px;
    border-radius: 12px;
    font-size: 14px;
    color: var(--lp-text-2);
    transition: background-color .15s ease, transform .15s ease;
}

.lp-platform:hover {
    background: var(--lp-surface-2);
    transform: translateY(-2px);
}

.lp-platform-icon {
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
}

.lp-platform-more .lp-platform-icon {
    border: 1px dashed var(--lp-border-2);
    border-radius: 50%;
    color: var(--lp-muted);
}

.lp-dots {
    display: none;
    justify-content: center;
    gap: 6px;
    padding-top: 12px;
}

.lp-dot {
    width: 22px;
    height: 4px;
    border-radius: 999px;
    background: var(--lp-border-2);
    border: 0;
    padding: 0;
    cursor: pointer;
}

.lp-dot[aria-current="true"] { background: var(--lp-violet); }

/* --------------------------------------------------------------------------
   Result card — video summary on top, format list below.

   Shaped like the result panel of a real downloader rather than a hero-sized
   player: the block is a demo, so the format rows (and their download buttons)
   are what deserve the space.
   -------------------------------------------------------------------------- */

/* padding-block, not the shorthand: this section IS the .lp-container, so a
   `padding: x 0` here would wipe out its inline padding and make the row wider
   than every other section. */
.lp-result-wrap { padding-block: 30px 0; }

/* Focused tools from one platform, such as Instagram Reels and Story.
   ------------------------------------------------------------------
   This was a full-bleed band sitting BELOW the hero — a navigation bar wedged
   between the download form and the result panel, and a gradient running the
   whole width of the window while every other element stopped at the
   container. It now renders inside the hero's container, above the headline it
   qualifies, so the background ends where the page content ends. */
.lp-tool-tabs {
    /* 70% of the container, centred. Narrower than the headline on purpose:
       it is a filter on this page, not a peer of the download form. */
    width: 70%;
    max-width: 100%;
    margin: 0 auto 18px;
    border-radius: 12px;
    /* The gradient no longer bleeds, so it needs its own corners clipping. */
    overflow: hidden;
    background: linear-gradient(100deg, #a728e8, #d24dc4);
    box-shadow: 0 10px 24px -18px rgba(167, 40, 232, .9);
}

.lp-tool-tabs-track {
    display: flex;
    overflow-x: auto;
    scrollbar-width: thin;
}

/* The first and last pills round with the bar rather than squaring off inside
   its clipped corners. */
.lp-tool-tabs-track > :first-child { border-start-start-radius: 12px; border-end-start-radius: 12px; }
.lp-tool-tabs-track > :last-child  { border-inline-end: 0; }

.lp-tool-tab {
    display: inline-flex;
    /* Fill the bar between them rather than clumping in the middle: at 70%
       width there is no leftover gradient for centred pills to float in.
       flex-basis: auto, not 0 — an exact seven-way split gave every tab 109px
       and truncated "Carousel" to "Caro…", while the labels together need only
       308px of the 763 available. Each tab takes the room its own label needs
       and then shares what is left, so the bar still fills and nothing is cut. */
    flex: 1 1 auto;
    align-items: center;
    justify-content: center;
    gap: 9px;
    min-height: 50px;
    padding: 0 14px;
    border-right: 1px solid rgba(255, 255, 255, .24);
    background: rgba(255, 255, 255, .13);
    color: #fff;
    font-size: 16px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

/* A last-resort guard: with flex-basis: auto nothing should truncate at this
   width, but a much longer label on a future tool must still not push the bar
   past its 70% or wrap it onto a second line. */
.lp-tool-tab > span {
    overflow: hidden;
    text-overflow: ellipsis;
}

.lp-tool-tab svg { flex: 0 0 auto; }

.lp-tool-tab:first-child { border-radius: 7px 0 0 7px; }
.lp-tool-tab:last-child { border-right: 0; border-radius: 0 7px 7px 0; }

.lp-tool-tab:hover,
.lp-tool-tab:focus-visible,
.lp-tool-tab.is-active { background: rgba(255, 255, 255, .29); color: #fff; }
.lp-tool-tab:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }

.lp-result {
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow);
    overflow: hidden;
}

:root[data-theme="dark"] .lp-result { background: rgba(255, 255, 255, .03); }

/* Head: thumbnail + what was found -------------------------------------- */

.lp-result-head {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 16px;
}

.lp-result-head[hidden] { display: none; }
.lp-result-head[hidden] + .lp-formats { border-top: 0; }

.lp-thumb {
    position: relative;
    flex: 0 0 200px;
    width: 200px;
    aspect-ratio: 16 / 9;
    border-radius: 10px;
    overflow: hidden;
    background: var(--thumb-water-2);
}

.lp-thumb-scene { width: 100%; height: 100%; object-fit: cover; }

/* The real cover image, laid over the placeholder drawing. Sized identically so
   the panel does not jump when the lookup returns. */
.lp-thumb-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    background: var(--thumb-water-2);
}

/* An explicit display beats the `hidden` attribute, so without this the image
   would sit over the placeholder before there is anything to show. */

.lp-badge-4k {
    position: absolute;
    top: 7px;
    left: 7px;
    display: grid;
    justify-items: center;
    padding: 3px 7px 2px;
    border-radius: 6px;
    background: #f5c518;
    color: #17140a;
    line-height: 1.05;
    font-weight: 800;
}

.lp-badge-4k b { font-size: 14px; letter-spacing: -.02em; }
.lp-badge-4k span { font-size: 7px; letter-spacing: .08em; }

.lp-thumb-time {
    position: absolute;
    right: 6px;
    bottom: 6px;
    padding: 2px 6px;
    border-radius: 5px;
    background: rgba(0, 0, 0, .78);
    color: #fff;
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
}

.lp-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(15, 12, 30, .58);
    color: #fff;
    /* Deliberately not `cursor: pointer`, and no hover growth: this marks the
       cover image as video, it is not something to press. It was a real button
       wired to nothing, and the pointer cursor was the part that made that a
       lie rather than merely useless. */
    pointer-events: none;
    backdrop-filter: blur(3px);
}

.lp-result-meta { min-width: 0; }

/* Clamped, because this field is a label and the API does not treat it as one.
   A tweet arrives with its entire body as the "title" — 302 characters in
   testing — which spilled past the thumbnail and pushed the format list down
   the page. Two lines identify the result; the rest is not what the panel is
   for. `title` carries the full text for anyone who wants it. */
.lp-result-meta h3 {
    margin: 0 0 6px;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -.015em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    /* Titles arrive from a third party and may be one unbroken string. */
    overflow-wrap: anywhere;
}

.lp-result-meta p {
    margin: 0;
    font-size: 14px;
    color: var(--lp-muted);
    display: -webkit-box;
    -webkit-line-clamp: 1;
    line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Format list ------------------------------------------------------------ */

.lp-formats { border-top: 1px solid var(--lp-border); }

.lp-formats-title {
    margin: 0;
    padding: 11px 16px;
    background: var(--lp-surface-2);
    border-bottom: 1px solid var(--lp-border);
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--lp-muted);
}

:root[data-theme="dark"] .lp-formats-title { background: rgba(255, 255, 255, .03); }

.lp-format-list:not([hidden]) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.lp-format-list[data-single="true"] { grid-template-columns: 1fr; }
.lp-format-list .lp-format:nth-child(odd) { border-right: 1px solid var(--lp-border); }
.lp-format-list[data-single="true"] .lp-format { border-right: 0; }

.lp-format {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--lp-border);
    transition: background-color .15s ease;
}

.lp-format:hover { background: var(--lp-surface-2); }
:root[data-theme="dark"] .lp-format:hover { background: rgba(255, 255, 255, .03); }

/* Container/codec chip, so the row is scannable before reading the label. */
.lp-format-tag {
    flex: 0 0 auto;
    min-width: 48px;
    padding: 5px 8px;
    border-radius: 7px;
    background: var(--lp-tile-violet);
    color: var(--lp-violet);
    text-align: center;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .03em;
}

.lp-format[data-kind="audio"] .lp-format-tag {
    background: var(--lp-tile-green);
    color: var(--lp-green-ink);
}

.lp-format-meta { flex: 1; min-width: 0; line-height: 1.35; }
.lp-format-meta strong { display: block; font-size: 15px; font-weight: 600; }
.lp-format-meta span { font-size: 13px; color: var(--lp-muted); }

.lp-format-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    border-radius: 999px;
    background: var(--lp-tile-amber);
    color: var(--lp-amber-ink);
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}

/* Every row is a real action, so every button is filled — the recommended one
   leads with the brand gradient rather than being the only one that looks live. */
.lp-format-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-width: 126px;
    height: 40px;
    padding: 0 18px;
    border: 0;
    border-radius: 10px;
    background: color-mix(in srgb, var(--lp-violet) 13%, transparent);
    color: var(--lp-violet);
    font-size: 14.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, filter .15s ease, transform .15s ease;
}

.lp-format-btn:hover {
    background: color-mix(in srgb, var(--lp-violet) 22%, transparent);
    transform: translateY(-1px);
}

.lp-format[data-recommended="true"] .lp-format-btn {
    background: var(--lp-grad-btn);
    color: #fff;
    box-shadow: 0 8px 18px -9px rgba(124, 58, 237, .95);
}

.lp-format[data-recommended="true"] .lp-format-btn:hover {
    background: var(--lp-grad-btn);
    filter: brightness(1.07);
}

/* An explicit display value beats the `hidden` attribute, so a hidden button
   would otherwise stay on screen. Both controls ship in every cloned row and
   landing.js hides the one the format does not need — without this rule the
   reader sees an empty link sitting next to the real one. */

/* The capability list shown before anything is pasted: it describes what the
   tool produces, so its buttons are inert until there is a file behind them. */
.lp-format-btn:disabled {
    opacity: .55;
    cursor: default;
    transform: none;
}

.lp-format-btn:disabled:hover {
    background: color-mix(in srgb, var(--lp-violet) 13%, transparent);
    transform: none;
    filter: none;
}

.lp-format[data-recommended="true"] .lp-format-btn:disabled:hover {
    background: var(--lp-grad-btn);
}

/* The download row is an anchor, not a button; it inherits none of the button
   defaults a browser would have given it. */
a.lp-format-btn { text-decoration: none; }

.lp-formats-note {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--lp-surface-2);
    font-size: 13px;
    line-height: 1.45;
    color: var(--lp-muted);
}

:root[data-theme="dark"] .lp-formats-note { background: rgba(255, 255, 255, .03); }
.lp-formats-note svg { flex: 0 0 auto; color: var(--lp-green-ink); }

/* Photo grid ---------------------------------------------------------------
   A carousel comes back as four items and a Xiaohongshu post as eighteen. As
   rows that is eighteen identical lines reading "JPG HD"; as thumbnails it is
   a thing a reader can actually choose from. Four across at every width, so
   a tile is always the same share of the panel and a reader learns one shape. */
.lp-grid {
    display: grid;
    /* Exactly four across. auto-fill used to decide the count from whatever
       width was going, so the same eighteen-photo post laid out eight-across
       on a desktop and three on a laptop — the tiles were never the size the
       design assumed, and at eight-across too small to judge a photo by. */
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--lp-border);
}

.lp-grid-item {
    position: relative;
    display: block;
    /* Square tiles: the source images are every shape, and a ragged grid reads
       as broken rather than as varied. */
    aspect-ratio: 1;
    border-radius: 11px;
    overflow: hidden;
    background: var(--lp-surface-2);
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease;
}

.lp-grid-item:hover,
.lp-grid-item:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px -12px rgba(15, 23, 42, .55);
}

.lp-grid-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* A thumbnail the CDN refuses to serve leaves an empty tile rather than a
   browser's broken-image glyph. Xiaohongshu's image CDN answers 404 for the
   URLs its own API returns, so this is the ordinary case, not a rare one. */
.lp-grid-item img:not([src]) { visibility: hidden; }

.lp-grid-item[data-thumb-failed] {
    background:
        repeating-linear-gradient(
            45deg,
            var(--lp-surface-2) 0 8px,
            color-mix(in srgb, var(--lp-border) 45%, transparent) 8px 16px
        );
}

.lp-grid-index {
    position: absolute;
    top: 7px;
    left: 7px;
    min-width: 20px;
    padding: 2px 6px;
    border-radius: 6px;
    background: rgba(15, 23, 42, .62);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}

/* Always visible, never hover-only: a phone has no hover, and on a phone this
   is the only affordance saying the tile is a download. */
.lp-grid-save {
    position: absolute;
    right: 7px;
    bottom: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(15, 23, 42, .62);
    color: #fff;
    transition: background-color .15s ease;
}

.lp-grid-item:hover .lp-grid-save { background: var(--lp-violet); }

@media (max-width: 640px) {
    .lp-grid {
        /* Still four; only the gap and padding tighten. */
        gap: 8px;
        padding: 12px;
    }
}



/* Each tile spins while its own picture is on its way.
   ---------------------------------------------------
   The tiles fetch the real file now, not a shared thumbnail, so they are
   heavier and arrive one by one — a grid of eighteen filled in visibly over
   several seconds with nothing to say it was working. A pseudo-element rather
   than another node: there is one per tile and they carry no meaning of their
   own. */
.lp-grid-item[data-loading]::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    border: 2.5px solid color-mix(in srgb, var(--lp-muted) 30%, transparent);
    border-top-color: var(--lp-violet);
    border-radius: 50%;
    animation: lp-spin .7s linear infinite;
    /* Under the download button, above the (still empty) picture. */
    z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
    .lp-grid-item[data-loading]::after { animation: none; opacity: .8; }
}

/* The tile's own controls -------------------------------------------------- */

/* Covers the whole tile. Transparent — the picture underneath IS the button;
   this only gives it a target, a focus ring and a keyboard stop. */
.lp-grid-open {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    padding: 0;
    background: transparent;
    cursor: zoom-in;
}

.lp-grid-open:focus-visible {
    outline: 2px solid var(--lp-violet);
    outline-offset: -2px;
    border-radius: 11px;
}

/* Above the tile button, or pressing the corner would open the viewer instead
   of downloading. */
.lp-grid-save { z-index: 2; }

/* Loading spinner ---------------------------------------------------------- */

/* Shown over the cover image while it is being fetched. Some of these CDNs
   take several seconds; without this the panel showed its placeholder drawing
   the whole time, which reads as "here is the picture" rather than "waiting". */
.lp-thumb-spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    border: 3px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: lp-spin .7s linear infinite;
    z-index: 3;
}

@keyframes lp-spin { to { transform: rotate(360deg); } }

/* Reduced motion: a steady ring rather than nothing, so the state is still
   visible to someone who has asked animation to stop. */
@media (prefers-reduced-motion: reduce) {
    .lp-thumb-spinner { animation: none; opacity: .8; }
}

/* Image viewer ------------------------------------------------------------- */

.lp-gallery {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: grid;
    place-items: center;
}

.lp-gallery-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(8, 6, 18, .88);
    backdrop-filter: blur(3px);
}

.lp-gallery-stage {
    position: relative;
    margin: 0;
    max-width: min(92vw, 1100px);
    max-height: 82vh;
    display: grid;
    place-items: center;
}

.lp-gallery-stage img {
    max-width: min(92vw, 1100px);
    /* Bounded by the viewport, never by the picture: a 4000px original must
       not push the controls off screen. */
    max-height: 82vh;
    width: auto;
    height: auto;
    border-radius: 10px;
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, .9);
}

.lp-gallery-btn {
    position: absolute;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .14);
    color: #fff;
    cursor: pointer;
    transition: background-color .15s ease;
}

.lp-gallery-btn:hover,
.lp-gallery-btn:focus-visible { background: rgba(255, 255, 255, .3); }
.lp-gallery-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.lp-gallery-close { top: 18px; right: 18px; }
.lp-gallery-prev  { left: 18px; top: 50%; transform: translateY(-50%); }
.lp-gallery-next  { right: 18px; top: 50%; transform: translateY(-50%); }

/* Hidden rather than disabled when there is only one image: a control that
   cannot do anything is better absent than greyed. */
.lp-gallery-btn[hidden] { display: none; }

.lp-gallery-count {
    position: absolute;
    top: 22px;
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    padding: 5px 12px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .14);
    color: #fff;
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
}

/* On the picture's own bottom-right corner, not the window's.
   ----------------------------------------------------------
   It used to be centred at the bottom of the viewport. With the stage up to
   82vh tall and portrait photos far narrower than the screen, that put the
   button a long way from the image it belonged to — on a wide monitor it sat
   under empty backdrop. Anchored to the figure, it stays on the photo at
   every aspect ratio. */
.lp-gallery-download {
    position: absolute;
    right: 14px;
    bottom: 14px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 18px;
    border-radius: 21px;
    background: var(--lp-grad-btn);
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 8px 22px -8px rgba(0, 0, 0, .85);
}

.lp-gallery-download:hover { filter: brightness(1.08); }
.lp-gallery-download:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (max-width: 640px) {
    .lp-gallery-btn { width: 40px; height: 40px; }
    .lp-gallery-close { top: 12px; right: 12px; }
    .lp-gallery-prev { left: 8px; }
    .lp-gallery-next { right: 8px; }
    .lp-gallery-stage img { max-width: 94vw; max-height: 70vh; }
    .lp-gallery-download { right: 10px; bottom: 10px; height: 38px; padding: 0 14px; font-size: 14px; }
}

/* Section headings --------------------------------------------------------- */

.lp-section-head {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 0 0 20px;
    text-align: center;
}

.lp-section-head h2 {
    margin: 0;
    font-size: clamp(1.2rem, 1.9vw, 1.5rem);
    font-weight: 700;
    letter-spacing: -.02em;
}

.lp-section-head .lp-accent { color: var(--lp-blue); }

.lp-section-lead {
    margin: -10px auto 22px;
    max-width: 640px;
    text-align: center;
    font-size: 15px;
    color: var(--lp-muted);
}

/* Features ---------------------------------------------------------------- */

.lp-features-wrap { padding-block: 36px 0; }

.lp-feature-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 18px;
}

.lp-feature {
    padding: 20px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
    transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}

:root[data-theme="dark"] .lp-feature { background: rgba(255, 255, 255, .03); }

.lp-feature:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--lp-violet) 45%, transparent);
    box-shadow: var(--lp-shadow);
}

.lp-feature-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 12px;
}

.lp-feature-icon {
    width: 46px;
    height: 46px;
    flex: 0 0 46px;
    display: grid;
    place-items: center;
    border-radius: 12px;
}

.lp-feature h3 {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
}

.lp-feature p {
    margin: 0;
    font-size: 14.5px;
    color: var(--lp-muted);
    line-height: 1.55;
}

/* Tint variants used by both feature and stat icon tiles. */
.lp-tile-violet { background: var(--lp-tile-violet); color: var(--lp-violet); }
.lp-tile-blue { background: var(--lp-tile-blue); color: var(--lp-blue); }
.lp-tile-green { background: var(--lp-tile-green); color: var(--lp-green); }
.lp-tile-amber { background: var(--lp-tile-amber); color: var(--lp-amber); }

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */

.lp-stats-wrap { padding: 26px 0 40px; }

/*
 * Separate cards, like the feature grid directly above, rather than four cells
 * crammed into one bordered slab. The slab had no gaps, so the numbers ran into
 * each other and the whole bar read as a table — and it forced every cell to be
 * a quarter of the width no matter how long the number inside was.
 */
.lp-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 18px;
}

.lp-stat {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
    padding: 20px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-stat { background: rgba(255, 255, 255, .03); }

.lp-stat-icon {
    width: 52px;
    height: 52px;
    flex: 0 0 52px;
    display: grid;
    place-items: center;
    border-radius: 14px;
}

.lp-stat-value {
    display: block;
    font-size: clamp(1.15rem, 1.7vw, 1.55rem);
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
}

.lp-stat-label { display: block; font-size: 14px; color: var(--lp-muted); line-height: 1.4; }

.lp-stat-violet .lp-stat-value { color: var(--lp-violet); }
.lp-stat-blue .lp-stat-value { color: var(--lp-blue); }
.lp-stat-green .lp-stat-value { color: var(--lp-green); }
.lp-stat-amber .lp-stat-value { color: var(--lp-amber); }

/* --------------------------------------------------------------------------
   SEO copy — collapsed to a teaser, expanded by the read-more button
   -------------------------------------------------------------------------- */

.lp-seo { padding: 8px 0 44px; }

.lp-seo-card {
    padding: 30px 32px 24px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-seo-card { background: rgba(255, 255, 255, .03); }

.lp-seo h2 {
    margin: 0 0 12px;
    font-size: clamp(1.2rem, 1.9vw, 1.5rem);
    font-weight: 700;
    letter-spacing: -.02em;
}

/* The card spans the full content row like every other section, but the prose
   inside stops at a readable measure rather than running the whole 1090px. */
.lp-seo-lead,
.lp-seo-body p,
.lp-seo-body ul,
.lp-seo-body ol,
.lp-faq-answer { max-width: 88ch; }

.lp-seo-lead {
    margin: 0;
    font-size: 16px;
    color: var(--lp-text-2);
}

/* The clip is height-based so the teaser ends mid-paragraph, hinting at more. */
.lp-seo-body {
    position: relative;
    margin-top: 20px;
    max-height: 190px;
    overflow: hidden;
    transition: max-height .35s ease;
}

.lp-seo-body::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 90px;
    pointer-events: none;
    background: linear-gradient(to bottom, transparent, var(--lp-surface) 92%);
    transition: opacity .25s ease;
}

:root[data-theme="dark"] .lp-seo-body::after {
    background: linear-gradient(to bottom, transparent, #0f1220 92%);
}

.lp-seo[data-expanded="true"] .lp-seo-body { max-height: 3000px; }
.lp-seo[data-expanded="true"] .lp-seo-body::after { opacity: 0; }

/* h2/h4 as well as h3: this block also renders editor HTML from the page body,
   which uses whatever heading levels the author picked. */
.lp-seo-body h2,
.lp-seo-body h3,
.lp-seo-body h4 {
    margin: 22px 0 8px;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
}

.lp-seo-body h2 { font-size: 19px; }
.lp-seo-body > :first-child { margin-top: 0; }

.lp-seo-body a { color: var(--lp-violet); text-decoration: underline; }
.lp-seo-body img { border-radius: var(--lp-radius); margin: 4px 0 16px; }

.lp-seo-body blockquote {
    margin: 0 0 14px;
    padding: 2px 0 2px 16px;
    border-left: 3px solid var(--lp-violet);
    color: var(--lp-muted);
}

.lp-seo-body p {
    margin: 0 0 12px;
    font-size: 15.5px;
    line-height: 1.72;
    color: var(--lp-muted);
}

.lp-seo-body ul,
.lp-seo-body ol {
    margin: 0 0 14px;
    padding-left: 22px;
    font-size: 15.5px;
    line-height: 1.72;
    color: var(--lp-muted);
}

.lp-seo-body li { margin-bottom: 6px; }
.lp-seo-body li::marker { color: var(--lp-violet); }
.lp-seo-body strong { color: var(--lp-text-2); font-weight: 600; }

/* Sized to hug its label — this is a disclosure toggle, not a call to action. */
.lp-readmore {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 18px;
    padding: 6px 13px;
    border: 1px solid var(--lp-border-2);
    border-radius: 8px;
    background: var(--lp-surface);
    color: var(--lp-violet);
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.25;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.lp-readmore:hover { background: var(--lp-surface-2); border-color: var(--lp-violet); }
.lp-readmore svg { transition: transform .25s ease; }
.lp-seo[data-expanded="true"] .lp-readmore svg { transform: rotate(180deg); }

/* Swap the label without a second round-trip through JS. */
.lp-readmore .lp-readmore-less { display: none; }
.lp-seo[data-expanded="true"] .lp-readmore .lp-readmore-more { display: none; }
.lp-seo[data-expanded="true"] .lp-readmore .lp-readmore-less { display: inline; }

/* --------------------------------------------------------------------------
   FAQ
   -------------------------------------------------------------------------- */

.lp-faq { padding: 0 0 52px; }

.lp-faq-list {
    display: grid;
    gap: 12px;
}

.lp-faq-item {
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius);
    box-shadow: var(--lp-shadow-sm);
    overflow: hidden;
    transition: border-color .18s ease;
}

:root[data-theme="dark"] .lp-faq-item { background: rgba(255, 255, 255, .03); }

.lp-faq-item[open] { border-color: color-mix(in srgb, var(--lp-violet) 45%, transparent); }

.lp-faq-item summary {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 17px 20px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

.lp-faq-item summary::-webkit-details-marker { display: none; }
.lp-faq-item summary:hover { color: var(--lp-violet); }

.lp-faq-icon {
    margin-left: auto;
    flex: 0 0 auto;
    color: var(--lp-muted);
    transition: transform .2s ease, color .2s ease;
}

.lp-faq-item[open] .lp-faq-icon { transform: rotate(180deg); color: var(--lp-violet); }

.lp-faq-answer {
    margin: 0;
    padding: 0 20px 18px;
    font-size: 15.5px;
    line-height: 1.7;
    color: var(--lp-muted);
}

/* --------------------------------------------------------------------------
   Loading overlay — shown between pressing Download and the result appearing
   -------------------------------------------------------------------------- */

.lp-loading {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    padding: 20px;
    background:
        radial-gradient(60% 50% at 30% 25%, rgba(99, 102, 241, .35), transparent 70%),
        radial-gradient(55% 45% at 72% 70%, rgba(192, 38, 211, .30), transparent 70%),
        color-mix(in srgb, var(--lp-bg) 82%, transparent);
    backdrop-filter: blur(10px) saturate(140%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    animation: lp-fade-in .2s ease both;
}


.lp-loading-card {
    width: 100%;
    max-width: 420px;
    padding: 34px 30px 28px;
    text-align: center;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-xl);
    box-shadow: var(--lp-shadow-lg), 0 0 60px -20px rgba(124, 58, 237, .6);
    animation: lp-pop-in .28s cubic-bezier(.2, .9, .3, 1.2) both;
}

:root[data-theme="dark"] .lp-loading-card { background: #10131f; }

/* Orb: a conic gradient masked into a ring, spinning around a static core. */
.lp-loading-orb {
    position: relative;
    width: 96px;
    height: 96px;
    margin: 0 auto 20px;
    display: grid;
    place-items: center;
}

.lp-loading-ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0deg, #4f8bff 90deg, #8b5cf6 200deg, #d946ef 300deg, transparent 360deg);
    /* The mask punches the middle out, leaving a 5px band of the gradient. */
    mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 5px));
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 5px));
    animation: lp-spin 1s linear infinite;
}

.lp-loading-core {
    width: 62px;
    height: 62px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--lp-grad-btn);
    color: #fff;
    box-shadow: 0 10px 26px -10px rgba(124, 58, 237, .95);
    animation: lp-pulse 1.4s ease-in-out infinite;
}

.lp-loading-title {
    margin: 0 0 18px;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -.015em;
}

.lp-loading-steps {
    margin: 0 0 20px;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 9px;
    text-align: left;
}

.lp-loading-steps li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14.5px;
    color: var(--lp-muted-2);
    transition: color .25s ease;
}

.lp-loading-dot {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--lp-surface-3);
    color: transparent;
    transition: background-color .25s ease, color .25s ease, transform .25s ease;
}

:root[data-theme="dark"] .lp-loading-dot { background: rgba(255, 255, 255, .07); }

/* Steps are lit one by one by landing.js as the mock progresses. */
.lp-loading-steps li[data-active="true"] { color: var(--lp-text); }
.lp-loading-steps li[data-active="true"] .lp-loading-dot {
    background: color-mix(in srgb, var(--lp-violet) 22%, transparent);
    color: var(--lp-violet);
}

.lp-loading-steps li[data-done="true"] { color: var(--lp-text-2); }
.lp-loading-steps li[data-done="true"] .lp-loading-dot {
    background: var(--lp-grad-btn);
    color: #fff;
    transform: scale(1.06);
}

.lp-loading-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--lp-surface-3);
    overflow: hidden;
}

:root[data-theme="dark"] .lp-loading-bar { background: rgba(255, 255, 255, .07); }

.lp-loading-bar span {
    display: block;
    height: 100%;
    width: 45%;
    border-radius: inherit;
    background: linear-gradient(90deg, #4f8bff, #8b5cf6 50%, #d946ef);
    animation: lp-slide 1.1s ease-in-out infinite;
}

@keyframes lp-spin { to { transform: rotate(360deg); } }
@keyframes lp-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes lp-pop-in {
    from { opacity: 0; transform: translateY(14px) scale(.96); }
    to   { opacity: 1; transform: none; }
}
@keyframes lp-pulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.07); }
}
@keyframes lp-slide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(240%); }
}

/* The result card fades in once the overlay clears. */
.lp-result-wrap[data-revealed="true"] { animation: lp-pop-in .4s ease both; }

/* Inline warning under the download field when no link was pasted. */
.lp-field-error {
    margin: 10px auto 0;
    max-width: 1090px;
    padding: 0 4px;
    text-align: left;
    font-size: 14px;
    font-weight: 500;
    color: var(--lp-pink);
}


/* --------------------------------------------------------------------------
   Inner pages — shared hero, prose, blog
   -------------------------------------------------------------------------- */

.lp-page-hero { padding: 46px 0 30px; text-align: center; }

/*
 * The trail starts at the left edge of the container, on every template.
 *
 * It used to be centred, which followed the hero it sits in rather than the
 * page: a breadcrumb reads as a path from home to here, and a path that begins
 * in the middle of the screen and moves outwards in both directions is not one.
 */
.lp-crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    margin-bottom: 16px;
    font-size: 13.5px;
    text-align: left;
    color: var(--lp-muted);
}

.lp-crumbs a:hover { color: var(--lp-violet); }
.lp-crumbs [aria-current] { color: var(--lp-text-2); }

.lp-page-eyebrow {
    margin: 0 0 12px;
    display: inline-block;
    padding: 5px 14px;
    border-radius: 999px;
    background: var(--lp-tile-violet);
    color: var(--lp-violet);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.lp-page-title {
    margin: 0;
    font-size: clamp(1.6rem, 3.4vw, 2.6rem);
    font-weight: 800;
    line-height: 1.18;
    letter-spacing: -.03em;
}

.lp-page-lead {
    margin: 14px auto 0;
    max-width: 660px;
    font-size: clamp(1rem, 1.3vw, 1.08rem);
    color: var(--lp-muted);
}

.lp-page-updated { margin: 14px 0 0; font-size: 13.5px; color: var(--lp-muted-2); }

/* Prose pages ------------------------------------------------------------- */

.lp-prose-wrap {
    display: grid;
    grid-template-columns: 230px minmax(0, 1fr);
    gap: 40px;
    align-items: start;
    padding-block: 10px 56px;
}

.lp-toc {
    position: sticky;
    top: 96px;
    padding: 18px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-toc { background: rgba(255, 255, 255, .03); }

.lp-toc-title {
    margin: 0 0 10px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--lp-muted);
}

/* No list markers: the legal headings already carry their own numbering, and a
   second set alongside it reads as "1. 1. Dữ liệu…". */
.lp-toc ol {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 8px;
    font-size: 14px;
}

.lp-toc a { color: var(--lp-text-2); }
.lp-toc a:hover { color: var(--lp-violet); }

/* A page with no table of contents gets the full content row, with the reading
   column centred in it rather than pinned to the left edge. */
.lp-prose-wide { grid-template-columns: minmax(0, 1fr); justify-items: center; }
.lp-prose-wide .lp-prose { width: 100%; }

.lp-prose {
    max-width: 74ch;
    padding: 30px 32px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-prose { background: rgba(255, 255, 255, .03); }

/* These also style editor HTML from the page body, which uses whatever heading
   levels and elements the author picked. */
.lp-prose h2,
.lp-prose h3,
.lp-prose h4 {
    margin: 30px 0 10px;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.015em;
    color: var(--lp-text);
    scroll-margin-top: 96px;
}

.lp-prose h3 { font-size: 17px; }
.lp-prose h4 { font-size: 16px; }
.lp-prose > :first-child { margin-top: 0; }

.lp-prose p,
.lp-prose ul,
.lp-prose ol {
    margin: 0 0 14px;
    font-size: 15.5px;
    line-height: 1.75;
    color: var(--lp-muted);
}

.lp-prose ul,
.lp-prose ol { padding-left: 22px; }
.lp-prose li { margin-bottom: 7px; }
.lp-prose li::marker { color: var(--lp-violet); }
.lp-prose strong { color: var(--lp-text-2); font-weight: 600; }
.lp-prose a { color: var(--lp-violet); text-decoration: underline; }
.lp-prose img { border-radius: var(--lp-radius); margin: 4px 0 16px; }

.lp-prose blockquote {
    margin: 0 0 14px;
    padding: 2px 0 2px 16px;
    border-left: 3px solid var(--lp-violet);
    color: var(--lp-muted);
}

/* Wide tables scroll inside the card rather than pushing the page sideways. */
.lp-prose table {
    display: block;
    width: 100%;
    overflow-x: auto;
    margin: 0 0 16px;
    border-collapse: collapse;
    font-size: 14.5px;
}

.lp-prose th,
.lp-prose td {
    padding: 9px 12px;
    border: 1px solid var(--lp-border);
    text-align: left;
}

.lp-prose th { background: var(--lp-surface-2); font-weight: 600; }

/* Blog listing ------------------------------------------------------------ */

.lp-blog { padding-block: 4px 56px; }

.lp-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-bottom: 28px;
}

.lp-chip {
    padding: 8px 16px;
    border: 1px solid var(--lp-border);
    border-radius: 999px;
    background: var(--lp-surface);
    font-size: 14px;
    font-weight: 500;
    color: var(--lp-text-2);
}

:root[data-theme="dark"] .lp-chip { background: rgba(255, 255, 255, .03); }

.lp-chip[aria-current="true"] {
    background: var(--lp-grad-btn);
    border-color: transparent;
    color: #fff;
    font-weight: 600;
}

.lp-post-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 22px;
}

.lp-post {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
    transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}

:root[data-theme="dark"] .lp-post { background: rgba(255, 255, 255, .03); }

.lp-post:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--lp-violet) 45%, transparent);
    box-shadow: var(--lp-shadow);
}

.lp-post-cover {
    display: grid;
    place-items: center;
    aspect-ratio: 16 / 9;
    color: #fff;
}

/* Generated covers: one gradient per tone, no image assets involved. */
.lp-cover-violet { background: linear-gradient(135deg, #6d5bf5, #a21caf); }
.lp-cover-blue   { background: linear-gradient(135deg, #3b82f6, #6d5bf5); }
.lp-cover-green  { background: linear-gradient(135deg, #10b981, #0891b2); }
.lp-cover-amber  { background: linear-gradient(135deg, #f59e0b, #ea580c); }

.lp-post-glyph {
    display: grid;
    place-items: center;
    width: 74px;
    height: 74px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .18);
    color: #fff;
    backdrop-filter: blur(2px);
}

.lp-post-body { padding: 18px 18px 20px; display: flex; flex-direction: column; flex: 1; }

.lp-post-cat {
    margin: 0 0 8px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--lp-violet);
}

.lp-post-title {
    margin: 0 0 10px;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.35;
    letter-spacing: -.015em;
}

.lp-post-title a:hover { color: var(--lp-violet); }

.lp-post-excerpt {
    margin: 0 0 16px;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--lp-muted);
}

.lp-post-meta {
    margin: auto 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 13px;
    color: var(--lp-muted-2);
}

/* Featured card lies on its side and leads the list. */
.lp-post-featured {
    flex-direction: row;
    margin-bottom: 26px;
}

.lp-post-featured .lp-post-cover { flex: 0 0 44%; aspect-ratio: auto; }
.lp-post-featured .lp-post-body { padding: 28px 30px; justify-content: center; }
.lp-post-featured .lp-post-title { font-size: clamp(1.15rem, 2vw, 1.5rem); }
.lp-post-featured .lp-post-excerpt { font-size: 15.5px; }

/* Pager ------------------------------------------------------------------- */

.lp-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin-top: 34px;
}

.lp-pager-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 16px;
    border: 1px solid var(--lp-border-2);
    border-radius: 10px;
    font-size: 14px;
    font-weight: 500;
    color: var(--lp-text-2);
}

.lp-pager-btn[aria-disabled="true"] { opacity: .45; }
.lp-pager-pages { display: flex; gap: 6px; }

.lp-pager-page {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 500;
    color: var(--lp-text-2);
}

.lp-pager-page[aria-current="page"] {
    background: var(--lp-grad-btn);
    color: #fff;
    font-weight: 600;
}

.lp-empty {
    margin: 30px 0;
    padding: 34px 20px;
    text-align: center;
    background: var(--lp-surface);
    border: 1px dashed var(--lp-border-2);
    border-radius: var(--lp-radius-lg);
    color: var(--lp-muted);
}

:root[data-theme="dark"] .lp-empty { background: rgba(255, 255, 255, .03); }

/* Categories -------------------------------------------------------------- */

.lp-cat-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
}

.lp-cat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 20px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
    transition: transform .18s ease, border-color .18s ease;
}

:root[data-theme="dark"] .lp-cat { background: rgba(255, 255, 255, .03); }

.lp-cat:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--lp-violet) 45%, transparent);
}

.lp-cat-name { font-size: 16px; font-weight: 600; }

.lp-cat-count {
    flex: 0 0 auto;
    padding: 4px 11px;
    border-radius: 999px;
    background: var(--lp-tile-violet);
    color: var(--lp-violet);
    font-size: 12.5px;
    font-weight: 600;
}

.lp-cat-intro { margin-bottom: 26px; max-width: none; }

/* Article ----------------------------------------------------------------- */

.lp-article { padding-block: 4px 40px; max-width: 820px; }

.lp-article-meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 0 0 22px;
    font-size: 14px;
    color: var(--lp-muted);
}

.lp-article-author { font-weight: 600; color: var(--lp-text-2); }

.lp-article-cover {
    display: grid;
    place-items: center;
    aspect-ratio: 21 / 9;
    border-radius: var(--lp-radius-lg);
    margin-bottom: 30px;
    box-shadow: var(--lp-shadow);
}

.lp-article-cover .lp-post-glyph { width: 96px; height: 96px; border-radius: 26px; }

.lp-article-body h2 {
    margin: 32px 0 12px;
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -.02em;
}

.lp-article-body h2:first-child { margin-top: 0; }

.lp-article-body p,
.lp-article-body ul {
    margin: 0 0 16px;
    font-size: 16.5px;
    line-height: 1.8;
    color: var(--lp-text-2);
}

.lp-article-body ul { padding-left: 24px; }
.lp-article-body li { margin-bottom: 8px; }
.lp-article-body li::marker { color: var(--lp-violet); }

.lp-article-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 36px;
    padding: 22px 26px;
    border-radius: var(--lp-radius-lg);
    background: var(--lp-surface-2);
    border: 1px solid var(--lp-border);
}

:root[data-theme="dark"] .lp-article-cta { background: rgba(255, 255, 255, .03); }

.lp-article-cta-title { margin: 0 0 4px; font-size: 17px; font-weight: 700; }
.lp-article-cta-text { margin: 0; font-size: 14.5px; color: var(--lp-muted); }

.lp-cta-sm { height: 46px; padding: 0 24px; font-size: 15px; }

.lp-article-figure { margin: 0 0 30px; }
.lp-article-figure img { width: 100%; border-radius: var(--lp-radius-lg); box-shadow: var(--lp-shadow); }
.lp-article .lp-chips { justify-content: flex-start; margin-bottom: 22px; }

/* Previous / next article */
.lp-post-nav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    padding-block: 0 52px;
    max-width: 820px;
}

.lp-post-nav-link {
    display: grid;
    gap: 6px;
    padding: 18px 20px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
    transition: transform .18s ease, border-color .18s ease;
}

:root[data-theme="dark"] .lp-post-nav-link { background: rgba(255, 255, 255, .03); }

.lp-post-nav-link:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--lp-violet) 45%, transparent);
}

/* A lone "next" card sits on the right, where the reader expects it. */
.lp-post-nav-next { grid-column: 2; text-align: right; }

.lp-post-nav-label { font-size: 13px; font-weight: 600; color: var(--lp-violet); }
.lp-post-nav-title { font-size: 15.5px; font-weight: 600; line-height: 1.4; }

.lp-related { padding-block: 10px 56px; }

/* Contact ----------------------------------------------------------------- */

.lp-channels {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
    padding-block: 4px 30px;
}

.lp-channel {
    padding: 22px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-channel { background: rgba(255, 255, 255, .03); }

.lp-channel h2 { margin: 14px 0 6px; font-size: 17px; font-weight: 700; }
.lp-channel p { margin: 0 0 14px; font-size: 14.5px; color: var(--lp-muted); }

.lp-channel-value {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--lp-violet);
    word-break: break-all;
}

.lp-channel-value:hover { text-decoration: underline; }

.lp-contact {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 26px;
    align-items: start;
    padding-block: 0 56px;
}

.lp-contact-form {
    padding: 28px 30px;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-contact-form { background: rgba(255, 255, 255, .03); }

.lp-contact-form h2,
.lp-contact-side h2 {
    margin: 0 0 18px;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.02em;
}

.lp-field-row { margin: 0 0 16px; display: grid; gap: 7px; }

.lp-field-row label { font-size: 14px; font-weight: 600; color: var(--lp-text-2); }

.lp-field-row input,
.lp-field-row textarea {
    width: 100%;
    padding: 11px 14px;
    border: 1px solid var(--lp-border-2);
    border-radius: 10px;
    background: var(--lp-bg);
    color: var(--lp-text);
    font-family: inherit;
    font-size: 15px;
    resize: vertical;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.lp-field-row input::placeholder,
.lp-field-row textarea::placeholder { color: var(--lp-muted-2); }

.lp-field-row input:focus,
.lp-field-row textarea:focus {
    outline: none;
    border-color: var(--lp-violet);
    box-shadow: var(--lp-glow);
}

.lp-form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    margin: 22px 0 0;
}

.lp-form-note { font-size: 13.5px; color: var(--lp-muted); }

.lp-contact-side-lead { margin: -8px 0 18px; font-size: 14.5px; color: var(--lp-muted); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.lp-footer {
    border-top: 1px solid var(--lp-border);
    background: var(--lp-surface-2);
    padding: 40px 0 26px;
}

:root[data-theme="dark"] .lp-footer { background: rgba(255, 255, 255, .02); }

.lp-footer-top {
    display: grid;
    grid-template-columns: minmax(240px, 1.4fr) repeat(3, minmax(0, 1fr));
    gap: 32px;
}

.lp-footer-about p {
    margin: 14px 0 0;
    max-width: 320px;
    font-size: 14.5px;
    color: var(--lp-muted);
}

.lp-footer h3 {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: .02em;
}

.lp-footer ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 9px;
}

.lp-footer li a {
    font-size: 14.5px;
    color: var(--lp-muted);
    transition: color .15s ease;
}

.lp-footer li a:hover { color: var(--lp-violet); }

.lp-footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 30px;
    padding-top: 20px;
    border-top: 1px solid var(--lp-border);
    font-size: 14px;
    color: var(--lp-muted);
}

.lp-footer-social { display: flex; gap: 8px; }

.lp-footer-social a {
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    border: 1px solid var(--lp-border);
    border-radius: 10px;
    color: var(--lp-muted);
}

.lp-footer-social a:hover { color: var(--lp-violet); border-color: var(--lp-violet); }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {
    .lp-nav a { padding: 10px 12px; font-size: 14px; }
    .lp-lang-btn span:not(.lp-caret) { display: none; }

    /*
     * Between the tightest desktop widths and the burger breakpoint at 880px
     * the row can still be one entry too long — it was already 51px over at
     * 881px with four downloader tiles, before any tool page joined it. Let the
     * nav itself scroll instead of pushing the language switcher off the edge
     * and making every page of the site scroll sideways.
     *
     * min-width: 0 is what allows a flex child to be narrower than its content;
     * without it the list simply refuses to shrink and nothing here applies.
     */
    .lp-nav { min-width: 0; }

    .lp-nav ul {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .lp-nav ul::-webkit-scrollbar { display: none; }

    /* A shrinking row must not squeeze the labels onto two lines. */
    .lp-nav a { white-space: nowrap; }
}

@media (max-width: 1024px) {
    .lp-feature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* Two rows of two, in step with the feature grid it sits under. */
    .lp-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* The table of contents costs more width than it earns below this point. */
    .lp-prose-wrap { grid-template-columns: minmax(0, 1fr); }
    .lp-toc { position: static; }
    .lp-toc ol { grid-auto-flow: column; grid-template-rows: repeat(3, auto); }
    .lp-prose { max-width: none; }

    .lp-post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .lp-cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .lp-contact { grid-template-columns: minmax(0, 1fr); }
}

/*
 * Below this the card is too narrow to keep the icon beside a number like
 * "52,631,889+" without squeezing the number into an unreadable size, so the
 * two stack. Still two cards per row — the grid does not change.
 */
@media (max-width: 620px) {
    .lp-stat {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
        padding: 16px;
    }
}

/* Tablet / mobile header: swap the inline nav for the burger drawer. */
@media (max-width: 880px) {
    .lp-nav,
    .lp-header-actions .lp-lang,
    .lp-header-actions .lp-login { display: none; }

    .lp-burger { display: grid; }
    .lp-header-inner { height: 66px; }
}

@media (max-width: 720px) {
    .lp-container { padding-inline: 16px; }
    .lp-hero { padding-top: 26px; }
    .lp-title { line-height: 1.12; }

    .lp-download { margin-top: 22px; }

    /*
     * Phone layout: the URL field takes a row of its own, then Paste and
     * Download sit side by side on the next one.
     *
     * Grid, not flex-wrap. Wrapping only keeps the two buttons together while
     * they happen to fit — an editor who renames the CTA to something longer
     * ("Tải video xuống máy") would push Download onto a third row and put the
     * primary action below the fold. Two explicit columns cannot wrap at all:
     * a long label shrinks its button instead of breaking the row.
     *
     * Matching heights because two buttons on one line that disagree by 8px
     * look like a mistake.
     */
    .lp-download-inner {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        align-items: center;
    }

    .lp-field { grid-column: 1 / -1; min-width: 0; }

    .lp-paste,
    .lp-cta {
        height: 52px;
        min-width: 0;
        /* A label too long for its column is clipped, never wrapped. */
        overflow: hidden;
        white-space: nowrap;
    }

    /* Six marks per swipe page, matching the mobile mock. */
    .lp-platform {
        flex: 0 0 calc(100% / 6);
        min-width: 0;
        gap: 7px;
        padding: 6px 2px;
        font-size: clamp(9px, 2.7vw, 12.5px);
        text-align: center;
    }
    .lp-platform-icon { width: 34px; height: 34px; }
    .lp-platform-icon > svg { width: 100%; height: auto; }
    .lp-platform-track { gap: 0; }
    .lp-dots { display: flex; }

    /* Result card on phones: smaller thumbnail, tighter rows. The button keeps
       its 40px height — it is the one thing that must stay easy to hit. */
    .lp-result-head { gap: 12px; padding: 12px; }
    /* Full width on a phone: 70% of a 360px screen leaves a bar too narrow
       to read, and seven equal shares of it would be 30px each. The pills go
       back to their natural size and the track scrolls. */
    .lp-tool-tabs { width: 100%; margin-bottom: 14px; border-radius: 10px; }
    .lp-tool-tabs-track { justify-content: flex-start; }
    .lp-tool-tab { flex: 0 0 auto; min-height: 46px; padding-inline: 16px; font-size: 14.5px; gap: 8px; }
    .lp-thumb { flex-basis: 124px; width: 124px; }
    .lp-play { width: 32px; height: 32px; }
    .lp-play svg { width: 15px; height: 15px; }
    .lp-badge-4k { top: 5px; left: 5px; padding: 2px 5px 1px; }
    .lp-badge-4k b { font-size: 11px; }
    .lp-badge-4k span { font-size: 6px; }
    .lp-thumb-time { font-size: 10.5px; padding: 1px 5px; }

    .lp-result-meta h3 { font-size: 15px; margin-bottom: 4px; }
    .lp-result-meta p { font-size: 12.5px; }

    .lp-format { gap: 10px; padding: 10px 12px; }
    .lp-format-list:not([hidden]) { grid-template-columns: 1fr; }
    .lp-format-list .lp-format:nth-child(odd) { border-right: 0; }
    .lp-format-tag { min-width: 42px; padding: 4px 6px; font-size: 10.5px; }
    .lp-format-meta strong { font-size: 14px; }
    .lp-format-meta span { font-size: 12px; }
    /* The gradient already marks the recommended row; the pill would only crowd
       the line at this width. */
    .lp-format-badge { display: none; }
    .lp-format-btn { min-width: 0; padding: 0 14px; font-size: 13.5px; }

    .lp-formats-title { padding: 9px 12px; font-size: 11.5px; }
    .lp-formats-note { padding: 10px 12px; font-size: 12px; }

    .lp-features-wrap { padding-top: 28px; }
    .lp-feature { padding: 16px; }
    .lp-feature-head { gap: 10px; margin-bottom: 8px; }
    .lp-feature-icon { width: 38px; height: 38px; flex-basis: 38px; border-radius: 10px; }
    .lp-feature h3 { font-size: 15px; }
    .lp-feature p { font-size: 13.5px; }

    /*
     * Sized to be read, not to fit four across. The old rule shrank the number
     * to clamp(.7rem, 3vw, .95rem) — about 11px on a phone — because it was
     * still trying to keep all four stats on one line.
     */
    .lp-stats { gap: 12px; }
    .lp-stat-icon { width: 38px; height: 38px; flex-basis: 38px; border-radius: 10px; }
    .lp-stat-value { font-size: 1.15rem; }
    .lp-stat-label { font-size: 13px; }

    .lp-seo-card { padding: 22px 18px 20px; }
    .lp-seo-body { max-height: 165px; }
    .lp-seo-lead { font-size: 15px; }
    .lp-seo-body p, .lp-seo-body ul, .lp-seo-body ol { font-size: 14.5px; }
    .lp-readmore { font-size: 14px; }

    .lp-faq-item summary { padding: 14px 16px; font-size: 15px; }
    .lp-faq-answer { padding: 0 16px 16px; font-size: 14.5px; }

    /* Inner pages */
    .lp-page-hero { padding: 28px 0 22px; }
    .lp-prose { padding: 22px 18px; }
    .lp-prose p, .lp-prose ul { font-size: 14.5px; }
    .lp-toc ol { grid-auto-flow: row; grid-template-rows: none; }

    .lp-post-grid { grid-template-columns: minmax(0, 1fr); }
    .lp-post-featured { flex-direction: column; }
    .lp-post-featured .lp-post-cover { flex-basis: auto; aspect-ratio: 16 / 9; }
    .lp-post-featured .lp-post-body { padding: 18px; }
    .lp-post-featured .lp-post-excerpt { font-size: 14.5px; }

    .lp-cat-grid { grid-template-columns: minmax(0, 1fr); }
    .lp-post-nav { grid-template-columns: minmax(0, 1fr); }
    .lp-post-nav-next { grid-column: auto; text-align: left; }

    .lp-article-cover { aspect-ratio: 16 / 9; }
    .lp-article-cover .lp-post-glyph { width: 74px; height: 74px; border-radius: 20px; }
    .lp-article-body p, .lp-article-body ul { font-size: 15.5px; }
    .lp-article-cta { padding: 18px; }

    .lp-channels { grid-template-columns: minmax(0, 1fr); }
    .lp-contact-form { padding: 20px 18px; }

    .lp-pager { gap: 10px; }
    .lp-pager-btn { padding: 9px 12px; }

    /* Loading overlay */
    .lp-loading-card { padding: 26px 20px 22px; }
    .lp-loading-orb { width: 82px; height: 82px; }
    .lp-loading-core { width: 54px; height: 54px; }
    .lp-loading-title { font-size: 16.5px; }
    .lp-loading-steps li { font-size: 13.5px; }

    .lp-footer-top { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px; }
    .lp-footer-about { grid-column: 1 / -1; }
}

@media (max-width: 480px) {
    .lp-brand-mark { width: 40px; height: 40px; flex-basis: 40px; border-radius: 12px; }
    .lp-brand-name { font-size: 19px; }
    .lp-field input { font-size: 15px; }
    .lp-paste { padding: 0 14px; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

/* ------------------------------------------------------------- callout ---
 * The CTA band, rendered from a CTA content block. Named "callout" because
 * .lp-cta is already the hero's download button.
 */
.lp-callout {
    padding: 8px 0 48px;
}

.lp-callout-card {
    padding: 36px 32px;
    text-align: center;
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-lg);
    box-shadow: var(--lp-shadow-sm);
}

:root[data-theme="dark"] .lp-callout-card { background: rgba(255, 255, 255, .03); }

.lp-callout-title {
    margin: 0 0 8px;
    font-size: clamp(1.25rem, 2.4vw, 1.75rem);
    font-weight: 700;
}

.lp-callout-lead {
    margin: 0 auto 20px;
    max-width: 46rem;
    color: var(--lp-muted);
}

.lp-callout-button {
    display: inline-block;
    padding: 12px 28px;
    font-weight: 600;
    color: #fff;
    background: var(--lp-gradient, linear-gradient(90deg, #7c3aed, #2563eb));
    border-radius: var(--lp-radius);
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease;
}

.lp-callout-button:hover {
    transform: translateY(-1px);
    box-shadow: var(--lp-shadow-sm);
}

/* -------------------------------------------------------------------------
   Footer contact block (Cấu hình → Liên hệ) and tap-target sizing.
   ------------------------------------------------------------------------- */
.lp-footer-contact {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 12px;
    font-style: normal;
    font-size: 14px;
    line-height: 1.5;
}

/*
 * Footer links were 20px tall — under the 24px minimum a pointer target needs,
 * and the reason a phone user hits the wrong one. The padding buys the height
 * without moving anything, because the negative inline margin gives it back.
 */
.lp-footer nav ul li a,
.lp-footer-contact a {
    display: inline-block;
    padding: 6px 0;
    min-height: 24px;
}

.lp-result-hint {
    opacity: .72;
    font-size: 14px;
}

/* ==========================================================================
   Waiting for a lookup.

   The overlay that used to cover the page is gone; the wait is shown where the
   reader is already looking — the button they pressed, and the panel the answer
   lands in. Neither animation claims a percentage, because nothing here knows
   one: the request is a single round trip with no progress events.
   ========================================================================== */

.lp-cta-spinner {
    display: none;
    width: 20px;
    height: 20px;
    border: 2.5px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: lp-cta-spin .7s linear infinite;
}

.lp-cta[data-busy="true"] .lp-cta-icon { display: none; }
.lp-cta[data-busy="true"] .lp-cta-spinner { display: block; }

.lp-cta[data-busy="true"],
.lp-cta:disabled {
    cursor: progress;
    /* Dimmed, not greyed out: it is working, not unavailable. */
    opacity: .9;
}

@keyframes lp-cta-spin {
    to { transform: rotate(360deg); }
}

.lp-result-progress {
    position: relative;
    height: 4px;
    margin-bottom: 18px;
    overflow: hidden;
    background: var(--lp-surface-3);
    border-radius: 999px;
}

.lp-result-progress span {
    position: absolute;
    inset: 0;
    display: block;
    border-radius: inherit;
    background: var(--lp-grad-btn);
    animation: lp-result-progress 1.15s ease-in-out infinite;
}

@keyframes lp-result-progress {
    0%   { transform: translateX(-100%) scaleX(.45); }
    50%  { transform: translateX(0) scaleX(.7); }
    100% { transform: translateX(100%) scaleX(.45); }
}

/*
 * While the answer is on its way, the wait is ALL there is.
 *
 * The panel ships with a sample thumbnail and a list of the formats the service
 * can offer — furniture for the empty state. Dimming them during a lookup was
 * not enough: a reader watching a spinner beside a thumbnail and four Download
 * buttons is reading a result that has not happened yet. Everything but the
 * loading block is taken out of the panel until the real answer lands.
 */
.lp-result-wrap[data-loading="true"] .lp-result > *:not(.lp-result-loading) { display: none; }

.lp-result-loading {
    display: grid;
    gap: 14px;
    place-items: center;
    padding: 46px 20px 50px;
}

.lp-result-loading .lp-result-progress {
    width: min(420px, 100%);
    margin: 0;
}

.lp-result-loading-text {
    margin: 0;
    font-size: 15px;
    color: var(--lp-muted);
}

@media (prefers-reduced-motion: reduce) {
    .lp-cta-spinner { animation-duration: 1.8s; }

    .lp-result-progress span {
        animation: none;
        transform: none;
        opacity: .55;
    }
}
