/* ===================================================================
   DevVault landing page.

   The public front door. It borrows the palette wholesale from
   devvault.css — same tokens, same two themes — so signing in feels like
   walking through a door rather than arriving at a different product.
   Everything here is prefixed .dv-l- and used nowhere else, which keeps
   the app's own stylesheet untouched.
   =================================================================== */

/* Anchor links land under the sticky bar without the heading hiding
   behind it. */
html { scroll-behavior: smooth; }
:target { scroll-margin-top: 5rem; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

.dv-l-body { background: var(--dv-bg); }

/* Header ------------------------------------------------------------ */
.dv-l-nav {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: color-mix(in srgb, var(--dv-bg) 85%, transparent);
    backdrop-filter: saturate(180%) blur(12px);
    border-bottom: 1px solid transparent;
    transition: border-color .2s, background-color .2s;
    /* The inner navbar is p-0 so it does not fight the sticky header, which
       left the bar exactly as tall as the tallest button in it — the links
       and the Create account button sat hard against both edges and the whole
       header read as a squashed strip. The height belongs here. */
    padding-block: .875rem;
}

/* The border only earns its place once there is content scrolled under
   it — at the top of the page it reads as a stray line. */
.dv-l-nav.is-stuck { border-bottom-color: var(--dv-border); }

.dv-l-brand {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-weight: 650;
    font-size: 1.0625rem;
    letter-spacing: -0.02em;
    color: var(--dv-text);
    text-decoration: none;
}

.dv-l-nav-link {
    color: var(--dv-text-muted);
    font-size: .875rem;
    font-weight: 500;
    text-decoration: none;
    padding: .4rem .6rem;
    border-radius: var(--dv-radius-sm);
    transition: color .12s, background-color .12s;
}

.dv-l-nav-link:hover { color: var(--dv-text); background: var(--dv-surface-2); }

/* Shared section furniture ------------------------------------------ */
.dv-l-section { padding: 5rem 0; }

@media (max-width: 767.98px) {
    .dv-l-section { padding: 3.5rem 0; }
}

.dv-l-eyebrow {
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--dv-accent);
    margin-bottom: .75rem;
}

.dv-l-h2 {
    font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
    font-weight: 650;
    letter-spacing: -0.025em;
    margin: 0 0 .75rem;
}

.dv-l-lead {
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--dv-text-muted);
    margin: 0;
}

.dv-l-measure { max-width: 42rem; }

/* Hero --------------------------------------------------------------- */
.dv-l-hero {
    position: relative;
    overflow: hidden;
    padding: 4.5rem 0 5rem;
}

/* Two soft accent washes and a faint grid. Pointer events are off so the
   decoration can never eat a click on the buttons above it. */
.dv-l-hero::before,
.dv-l-hero::after {
    content: "";
    position: absolute;
    pointer-events: none;
    z-index: 0;
}

.dv-l-hero::before {
    inset: -30% -10% auto -10%;
    height: 70%;
    background:
        radial-gradient(45% 60% at 25% 40%, rgba(var(--dv-accent-rgb), .16), transparent 70%),
        radial-gradient(40% 55% at 78% 30%, rgba(var(--dv-accent-rgb), .10), transparent 70%);
}

.dv-l-hero::after {
    inset: 0;
    background-image:
        linear-gradient(to right, var(--dv-border) 1px, transparent 1px),
        linear-gradient(to bottom, var(--dv-border) 1px, transparent 1px);
    background-size: 56px 56px;
    opacity: .5;
    mask-image: radial-gradient(70% 60% at 50% 20%, #000, transparent 75%);
    -webkit-mask-image: radial-gradient(70% 60% at 50% 20%, #000, transparent 75%);
}

.dv-l-hero > * { position: relative; z-index: 1; }

.dv-l-badge {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .3rem .7rem;
    border-radius: 999px;
    background: var(--dv-accent-soft);
    border: 1px solid rgba(var(--dv-accent-rgb), .22);
    color: var(--dv-accent);
    font-size: .8125rem;
    font-weight: 550;
}

.dv-l-h1 {
    font-size: clamp(2.125rem, 1.4rem + 3.2vw, 3.375rem);
    line-height: 1.08;
    font-weight: 700;
    letter-spacing: -0.035em;
    margin: 1.25rem 0 1rem;
}

.dv-l-h1 .dv-l-accent { color: var(--dv-accent); }

.dv-l-hero-lead {
    font-size: 1.125rem;
    line-height: 1.6;
    color: var(--dv-text-muted);
    max-width: 34rem;
    margin: 0 0 1.75rem;
}

.dv-l-cta-note {
    font-size: .875rem;
    color: var(--dv-text-faint);
    margin: 1rem 0 0;
}

.dv-l-btn-lg { padding: .625rem 1.25rem; font-weight: 550; }

/* Hero mock ----------------------------------------------------------
   A still of the error list, drawn in markup rather than shipped as a
   screenshot: it stays sharp on any display, follows the theme, and
   cannot drift out of date with a redesign the way a PNG does. */
.dv-l-mock {
    background: var(--dv-surface);
    border: 1px solid var(--dv-border);
    border-radius: var(--dv-radius);
    box-shadow: var(--dv-shadow-lift);
    overflow: hidden;
}

.dv-l-mock-bar {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .875rem;
    background: var(--dv-surface-2);
    border-bottom: 1px solid var(--dv-border);
}

.dv-l-dot {
    width: .625rem;
    height: .625rem;
    border-radius: 50%;
    background: var(--dv-border-strong);
}

.dv-l-mock-url {
    flex: 1;
    text-align: center;
    font-family: var(--dv-mono);
    font-size: .75rem;
    color: var(--dv-text-faint);
}

.dv-l-mock-body { padding: 1rem; }

.dv-l-mock-search {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .75rem;
    border: 1px solid var(--dv-border-strong);
    border-radius: var(--dv-radius-sm);
    background: var(--dv-bg);
    font-family: var(--dv-mono);
    font-size: .875rem;
    color: var(--dv-text);
}

.dv-l-caret {
    display: inline-block;
    width: 1px;
    height: 1em;
    background: var(--dv-accent);
    animation: dv-l-blink 1.1s step-end infinite;
}

@keyframes dv-l-blink { 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
    .dv-l-caret { animation: none; }
}

.dv-l-mock-meta {
    font-size: .8125rem;
    color: var(--dv-text-muted);
    margin: .75rem 0 .5rem;
}

.dv-l-mock-row {
    padding: .75rem;
    border: 1px solid var(--dv-border);
    border-radius: var(--dv-radius-sm);
    background: var(--dv-surface);
}

.dv-l-mock-row + .dv-l-mock-row { margin-top: .5rem; }

.dv-l-mock-row.is-match { border-color: rgba(var(--dv-accent-rgb), .45); }

.dv-l-mock-title {
    font-family: var(--dv-mono);
    font-size: .875rem;
    font-weight: 500;
    color: var(--dv-text);
    margin: 0 0 .4rem;
    word-break: break-word;
}

.dv-l-chip {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .1rem .45rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 550;
    background: var(--dv-surface-2);
    color: var(--dv-text-muted);
    border: 1px solid var(--dv-border);
}

.dv-l-chip.is-accent {
    background: var(--dv-accent-soft);
    color: var(--dv-accent);
    border-color: rgba(var(--dv-accent-rgb), .2);
}

.dv-l-chip.is-success {
    background: var(--dv-success-soft);
    color: var(--dv-success);
    border-color: rgba(21, 127, 91, .25);
}

.dv-l-chip.is-warning {
    background: var(--dv-warning-soft);
    color: var(--dv-warning);
    border-color: rgba(180, 105, 14, .25);
}

.dv-l-solution {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin-top: .625rem;
    padding-top: .625rem;
    border-top: 1px dashed var(--dv-border);
    font-size: .875rem;
    color: var(--dv-text-muted);
}

.dv-l-solution .bi { color: var(--dv-success); }

/* Bootstrap paints inline code pink, which is the one colour in the mock
   that belongs to no part of the palette. */
.dv-l-solution code { color: var(--dv-accent); }

/* Proof strip -------------------------------------------------------- */
.dv-l-stats {
    border-block: 1px solid var(--dv-border);
    background: var(--dv-surface);
}

.dv-l-stat-n {
    font-size: 1.5rem;
    font-weight: 650;
    letter-spacing: -0.02em;
    color: var(--dv-text);
}

.dv-l-stat-l {
    font-size: .875rem;
    color: var(--dv-text-muted);
}

/* Cards -------------------------------------------------------------- */
.dv-l-card {
    height: 100%;
    background: var(--dv-surface);
    border: 1px solid var(--dv-border);
    border-radius: var(--dv-radius);
    padding: 1.375rem;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}

.dv-l-card:hover {
    border-color: var(--dv-border-strong);
    box-shadow: var(--dv-shadow-lift);
    transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
    .dv-l-card:hover { transform: none; }
}

.dv-l-card h3 {
    font-size: 1rem;
    font-weight: 600;
    margin: .875rem 0 .375rem;
}

.dv-l-card p {
    font-size: .875rem;
    line-height: 1.55;
    color: var(--dv-text-muted);
    margin: 0;
}

.dv-l-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--dv-radius-sm);
    background: var(--dv-accent-soft);
    color: var(--dv-accent);
    font-size: 1.125rem;
}

/* The three headline capabilities get a roomier card and a tinted top. */
.dv-l-card.is-spotlight {
    padding: 1.625rem;
    background:
        linear-gradient(180deg, rgba(var(--dv-accent-rgb), .05), transparent 45%),
        var(--dv-surface);
}

/* Steps -------------------------------------------------------------- */
.dv-l-step-n {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--dv-accent);
    color: #fff;
    font-size: .875rem;
    font-weight: 650;
    flex-shrink: 0;
}

[data-bs-theme="dark"] .dv-l-step-n { color: #12131a; }

.dv-l-step h3 {
    font-size: 1.0625rem;
    font-weight: 600;
    margin: 0 0 .375rem;
}

.dv-l-step p {
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--dv-text-muted);
    margin: 0;
}

/* Code sample -------------------------------------------------------- */
.dv-l-code {
    background: var(--dv-surface);
    border: 1px solid var(--dv-border);
    border-radius: var(--dv-radius);
    overflow: hidden;
}

.dv-l-code-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .5rem .875rem;
    background: var(--dv-surface-2);
    border-bottom: 1px solid var(--dv-border);
    font-size: .8125rem;
    color: var(--dv-text-muted);
    font-weight: 550;
}

.dv-l-code pre {
    margin: 0;
    padding: 1rem;
    overflow-x: auto;
    font-family: var(--dv-mono);
    font-size: .875rem;
    line-height: 1.7;
    color: var(--dv-text);
}

.dv-l-code .tok-cmd { color: var(--dv-accent); }
.dv-l-code .tok-str { color: var(--dv-success); }
.dv-l-code .tok-dim { color: var(--dv-text-faint); }

/* Closing call to action --------------------------------------------- */
.dv-l-final {
    position: relative;
    overflow: hidden;
    background: var(--dv-surface);
    border: 1px solid var(--dv-border);
    border-radius: calc(var(--dv-radius) * 1.5);
    padding: 3rem 2rem;
    text-align: center;
}

.dv-l-final::before {
    content: "";
    position: absolute;
    inset: -60% -20% auto -20%;
    height: 140%;
    pointer-events: none;
    background: radial-gradient(45% 55% at 50% 35%, rgba(var(--dv-accent-rgb), .14), transparent 70%);
}

.dv-l-final > * { position: relative; }

/* Back to top --------------------------------------------------------
   Kept out of the flow entirely until there is something to scroll back
   up from — a button that does nothing is worse than no button. It fades
   rather than appears so it never pulls the eye mid-read. */
.dv-l-top {
    position: fixed;
    right: 1.25rem;
    bottom: 1.25rem;
    z-index: 1040;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--dv-border-strong);
    border-radius: 50%;
    background: var(--dv-surface);
    color: var(--dv-text-muted);
    box-shadow: var(--dv-shadow-lift);
    font-size: 1.125rem;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(.5rem);
    transition: opacity .18s, transform .18s, visibility .18s, color .12s, border-color .12s;
}

.dv-l-top.is-shown {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.dv-l-top:hover {
    color: var(--dv-accent);
    border-color: var(--dv-accent);
}

.dv-l-top:focus-visible {
    outline: 2px solid var(--dv-accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .dv-l-top { transition: opacity .18s, visibility .18s; transform: none; }
}

/* Footer ------------------------------------------------------------- */
.dv-l-footer {
    border-top: 1px solid var(--dv-border);
    padding: 2rem 0;
    font-size: .875rem;
    color: var(--dv-text-muted);
}

.dv-l-footer a { color: var(--dv-text-muted); text-decoration: none; }
.dv-l-footer a:hover { color: var(--dv-text); }

/* The byline sits a step quieter than the footer links: it is a signature,
   not a navigation item. */
.dv-l-credit { color: var(--dv-text-faint); font-size: .8125rem; }


/* Collapsed header --------------------------------------------------

   The menu expands in the flow here, so it needs less than the app's does,
   but the appearance dropdown has the same problem: .dropdown-menu-end pins
   the menu's right edge to a button now sitting at the LEFT of the screen,
   which lays the menu out off the side. Anchor it to the row instead. */
@media (max-width: 1199.98px) {
    .dv-l-nav { padding-block: .625rem; }

    /* The bar is deliberately see-through with a blur, so the page slides
       under it. That is right for a 60px strip and wrong for an open menu:
       the hero headline showed straight through the links, and the bar and
       the menu read as two different surfaces because only one of them was
       tinted. While the menu is open the header is solid. */
    .dv-l-nav:has(#dvLandingMenu.show),
    .dv-l-nav:has(#dvLandingMenu.collapsing) {
        background: var(--dv-surface);
        border-bottom-color: var(--dv-border);
        box-shadow: var(--dv-shadow-lift);
    }

    /* A line between the bar and the menu, so the brand row still reads as
       the bar rather than the first item of the list. */
    #dvLandingMenu {
        border-top: 1px solid var(--dv-border);
        margin-top: .625rem;
    }

    /* Stacked, these are rows rather than inline links — full width, and a
       tap target that matches the app's own collapsed menu. */
    #dvLandingMenu .dv-l-nav-link {
        display: block;
        padding: .6rem .7rem;
    }

    #dvLandingMenu > .d-flex { position: relative; }
    #dvLandingMenu > .d-flex > .dropdown { position: static; }

    #dvLandingMenu .dropdown-menu {
        left: 0;
        right: 0;
        width: auto;
        min-width: 0;
    }
}
