/* ==========================================================================
   GigWand - public site
   Committed to one look: a dark stage. The product is for people who work in
   rooms with the lights down, and the hero is a WebGL scene that only reads
   against black, so there is no light theme to keep honest.
   ========================================================================== */

:root {
    --ink: #07070b;
    --ink-2: #0c0c13;
    --surface: #12121b;
    --surface-2: #191926;
    --line: rgba(255, 255, 255, 0.09);
    --line-strong: rgba(255, 255, 255, 0.16);

    --text: #eeecf7;
    --muted: #9b97b0;
    --faint: #6e6a82;

    --violet: #7c5cff;
    --violet-soft: #a992ff;
    --violet-dim: rgba(124, 92, 255, 0.14);
    --gold: #ffcb6b;
    --mint: #35e0c0;

    --radius: 14px;
    --radius-lg: 22px;
    --maxw: 1140px;

    --sans: "Sora", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --body: "Inter", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
    margin: 0;
    background: var(--ink);
    color: var(--text);
    font-family: var(--body);
    font-size: 16.5px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

a { color: var(--violet-soft); text-decoration: none; }
a:hover { color: #c4b4ff; }

h1, h2, h3, h4 { font-family: var(--sans); font-weight: 600; letter-spacing: -0.022em; line-height: 1.1; margin: 0; }

.shell { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

/* ---- Nav ---------------------------------------------------------------- */

.site-nav {
    position: sticky; top: 0; z-index: 50;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    background: rgba(7, 7, 11, 0.66);
    border-bottom: 1px solid transparent;
    transition: border-color .3s ease, background .3s ease;
}
.site-nav.stuck { border-bottom-color: var(--line); background: rgba(7, 7, 11, 0.9); }
.site-nav .shell { display: flex; align-items: center; gap: 28px; height: 70px; }

.wordmark {
    display: inline-flex; align-items: center; gap: 9px;
    font-family: var(--sans); font-weight: 600; font-size: 20px;
    letter-spacing: -0.03em; color: var(--text);
}
.wordmark:hover { color: var(--text); }
.wordmark .spark { width: 22px; height: 22px; display: block; }

.site-nav nav { display: flex; gap: 6px; margin-left: auto; align-items: center; }
.site-nav nav a.link {
    color: var(--muted); font-size: 15px; padding: 8px 13px; border-radius: 9px;
    transition: color .18s ease, background .18s ease;
}
.site-nav nav a.link:hover { color: var(--text); background: rgba(255, 255, 255, 0.05); }
.site-nav nav a.link.active { color: var(--text); }

.navtoggle { display: none; }

/* ---- Buttons ------------------------------------------------------------ */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    font-family: var(--sans); font-weight: 600; font-size: 15px;
    padding: 12px 22px; border-radius: 11px; border: 1px solid transparent;
    cursor: pointer; text-align: center; line-height: 1.2;
    transition: transform .16s ease, box-shadow .22s ease, background .18s ease, border-color .18s ease, color .18s ease;
}
.btn:active { transform: translateY(1px); }

.btn-primary {
    background: linear-gradient(135deg, #8b6cff 0%, #6a46f5 100%);
    color: #fff;
    box-shadow: 0 8px 26px -10px rgba(124, 92, 255, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-primary:hover { color: #fff; box-shadow: 0 14px 38px -12px rgba(124, 92, 255, 1), inset 0 1px 0 rgba(255, 255, 255, 0.3); }

.btn-ghost { background: rgba(255, 255, 255, 0.04); border-color: var(--line-strong); color: var(--text); }
.btn-ghost:hover { background: rgba(255, 255, 255, 0.08); color: var(--text); }

.btn-lg { font-size: 16.5px; padding: 15px 30px; border-radius: 13px; }
.btn-block { width: 100%; }

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

.hero { position: relative; min-height: 92vh; display: flex; align-items: center; padding: 90px 0 110px; }

/* The canvas sits behind everything and is purely decorative. It fades in once
   three.js has loaded so the page is readable the instant HTML arrives, rather
   than waiting 650KB for its own headline. */
#hero-canvas {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; transition: opacity 1.4s ease; pointer-events: none;
}
#hero-canvas.ready { opacity: 1; }

/* A CSS stand-in for the WebGL glow, visible immediately and underneath it
   forever after. If WebGL is blocked or the device refuses it, this is still a
   deliberate-looking hero rather than a black rectangle. */
.hero::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    /* Multi-stop rather than colour-to-transparent: a two-stop radial gradient
       fades linearly and leaves a visible disc edge against a ground this
       dark. The extra stops give it a falloff the eye reads as light. */
    background:
        radial-gradient(900px 640px at 70% 44%,
            rgba(124, 92, 255, 0.24) 0%,
            rgba(124, 92, 255, 0.13) 30%,
            rgba(124, 92, 255, 0.05) 55%,
            rgba(124, 92, 255, 0.015) 75%,
            transparent 100%),
        radial-gradient(620px 460px at 20% 74%,
            rgba(255, 203, 107, 0.09) 0%,
            rgba(255, 203, 107, 0.03) 45%,
            transparent 100%),
        radial-gradient(1100px 700px at 50% -8%,
            rgba(53, 224, 192, 0.06) 0%,
            rgba(53, 224, 192, 0.02) 50%,
            transparent 100%);
}

/* A scrim over the canvas, dense on the left where the headline sits and clear
   on the right where the trail is. The sparks are additive, so without this the
   brightest part of the animation lands straight on the text it is meant to
   frame. Sits above the canvas and below .shell. */
.hero::after {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: linear-gradient(100deg,
        var(--ink) 0%,
        rgba(7, 7, 11, 0.92) 26%,
        rgba(7, 7, 11, 0.55) 46%,
        rgba(7, 7, 11, 0.1) 64%,
        transparent 78%);
}
@media (max-width: 900px) {
    /* Narrow: the copy is over the middle, so the scrim covers everything. */
    .hero::after { background: rgba(7, 7, 11, 0.74); }
}
.hero .shell { position: relative; z-index: 2; }

.hero-copy { max-width: 700px; }

.eyebrow {
    display: inline-flex; align-items: center; gap: 9px;
    font-size: 13px; font-weight: 600; letter-spacing: 0.04em;
    color: var(--violet-soft); background: var(--violet-dim);
    border: 1px solid rgba(124, 92, 255, 0.3);
    padding: 6px 14px; border-radius: 100px; margin-bottom: 26px;
}
.eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--mint); box-shadow: 0 0 10px var(--mint); }

h1.display {
    font-size: clamp(2.6rem, 6.4vw, 4.5rem);
    letter-spacing: -0.035em; line-height: 1.02; margin-bottom: 24px;
}
h1.display .shine {
    /*
     * The colour has to reach the FIRST letter.
     *
     * This was linear-gradient(105deg, #fff 8%, ...) and the word read white
     * until about the "n" of entertainers. Two reasons, and both had to go.
     *
     * The white stop sat at 8%, so the opening letters were painted with flat
     * white before any colour began. And 105deg is a steep axis: on a box far
     * wider than it is tall, the gradient line runs mostly across the HEIGHT,
     * which compresses the horizontal spread and pushes the first real colour
     * further right still. Together they cost the first four letters.
     *
     * 96deg is near-horizontal with just enough tilt to look deliberate, and
     * the first stop is a colour at 0% rather than white with a run-up. White
     * now appears mid-word as a highlight, which is what it was always meant
     * to be.
     *
     * inline-block so background-clip has a box that is exactly the word.
     * Left inline, the painting box is the line box, and the gradient gets
     * stretched across whitespace the letters do not occupy.
     */
    display: inline-block;
    /*
     * Seven stops, not four, because the gradient is now WIDER than the word
     * and slides across it. At 220% background-size only about 45% of the
     * gradient is inside the letters at any moment, so stops spaced ~18% apart
     * guarantee that window always spans at least two of them. Four stops
     * spread over the same width would let a flat run drift across the word
     * and it would go white mid-sweep - the same failure as the original
     * "#fff 8%", arriving on a timer instead of sitting still.
     */
    background: linear-gradient(96deg,
        var(--violet-soft) 0%,
        #fff 18%,
        var(--gold) 36%,
        var(--violet-soft) 54%,
        #fff 72%,
        var(--gold) 90%,
        var(--violet-soft) 100%);
    background-size: 220% 100%;
    background-position: 0% 50%;
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
    /*
     * ALTERNATE, so the sweep reverses rather than looping.
     *
     * A looping sweep needs the gradient's first and last colour to match or
     * it snaps back visibly every cycle. Reversing sidesteps that entirely.
     *
     * Four seconds each way, up from nine. Nine was a drift you had to watch
     * for; four reads as a live surface without becoming the thing your eye
     * keeps going back to while trying to read the paragraph underneath.
     * ease-in-out matters more at this speed than it did at nine: it slows at
     * each end, so the reversal still lands as a turn rather than a bounce.
     */
    animation: shine-sweep 4s ease-in-out infinite alternate;
}

@keyframes shine-sweep {
    from { background-position: 0% 50%; }
    to   { background-position: 100% 50%; }
}

/*
 * Somebody who has asked their machine for less motion gets the gradient and
 * none of the movement. The word still reads exactly as designed; it simply
 * holds still.
 */
@media (prefers-reduced-motion: reduce) {
    h1.display .shine {
        animation: none;
        background-position: 30% 50%;
    }
}

.lede {
    font-size: clamp(1.05rem, 2.2vw, 1.28rem); color: var(--muted);
    max-width: 610px; margin-bottom: 36px;
    /*
     * A legibility shadow, not a decorative one. The hero sits over a field of
     * bright particles that runs behind the right-hand end of these lines, and
     * grey text on a moving light source is the one place this page is hard to
     * read. Two layers: a tight dark edge to separate the glyphs, and a wider
     * soft one to lift the whole line off whatever is behind it.
     */
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 2px 14px rgba(0, 0, 0, 0.4);
}
.lede strong { color: var(--text); font-weight: 600; }

.hero-cta { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.hero-note { font-size: 14px; color: var(--faint); margin-top: 18px; }

/* ---- Sections ----------------------------------------------------------- */

.section { padding: 100px 0; position: relative; }
.section.tight { padding: 70px 0; }
.section-head { max-width: 660px; margin-bottom: 54px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.kicker {
    font-size: 13px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--gold); margin-bottom: 14px;
}
h2.title { font-size: clamp(1.85rem, 3.9vw, 2.7rem); margin-bottom: 16px; }
.section-head p { color: var(--muted); font-size: 1.08rem; margin: 0; }

.rule { height: 1px; background: linear-gradient(90deg, transparent, var(--line-strong), transparent); border: 0; margin: 0; }

/* ---- Cards -------------------------------------------------------------- */

.grid { display: grid; gap: 20px; }
.grid.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.card {
    background: linear-gradient(180deg, var(--surface) 0%, var(--ink-2) 100%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 26px;
    position: relative; overflow: hidden;
    transition: border-color .25s ease, transform .25s ease;
}
.card:hover { border-color: var(--line-strong); transform: translateY(-2px); }
.card h3 { font-size: 1.12rem; margin-bottom: 9px; }
.card p { color: var(--muted); font-size: 0.97rem; margin: 0; }

.card .ico {
    width: 42px; height: 42px; border-radius: 12px; margin-bottom: 18px;
    display: grid; place-items: center;
    background: var(--violet-dim); border: 1px solid rgba(124, 92, 255, 0.28);
    color: var(--violet-soft);
}
.card .ico svg { width: 21px; height: 21px; }

/* ---- Comparison --------------------------------------------------------- */

.compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.compare .card { padding: 28px; }
.compare .card.them { background: var(--ink-2); }
.compare .card.us { border-color: rgba(124, 92, 255, 0.34); box-shadow: 0 26px 60px -40px rgba(124, 92, 255, 0.9); }
.compare h3 { font-size: 1rem; letter-spacing: 0.02em; margin-bottom: 18px; color: var(--muted); font-weight: 600; }
.compare .card.us h3 { color: var(--violet-soft); }
.compare ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; }
.compare li { display: flex; gap: 12px; font-size: 0.97rem; color: var(--muted); align-items: flex-start; }
.compare .card.us li { color: var(--text); }
.compare li .mark { flex: 0 0 auto; width: 19px; height: 19px; margin-top: 2px; }

/* ---- Pricing ------------------------------------------------------------ */

/* Auto-flow rather than a fixed three columns. There are two plans now, and a
   hardcoded third column left them shunted to the left of an empty gap. This
   centres whatever number of plans exist, and caps their width so two do not
   stretch into slabs. */
.plans {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 360px);
    justify-content: center;
    gap: 20px;
    align-items: stretch;
}
.plan { display: flex; flex-direction: column; }
.plan.featured {
    border-color: rgba(124, 92, 255, 0.42);
    box-shadow: 0 30px 70px -44px rgba(124, 92, 255, 1);
}
.plan .tag {
    position: absolute; top: 18px; right: 18px; font-size: 11px; font-weight: 700;
    letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink);
    background: var(--gold); padding: 4px 10px; border-radius: 100px;
}
.plan .name { font-family: var(--sans); font-weight: 600; font-size: 1.16rem; margin-bottom: 6px; }
.plan .who { color: var(--faint); font-size: 0.9rem; margin-bottom: 22px; }
.plan .price { display: flex; align-items: baseline; gap: 7px; margin-bottom: 4px; }
.plan .price .amt { font-family: var(--sans); font-size: 2.7rem; font-weight: 600; letter-spacing: -0.04em; }
.plan .price .per { color: var(--faint); font-size: 0.95rem; }
.plan .billed { color: var(--faint); font-size: 0.85rem; margin-bottom: 24px; }
.plan ul { list-style: none; margin: 0 0 26px; padding: 0; display: grid; gap: 11px; }
.plan li { display: flex; gap: 11px; font-size: 0.95rem; color: var(--muted); align-items: flex-start; }
.plan li .mark { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 3px; color: var(--mint); }
.plan li strong { color: var(--text); font-weight: 600; }
.plan .go { margin-top: auto; }

/* ---- Steps -------------------------------------------------------------- */

.steps { counter-reset: step; display: grid; gap: 2px; }
.step { display: grid; grid-template-columns: 58px 1fr; gap: 22px; padding: 26px 0; border-bottom: 1px solid var(--line); }
.step:last-child { border-bottom: 0; }
.step .n {
    counter-increment: step; font-family: var(--sans); font-size: 1.3rem; font-weight: 600;
    color: var(--violet-soft); width: 48px; height: 48px; border-radius: 50%;
    display: grid; place-items: center; border: 1px solid rgba(124, 92, 255, 0.3); background: var(--violet-dim);
}
.step .n::before { content: counter(step); }
.step h3 { font-size: 1.1rem; margin-bottom: 7px; }
.step p { color: var(--muted); margin: 0; font-size: 0.99rem; }

/* ---- Quote -------------------------------------------------------------- */

.quote { text-align: center; max-width: 780px; margin: 0 auto; }
.quote blockquote {
    font-family: var(--sans); font-size: clamp(1.3rem, 3vw, 1.85rem); line-height: 1.34;
    letter-spacing: -0.02em; margin: 0 0 22px; color: var(--text);
}
.quote .by { color: var(--faint); font-size: 0.95rem; }

/* ---- CTA band ----------------------------------------------------------- */

.cta-band {
    border: 1px solid rgba(124, 92, 255, 0.3);
    border-radius: 26px; padding: 58px 40px; text-align: center;
    background:
        radial-gradient(600px 300px at 50% 0%, rgba(124, 92, 255, 0.22), transparent 72%),
        linear-gradient(180deg, var(--surface) 0%, var(--ink-2) 100%);
}
.cta-band h2 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); margin-bottom: 14px; }
.cta-band p { color: var(--muted); max-width: 520px; margin: 0 auto 30px; }

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

.site-foot { border-top: 1px solid var(--line); padding: 50px 0 60px; margin-top: 40px; }
.site-foot .cols { display: flex; flex-wrap: wrap; gap: 40px; justify-content: space-between; }
.site-foot .about { max-width: 320px; }
.site-foot .about p { color: var(--faint); font-size: 0.92rem; margin: 14px 0 0; }
.site-foot .linkcol h4 { font-size: 0.8rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); margin-bottom: 14px; font-weight: 700; }
.site-foot .linkcol a { display: block; color: var(--muted); font-size: 0.94rem; padding: 4px 0; }
.site-foot .linkcol a:hover { color: var(--text); }
.site-foot .fine { margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--line); color: var(--faint); font-size: 0.86rem; display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; }

/* ---- Auth / forms ------------------------------------------------------- */

.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }
.auth-side {
    position: relative; padding: 52px; display: flex; flex-direction: column; justify-content: space-between;
    border-right: 1px solid var(--line); overflow: hidden;
    background:
        radial-gradient(660px 480px at 30% 30%, rgba(124, 92, 255, 0.2), transparent 70%),
        radial-gradient(500px 400px at 78% 82%, rgba(255, 203, 107, 0.1), transparent 72%),
        var(--ink-2);
}
/* The explicit 100% matters. A canvas is a replaced element, so with width:auto
   it takes its INTRINSIC size from the width/height attributes that
   renderer.setSize writes - and then measuring the canvas to decide those
   attributes is a feedback loop that grows the framebuffer on every resize. */
#auth-canvas {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; transition: opacity 1.4s ease; pointer-events: none;
}
/* The field is atmosphere, not the subject. */
#auth-canvas.ready { opacity: 0.62; }
/* A scrim over the animation, densest where the copy sits.
   The particles were passing directly behind several lines, which is the one
   place motion costs legibility rather than adding atmosphere. Dimming the
   whole canvas would have flattened the panel; this quiets it only under the
   text and leaves the corners alive. Sits above the canvas (z-index 0) and
   below the content (z-index 2). */
.auth-side::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        /* Over the copy specifically. */
        radial-gradient(
            900px 720px at 20% 52%,
            rgba(7, 7, 11, 0.92) 0%,
            rgba(7, 7, 11, 0.66) 46%,
            transparent 78%
        ),
        /* And a wash from the left edge: the bright end of the field drifts in
           from the upper right and was reaching the ends of the longer lines. */
        linear-gradient(
            100deg,
            rgba(7, 7, 11, 0.6) 0%,
            rgba(7, 7, 11, 0.26) 46%,
            transparent 72%
        );
}
.auth-side > * { position: relative; z-index: 2; }
.auth-side .pitch { max-width: 420px; }
.auth-side .pitch h2 { font-size: clamp(1.6rem, 3vw, 2.15rem); margin-bottom: 18px; }
/* Lifted off --muted. That token is tuned for copy on a flat panel; this copy
   sits over a moving background and lost the bottom of its contrast range. */
/* Near-white. Over a moving background there is no subtle grey that stays
   readable through the bright part of the cycle. */
.auth-side .pitch p { color: #e9e7f3; line-height: 1.65; }
/* The list is a separate thought from the sentence above it, and at 30px it
   read as a fourth paragraph. */
.auth-side .proof { display: grid; gap: 14px; margin-top: 42px; }
.auth-side .proof div { display: flex; gap: 12px; align-items: flex-start; color: #ddd9ea; font-size: 0.95rem; }
.auth-side .proof .mark { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 3px; color: var(--mint); }

.auth-main { display: flex; align-items: center; justify-content: center; padding: 52px 32px; }

/* Depth, not drama. The right side is a flat field next to a panel carrying a
   gradient and a particle field, so the form had nothing holding it. A barely
   raised surface, a hairline, and one wide soft shadow give it a plane to sit
   on without competing with the glow opposite. */
.auth-card {
    width: 100%;
    max-width: 430px;
    padding: 36px 34px;
    border-radius: 20px;
    background: linear-gradient(180deg, rgba(25, 25, 38, 0.72) 0%, rgba(18, 18, 27, 0.72) 100%);
    border: 1px solid var(--line);
    box-shadow: 0 30px 70px -40px rgba(0, 0, 0, 0.95), 0 2px 10px -6px rgba(0, 0, 0, 0.7);
}
.auth-card input,
.auth-card select {
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
}
/* The submit button was the brightest object on the page by a distance,
   brighter than the headline it was meant to follow. Same colour, less halo. */
.auth-card .btn-primary {
    box-shadow: 0 6px 18px -12px rgba(124, 92, 255, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.auth-card .btn-primary:hover {
    box-shadow: 0 10px 26px -14px rgba(124, 92, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.24);
}
.legal-reassure { margin-top: 10px; color: var(--muted); }
.auth-card h1 { font-size: 1.85rem; margin-bottom: 8px; }
.auth-card .sub { color: var(--muted); margin: 0 0 30px; font-size: 0.98rem; }

.field { margin-bottom: 17px; }
.field label { display: block; font-size: 13.5px; font-weight: 600; color: var(--muted); margin-bottom: 7px; }
.field .hint { font-weight: 400; color: var(--faint); }
.field input[type="text"], .field input[type="email"], .field input[type="password"],
.field input[type="tel"], .field select, .field textarea {
    width: 100%; padding: 13px 15px; font-size: 15.5px; font-family: inherit;
    color: var(--text); background: var(--surface-2);
    border: 1px solid var(--line-strong); border-radius: 11px;
    transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none; border-color: var(--violet);
    box-shadow: 0 0 0 3px rgba(124, 92, 255, 0.2);
    background: var(--surface);
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239b97b0' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 13px center; background-size: 18px;
    padding-right: 42px;
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.auth-alt { margin-top: 24px; text-align: center; color: var(--muted); font-size: 0.94rem; }
.legal { margin-top: 22px; color: var(--faint); font-size: 0.83rem; text-align: center; line-height: 1.5; }

.flash { padding: 13px 16px; border-radius: 11px; margin-bottom: 20px; font-size: 0.95rem; border: 1px solid; }
.flash.ok { background: rgba(53, 224, 192, 0.1); border-color: rgba(53, 224, 192, 0.4); color: #7ff0da; }
.flash.err { background: rgba(255, 106, 106, 0.1); border-color: rgba(255, 106, 106, 0.42); color: #ff9d9d; }

/* ---- Onboarding wizard -------------------------------------------------- */

.wiz { max-width: 640px; margin: 0 auto; padding: 44px 24px 90px; }
.wiz-head { text-align: center; margin-bottom: 34px; }
.wiz-head h1 { font-size: 1.9rem; margin-bottom: 10px; }
.wiz-head p { color: var(--muted); margin: 0; }
.wiz-steps { display: flex; gap: 8px; margin-bottom: 34px; }
.wiz-steps i {
    flex: 1; height: 4px; border-radius: 100px; background: var(--surface-2); display: block;
    transition: background .4s ease;
}
.wiz-steps i.done { background: var(--violet); }
.wiz-steps i.now { background: linear-gradient(90deg, var(--violet), var(--gold)); }
.wiz-card { background: linear-gradient(180deg, var(--surface) 0%, var(--ink-2) 100%); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 30px; }
.wiz-card h2 { font-size: 1.3rem; margin-bottom: 8px; }
.wiz-card .lead { color: var(--muted); margin: 0 0 26px; font-size: 0.98rem; }
.wiz-actions { display: flex; gap: 12px; align-items: center; margin-top: 26px; }
.wiz-actions .skip { margin-left: auto; color: var(--faint); font-size: 0.92rem; background: none; border: 0; cursor: pointer; font-family: inherit; }
.wiz-actions .skip:hover { color: var(--muted); text-decoration: underline; }
/* Underlined at rest, not only on hover. It is a real submit button, but styled
   as quiet text it read as a caption - Chris asked whether it was clickable at
   all, which is the answer. */
.wiz-actions .skip { text-decoration: underline; text-underline-offset: 3px; }
/* Back sits on the LEFT. It must not inherit .skip's margin-left:auto, which is
   what pushes the skip link to the far right. */
.wiz-actions .wiz-back {
    order: -1;
    color: var(--faint);
    font-size: 0.92rem;
    background: none;
    border: 0;
    cursor: pointer;
    font-family: inherit;
    padding: 6px 2px;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.wiz-actions .wiz-back:hover { color: var(--muted); }

/* The booking link and its two buttons.

   This row carried class="flex" with gap/align-items/flex-wrap in an inline
   style. .flex is defined in app.css - the CRM stylesheet - and the wizard
   loads site.css only, so the row was never a flex container and every one
   of those three properties was inert. The buttons flowed as plain inline
   blocks directly under the input with no gap at all, which is what Chris
   saw on a phone.

   On a narrow card the link takes its own line and the buttons sit under it,
   with a real gap between the two rows. */
.url-row {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 10px; margin-top: 8px;
}
.url-box {
    flex: 1 1 180px; min-width: 0;
    font-family: ui-monospace, Menlo, monospace; font-size: .82rem;
}
.wiz-preview-head {
    display: flex; justify-content: space-between; align-items: center;
    gap: 10px; margin-bottom: 10px;
}

@media (max-width: 640px) {
    /* Full width each, so two half-width buttons do not end up on one line
       with the link squeezed above them. */
    .url-box { flex: 1 0 100%; }
    .url-row .btn { flex: 1 1 auto; }
}

/* The picker, the typed hex and the hint.

   On a phone the three do not fit across one line: the hint ran out past the
   right edge of the card, which is what Chris reported. It gets its own
   full-width line under the inputs there, and sits beside them on a wider
   card. flex-wrap alone would have done it, but only by accident of the
   widths - this says which line it belongs on at each size. */
.accent-row {
    display: flex; gap: 10px; align-items: center;
    margin-top: 12px; flex-wrap: wrap;
}
.accent-picker {
    flex: 0 0 auto; width: 64px; height: 48px; padding: 5px; cursor: pointer;
    background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: 11px;
}
.accent-hex {
    flex: 0 1 132px; min-width: 112px; height: 48px; padding: 0 12px;
    font-family: ui-monospace, Menlo, monospace; text-transform: uppercase;
    color: var(--text); background: var(--surface-2);
    border: 1px solid var(--line-strong); border-radius: 11px;
}
.accent-hint { font-size: .86rem; white-space: nowrap; }

@media (max-width: 640px) {
    /* Its own line, not a leftover on the end of the previous one. */
    .accent-hint { flex: 1 0 100%; white-space: normal; margin-top: 2px; }
}

/* Accent presets on the wizard.

   The same eight colours the Account page offers, from the same constant, so
   a colour chosen at signup is one of the ones still on offer afterwards.

   The ring uses the CARD's background, not the page's - these sit inside
   .wiz-card, whose gradient is lighter than the page behind it, and a ring cut
   in page-black left a dark gap around every selected swatch. */
.swatches { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 8px; }
.swatch {
    width: 34px; height: 34px; padding: 0; border-radius: 50%; cursor: pointer;
    background: var(--sw); border: 2px solid transparent;
    box-shadow: 0 0 0 1px var(--line);
    transition: transform .14s ease, box-shadow .18s ease;
}
.swatch:hover { transform: scale(1.08); }
.swatch.on { border-color: var(--surface); box-shadow: 0 0 0 2px var(--sw); }
.swatch:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

/* One row on a phone. Eight at a fixed 34px plus gaps overflow the card, and a
   wrapped last swatch reads as a ninth option left behind. Shrink to fit, never
   grow; aspect-ratio keeps them circular as the width comes down. */
@media (max-width: 640px) {
    .swatches { flex-wrap: nowrap; gap: 6px; }
    .swatch {
        flex: 0 1 34px;
        width: auto; min-width: 0; max-width: 34px;
        height: auto; aspect-ratio: 1;
    }
}

.choice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.choice { position: relative; }
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice span {
    display: block; text-align: center; padding: 18px 12px; border-radius: 13px;
    border: 1px solid var(--line-strong); background: var(--surface-2);
    font-family: var(--sans); font-weight: 600; font-size: 0.97rem; cursor: pointer;
    transition: border-color .18s ease, background .18s ease, color .18s ease;
}
.choice span:hover { border-color: var(--violet); }
.choice input:checked + span {
    border-color: var(--violet); background: var(--violet-dim); color: #fff;
    box-shadow: 0 0 0 3px rgba(124, 92, 255, 0.16);
}
.choice input:focus-visible + span { outline: 2px solid var(--violet-soft); outline-offset: 2px; }

.copybox {
    display: flex; gap: 10px; align-items: center; background: var(--ink);
    border: 1px solid var(--line-strong); border-radius: 11px; padding: 12px 14px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13.5px;
    color: var(--mint); word-break: break-all;
}

/* ---- Utilities ---------------------------------------------------------- */

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.center { text-align: center; }
.mt-s { margin-top: 10px; } .mt { margin-top: 20px; } .mt-l { margin-top: 40px; }
.mb-s { margin-bottom: 10px; } .mb { margin-bottom: 20px; }
.nowrap { white-space: nowrap; }

/* Reveal on scroll. Starts visible and is only hidden once JS confirms it can
   put it back - so with JS off or broken, the page is fully readable. */
.reveal { opacity: 1; }
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s cubic-bezier(.2,.7,.3,1), transform .7s cubic-bezier(.2,.7,.3,1); }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .js .reveal { opacity: 1; transform: none; transition: none; }
}

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

@media (max-width: 900px) {
    .auth-wrap { grid-template-columns: 1fr; }
    /* Form first on a phone.
       The panel used to be display:none here, which did put the form at the
       top - but it also threw away the wordmark and every reason to sign up,
       on the devices most likely to be someone's first visit. Reordered
       instead: the form is what they came for and it is what they land on,
       and the pitch is still there for anyone who scrolls.
       The canvas stays off - a WebGL particle field is not worth its battery
       below the fold. */
    .auth-main { order: 1; }
    .auth-side {
        order: 2;
        min-height: 0;
        padding: 40px 28px 44px;
        border-right: 0;
        border-top: 1px solid var(--line);
        gap: 30px;
    }
    .auth-side #auth-canvas,
    .auth-side::after { display: none; }
    .auth-side .proof { margin-top: 26px; }
    .auth-card {
        padding: 26px 22px;
        border: 0;
        background: none;
        box-shadow: none;
    }
    .grid.c3, .grid.c4, .plans { grid-template-columns: 1fr; }
    /* Back to stacking on a phone: auto-flow column would run them off-screen. */
    .plans { grid-auto-flow: row; grid-auto-columns: auto; }
    /* The crafts grid is the exception. One column turned eight short cards
       into eight full-width screens, which read as a very long list of people
       who are not you. Two up keeps the whole set in view. */
    .grid.c4.crafts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
    .grid.c4.crafts .card { padding: 14px; }
    .grid.c4.crafts h3 { font-size: 1rem; }
    .grid.c4.crafts p { font-size: .88rem; line-height: 1.45; }
    .grid.c2, .compare { grid-template-columns: 1fr; }
    .hero { min-height: auto; padding: 60px 0 80px; }
    .section { padding: 70px 0; }

    .navtoggle {
        display: grid; place-items: center; margin-left: auto;
        width: 40px; height: 40px; border-radius: 10px;
        background: rgba(255, 255, 255, 0.05); border: 1px solid var(--line-strong);
        color: var(--text); cursor: pointer;
    }
    .site-nav nav {
        position: absolute; top: 70px; left: 0; right: 0;
        flex-direction: column; align-items: stretch; gap: 4px; padding: 14px 24px 20px;
        background: rgba(7, 7, 11, 0.98); border-bottom: 1px solid var(--line);
        display: none;
    }
    .site-nav.open nav { display: flex; }
    .site-nav nav .btn { width: 100%; margin-top: 6px; }

    /* Language picker beside the hamburger, not inside it.
       <nav> is absolutely positioned at this width so it leaves the flex flow
       entirely; the row is wordmark | picker | toggle. order puts the picker
       first of the two, and the auto margin does the pushing now that the
       toggle no longer carries it. */
    .site-nav .shell { gap: 10px; }
    .site-nav .shell > .langpick { order: 2; margin-left: auto; }
    .navtoggle { order: 3; margin-left: 0; }
    .langpick select {
        font-size: 13px; padding: 9px 26px 9px 10px;
        min-height: 40px; background-position: right 7px center;
    }
    .cta-band { padding: 44px 24px; }
    .step { grid-template-columns: 1fr; gap: 14px; }
}

@media (max-width: 520px) {
    .field-row { grid-template-columns: 1fr; }
    .hero-cta .btn { width: 100%; }
}

/* ---- Password reveal -----------------------------------------------------
   One field with a reveal, rather than a password plus a confirm. A confirm
   box only catches a typo made twice differently; seeing what you typed
   catches it outright, on the screen where people are least willing to fill in
   an extra field. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 74px; }
.pw-reveal {
    position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
    font-family: var(--body); font-size: 12.5px; font-weight: 600;
    color: var(--muted); background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--line-strong); border-radius: 8px;
    padding: 6px 11px; cursor: pointer;
    transition: color .16s ease, background .16s ease, border-color .16s ease;
}
.pw-reveal:hover { color: var(--text); background: rgba(255, 255, 255, 0.1); }
.pw-reveal:focus-visible { outline: 2px solid var(--violet-soft); outline-offset: 2px; }
.pw-hint { margin: 7px 0 0; font-size: 12.5px; color: var(--faint); }

/* ---- Numbered beat list (the problem section) ----------------------------
   The booking loop, one line per beat. Deliberately terse: the point lands by
   how many lines there are, not by what any one of them says. */
.beat-list {
    list-style: none; counter-reset: beat; margin: 0 0 30px; padding: 0;
    display: grid; gap: 10px; max-width: 620px;
}
.beat-list li {
    counter-increment: beat;
    display: flex; align-items: baseline; gap: 14px;
    font-size: 1.05rem; color: var(--text);
}
.beat-list li::before {
    content: counter(beat);
    flex: 0 0 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center;
    font-size: 12px; font-weight: 700; font-family: var(--sans);
    color: var(--violet-soft); background: var(--violet-dim);
    border: 1px solid rgba(124, 92, 255, 0.28);
}
.beat-list li:last-child { color: var(--gold); }

.section-close {
    max-width: 680px; color: var(--muted); font-size: 1.05rem;
    border-left: 2px solid var(--violet); padding-left: 18px; margin: 34px 0 0;
}
.section-close strong { color: var(--text); }

/* ---- The lead-to-gig flow ----------------------------------------------- */
.flow {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
    gap: 10px 0;
}
.flow li { display: flex; align-items: center; }
.flow li span {
    display: block; padding: 9px 16px; border-radius: 100px;
    background: var(--surface); border: 1px solid var(--line-strong);
    font-family: var(--sans); font-weight: 600; font-size: 0.92rem;
    white-space: nowrap;
}
/* The arrow between stages is decoration, so it is drawn rather than typed:
   a text arrow would be read out by a screen reader between every item. */
.flow li:not(:last-child)::after {
    content: ""; width: 26px; height: 1px; margin: 0 4px;
    background: linear-gradient(90deg, var(--line-strong), rgba(124, 92, 255, .6));
}
.flow li:first-child span { border-color: rgba(124, 92, 255, .45); color: var(--violet-soft); }
.flow li:last-child span { border-color: rgba(255, 203, 107, .4); color: var(--gold); }

/* ---- AI vs automation labels -------------------------------------------
   The two are genuinely different and the page says so. The label carries
   that distinction visually so it survives skim-reading. */
.tagline {
    display: inline-block; font-size: 10.5px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 100px; margin-bottom: 14px;
}
.tag-ai { background: var(--violet-dim); color: var(--violet-soft); border: 1px solid rgba(124, 92, 255, .34); }
.tag-auto { background: rgba(53, 224, 192, .12); color: var(--mint); border: 1px solid rgba(53, 224, 192, .3); }

.founder-body {
    font-size: 1.08rem; line-height: 1.7; color: var(--muted);
    /* Centered, matching the .quote block it sits in and the founder block on
       the /performers landing page. It was explicitly text-align: left, which
       left one left-ragged paragraph inside an otherwise centered section. */
    max-width: 660px; margin: 0 auto 20px; text-align: center;
}

/* ---- Language selector -------------------------------------------------- */
.langpick { position: relative; }
.langpick select {
    appearance: none; font: inherit; font-size: 14px;
    color: var(--muted); background: transparent;
    border: 1px solid var(--line-strong); border-radius: 9px;
    padding: 7px 30px 7px 12px; cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239b97b0' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 9px center; background-size: 15px;
}
.langpick select:hover { color: var(--text); border-color: var(--violet); }

/* The picker is a sibling of <nav> now, not a child, so it picks up .shell's
   28px gap instead of nav's 6px. Pulled back so the desktop bar looks exactly
   as it did when the picker lived inside the nav.
   
   Scoped to min-width rather than left unscoped: this rule sits AFTER the
   max-width:900px block in the file, so unscoped it won at equal specificity
   and dragged the picker on top of the wordmark on a phone. */
@media (min-width: 901px) {
    .site-nav .shell > .langpick { margin-left: -22px; }
}

@media (max-width: 900px) {
    .flow { justify-content: flex-start; }
    .flow li:not(:last-child)::after { width: 16px; }
    .founder-body { font-size: 1rem; }
}

/* Screen-reader-only label. Present in the accessibility tree, absent on
   screen; clip-path rather than display:none so it is still announced. */
.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* The line under the crafts grid. Says the list is not a gate. */
.crafts-more {
    margin: 22px auto 0;
    max-width: 760px;
    text-align: center;
    color: var(--muted);
    font-size: .95rem;
    line-height: 1.6;
}

/* The onboarding form preview. A lightbox rather than a new tab: leaving the
   wizard to look at something is how people fail to come back. */
.wiz-preview {
    position: fixed; inset: 0; z-index: 200; display: flex;
    align-items: center; justify-content: center; padding: 20px;
    background: rgba(0, 0, 0, .68);
}
.wiz-preview[hidden] { display: none; }
.wiz-preview-card {
    background: var(--surface, #17171b);
    border: 1px solid var(--line);
    border-radius: 14px; padding: 16px;
    width: 100%; max-width: 560px;
}

/* ---------------------------------------------------------------------------
   Legal documents (/terms, /privacy)
   ---------------------------------------------------------------------------
   Set to be READ, not skimmed. The marketing pages above run wide and lean on
   motion; an agreement someone is checking a clause in wants a single narrow
   measure, generous leading, and numbered headings that can be found by eye.

   Scoped under .legalpage throughout. There is already a .legal class doing a
   different job - the small centred fine print under the signup button - and
   an article reusing that name inherits 0.83rem centred faint text for a
   4,000-word agreement.
   --------------------------------------------------------------------------- */
.legalpage { padding: 132px 0 96px; }
.legalpage .shell.narrow { max-width: 760px; }

.legalpage h1 { font-size: clamp(2rem, 4.4vw, 2.7rem); margin: 0 0 6px; letter-spacing: -0.02em; }

.legalpage h2 {
    font-size: 1.16rem;
    margin: 44px 0 14px;
    padding-top: 22px;
    border-top: 1px solid var(--line);
    letter-spacing: -0.01em;
    scroll-margin-top: 96px;     /* so /terms#refunds lands clear of the fixed nav */
}

.legalpage p,
.legalpage li { color: var(--muted); font-size: 0.99rem; line-height: 1.72; }
.legalpage p { margin: 0 0 14px; }
.legalpage ul { margin: 0 0 16px; padding-left: 22px; }
.legalpage li { margin-bottom: 9px; }
.legalpage strong { color: var(--text); font-weight: 600; }
.legalpage a { color: var(--violet-soft); }

.lp-meta { font-size: 0.86rem !important; color: var(--faint) !important; margin-bottom: 30px !important; }

/* The read-this-first block and the all-caps clauses. Same treatment: the
   convention is upper case, so the job here is keeping it legible - wider
   letter-spacing, shorter measure, smaller than body rather than larger. */
.lp-lede,
.lp-caps {
    font-size: 0.84rem !important;
    line-height: 1.66;
    letter-spacing: 0.012em;
    color: var(--text) !important;
}
.lp-lede {
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    padding: 18px 20px;
    margin: 0 0 34px !important;
}
.lp-caps { color: var(--muted) !important; }

.lp-draft {
    background: rgba(255, 176, 32, 0.09);
    border: 1px solid rgba(255, 176, 32, 0.42);
    border-radius: 12px;
    padding: 14px 18px;
    margin-bottom: 30px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--gold);
}
.lp-draft code { font-size: 0.86em; background: rgba(0, 0, 0, 0.3); padding: 1px 5px; border-radius: 4px; }

/* Wide content scrolls inside its own box rather than the page body. */
.lp-table-wrap { overflow-x: auto; margin: 0 0 18px; }
.lp-table { width: 100%; border-collapse: collapse; margin: 0; font-size: 0.92rem; min-width: 480px; }
.lp-table th,
.lp-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
.lp-table th { color: var(--text); font-weight: 600; white-space: nowrap; }
.lp-table td { color: var(--muted); }

.lp-foot { margin-top: 42px !important; padding-top: 22px; border-top: 1px solid var(--line); font-size: 0.92rem !important; }

@media (max-width: 720px) {
    .legalpage { padding: 104px 0 72px; }
    .legalpage h2 { margin-top: 34px; }
}

/* Language selector beside the wordmark on the signed-out pages. Quiet by
   design: it is a site setting, not a step in the form. */
.auth-lang { margin-left: 12px; font-size: .82rem; letter-spacing: .01em; }
.auth-lang a { color: rgba(255,255,255,.55); text-decoration: none; padding: 2px 4px; border-radius: 4px; }
.auth-lang a:hover { color: rgba(255,255,255,.85); }
.auth-lang a.on { color: #fff; background: rgba(255,255,255,.12); }
.auth-lang-sep { color: rgba(255,255,255,.28); margin: 0 2px; }
