/* Faint cold light following the cursor across the whole page. */
body::before {
    content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
    background: radial-gradient(600px 400px at var(--px, 50%) var(--py, 30%), rgba(140, 160, 200, 0.06), transparent 70%);
    opacity: var(--wake, 1);
}
/* --wake (js/pointer.js) goes 0 to 1 as the light wakes up on load; every lit effect below scales with it.
   With JS it starts at 0 so nothing flashes bright before pointer.js runs; without JS the fallback is 1. */
.js { --wake: 0; }
/* Lift content above the light. The nav keeps base.css's fixed position and z-index 50. */
main, .footer { position: relative; z-index: 1; }
/* The vault glow (inset -90px) and the frame glow (inset -60px) reach past the viewport on phones,
   which widens the mobile layout viewport (and the fixed nav with it). Clip them sideways only,
   so they still bleed above and below. */
main { overflow-x: clip; }

/* ---------- hero vault: rim + glow behind the lock ---------- */
.vault { --angle: 200deg; --nx: 0; --ny: 0; }
.vault-glow {
    background: conic-gradient(from calc(var(--angle) - 60deg), #9fb8ff, var(--metal-hi) 18%, transparent 34%, transparent 66%, var(--metal-lo) 86%, #9fb8ff);
    filter: blur(60px); opacity: calc(0.55 * var(--wake, 1)); pointer-events: none;
    transform: translate(calc(var(--nx) * 80px), calc(var(--ny) * 80px));
}
.vault-rim {
    filter: brightness(calc(0.3 + 0.7 * var(--wake, 1)));
    background: conic-gradient(from calc(var(--angle) - 60deg), #fff, var(--metal) 12%, #2a2f38 30%, #0c0d10 50%, #2a2f38 70%, var(--metal-hi) 90%, #fff);
}
.vault-face {
    background:
        radial-gradient(260px 200px at var(--mx, 50%) var(--my, 40%), rgba(190, 205, 230, calc(0.16 * var(--wake, 1))), transparent 70%),
        linear-gradient(180deg, #111215, #030304);
}

/* ---------- demo frame: same rim, drawn as a 1.5px ring ---------- */
.frame { --angle: 200deg; --nx: 0; --ny: 0; position: relative; border-radius: 22px; box-shadow: 0 40px 80px -30px #000; }
.frame::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; pointer-events: none;
    filter: brightness(calc(0.3 + 0.7 * var(--wake, 1)));
    background: conic-gradient(from calc(var(--angle) - 60deg), #fff, var(--metal) 12%, #2a2f38 30%, #0c0d10 50%, #2a2f38 70%, var(--metal-hi) 90%, #fff);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
}
.frame::after {
    content: ""; position: absolute; inset: -60px; z-index: -1; border-radius: 40px; pointer-events: none;
    background: conic-gradient(from calc(var(--angle) - 60deg), rgba(159, 184, 255, 0.35), transparent 30%, transparent 70%, rgba(127, 150, 200, 0.3));
    filter: blur(50px); opacity: calc(0.6 * var(--wake, 1));
}
.bezel {
    border-radius: 22px; padding: 10px;
    background:
        radial-gradient(500px 300px at var(--mx, 50%) var(--my, 0%), rgba(200, 215, 240, calc(0.12 * var(--wake, 1))), transparent 60%),
        linear-gradient(180deg, #16171b, #0a0a0c);
}
.scene { perspective: 1400px; }
.tilt {
    transform: rotateX(calc(4deg - var(--ny) * 4deg)) rotateY(calc(var(--nx) * 6deg));
    transition: transform 0.25s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation: none !important; transition: none !important; }
    .tilt { transform: none !important; }
    .vault-glow { transform: none !important; }
    .js .reveal { opacity: 1; transform: none; }
}

/* ---------- engraved light lines on the vault (drawn by js/engrave.js) ---------- */
.vault-engrave {
    position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
    clip-path: polygon(50% 3%, 97% 26.5%, 97% 73.5%, 50% 97%, 3% 73.5%, 3% 26.5%);
    filter: drop-shadow(0 0 3px rgba(185, 198, 218, 0.9)) drop-shadow(0 0 8px rgba(159, 184, 255, 0.35));
}
.vault-engrave path { fill: none; stroke: #e6ecf5; stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- hero title: glossy black letters, lit where the cursor light falls ---------- */
.title-in { display: inline-block; white-space: nowrap; }
.title-in span {
    --mx: 50%; --my: -40%;
    display: inline-block; position: relative;
    /* padding widens each letter's paint box so background-clip:text never cuts a glyph edge */
    padding: 0.08em 0.1em 0.12em; margin: 0 -0.1em;
    color: transparent; -webkit-text-fill-color: transparent;
    background:
        radial-gradient(220px 180px at var(--mx) var(--my), rgba(255, 255, 255, calc(0.95 * var(--wake, 1))), rgba(190, 205, 230, calc(0.55 * var(--wake, 1))) 30%, transparent 70%),
        linear-gradient(180deg, #3a3e46 0%, #0b0c0e 38%, #000 52%, #16181c 64%, #2a2d33 72%, #050506 100%);
    -webkit-background-clip: text; background-clip: text;
    /* edge light instead of text-stroke, which draws Inter's inner contours (the e's crossbar) */
    filter: drop-shadow(0 0 0.6px rgba(230, 236, 245, 0.55)) drop-shadow(0 0 18px rgba(159, 184, 255, 0.1)) brightness(1);
}
/* Page load: letters rise out of the dark one after another. */
.js .title-in span { animation: letter-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 55ms); }
.js .title-in span.ready { animation: none; }
/* Crossing a letter sends a ripple of light along the word; letters themselves never move (js/title.js). */
@keyframes letter-in {
    from { opacity: 0; transform: translateY(0.25em) rotateX(-50deg); }
}

/* ---------- hero lattice: engraved hex grid on the sides, lit by the cursor ---------- */
.lattice {
    position: absolute; inset: 0; pointer-events: none; z-index: 0;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='55.4' height='96'%3E%3Cpath d='M27.7 0v16M27.7 16 55.4 32v32L27.7 80 0 64V32ZM27.7 80v16' fill='none' stroke='%23b9c6da' stroke-width='1'/%3E%3C/svg%3E");
    background-size: 55.4px 96px; background-position: 50% 0;
    opacity: 0.55;
    -webkit-mask:
        radial-gradient(380px 300px at var(--mx, 50%) var(--my, 30%), rgba(0, 0, 0, calc(0.55 * var(--wake, 1))), transparent 75%),
        radial-gradient(ellipse 70% 85% at 50% 42%, transparent 45%, rgba(0, 0, 0, 0.18) 75%, rgba(0, 0, 0, 0.3) 100%);
    mask:
        radial-gradient(380px 300px at var(--mx, 50%) var(--my, 30%), rgba(0, 0, 0, calc(0.55 * var(--wake, 1))), transparent 75%),
        radial-gradient(ellipse 70% 85% at 50% 42%, transparent 45%, rgba(0, 0, 0, 0.18) 75%, rgba(0, 0, 0, 0.3) 100%);
}
.lattice::after { /* fade into the demo below */
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 200px; background: linear-gradient(transparent, #000);
}

/* ---------- demo carve: the explorer is cut out of the background, then forms (js/assemble.js) ---------- */
.frame::before, .frame::after { transition: opacity 1s ease; }
.frame.tilt { transition: transform 0.25s ease-out, box-shadow 1.2s ease; } /* keeps .tilt's transform transition */
.js .frame.forming { box-shadow: none; pointer-events: none; }
/* 0.001, not 0: the browser still paints these while they're invisible, so the explorer, its rim and its glow
   are already drawn when they appear. At 0 the first reveal had to paint them all in one frame and stuttered. */
.js .frame.forming::before, .js .frame.forming::after { opacity: 0.001; }
.js .frame.forming .bezel { opacity: 0.001; }
.carve { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.carve svg {
    position: absolute; left: 0; top: 0; overflow: visible; z-index: 1; will-change: opacity;
    filter: drop-shadow(0 0 2px rgba(185, 198, 218, 0.9)) drop-shadow(0 0 8px rgba(159, 184, 255, 0.35));
}
.carve path { fill: none; stroke: #cfd8e6; stroke-width: 1.2; stroke-dasharray: 1; stroke-dashoffset: 1; }
/* The cutting point: a white-hot spark riding the outline. */
.carve .spark {
    position: absolute; left: 0; top: 0; z-index: 2; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; opacity: 0;
    offset-rotate: 0deg; background: #fff;
    box-shadow: 0 0 6px 2px #fff, 0 0 16px 6px rgba(159, 184, 255, 0.7), 0 0 34px 10px rgba(159, 184, 255, 0.25);
}
/* A carved piece: solid brushed dark metal, lit on its top edge. */
/* Only opacity and transform animate on slabs and the polish line, so the GPU runs them without repainting. */
.carve .slab {
    position: absolute; overflow: hidden; opacity: 0; will-change: opacity, transform; transform-origin: 50% 100%;
    box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(230, 236, 245, 0.22);
    background:
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 3px),
        linear-gradient(180deg, #1b1d22, #0b0c0e 60%, #07080a);
}
/* The line of light that polishes a slab into the real piece. */
.carve .polish {
    position: absolute; z-index: 3; height: 2px; margin-top: -1px; opacity: 0; will-change: opacity, transform;
    background: linear-gradient(90deg, transparent, #fff 20%, #fff 80%, transparent);
    box-shadow: 0 0 12px 3px rgba(185, 198, 218, 0.6);
}
@media (prefers-reduced-motion: reduce) {
    .js .frame.forming::before, .js .frame.forming::after, .js .frame.forming .bezel { opacity: 1; }
}

@media (max-width: 760px) {
    .lattice { display: none; } /* phones keep the plain hero; the grid is for wide screens' empty sides */
}

/* ---------- nav mark: the hero vault in miniature, rim lit from the cursor like the big one ---------- */
.mark { --angle: 200deg; position: relative; display: block; width: 22px; height: 25px; transition: filter 0.3s; }
.mark::before, .mark i { position: absolute; clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); }
.mark::before {
    content: ""; inset: 0; filter: brightness(calc(0.3 + 0.7 * var(--wake, 1)));
    background: conic-gradient(from calc(var(--angle) - 60deg), #fff, var(--metal) 12%, #2a2f38 30%, #0c0d10 50%, #2a2f38 70%, var(--metal-hi) 90%, #fff);
}
.mark i { inset: 1.5px; background: linear-gradient(180deg, #1a1c20, #050506); }
.mark svg { position: absolute; left: 50%; top: 50%; width: 7px; height: 11px; transform: translate(-50%, -46%); }
.mark path { fill: #cfd8e6; transition: fill 0.3s; }
.brand:hover .mark { filter: drop-shadow(0 0 6px rgba(185, 198, 218, 0.55)); }
.brand:hover .mark path { fill: #fff; }
