/* VAMP website styles.
 *
 * Everything is scoped under .vlanding, which is why this file and the desktop app's
 * styles.css can never collide: no rule here can reach a page that does not opt in by
 * carrying that class. Extracted from hubLandingStyles() in app/static/app.js when the
 * site became its own thing; this file is now the source of truth for the site's look.
 */
/* Scoped to the site's own pages by [data-page], NOT bare `body`. app.js links this same
 * file into the app shell to draw the landing at / (that is how the two stopped drifting),
 * and an unscoped body rule there would repaint the application's background too. */
body[data-page] { margin: 0; background: #0b0d12; }

/* THE TYPE, and the reason this file needs a comment about it: for a while there was no
 * font-family here at all, so every page in this folder rendered in the browser's default
 * serif while the landing at / - drawn by app.js under app/static/styles.css - rendered in
 * Inter. The wordmark visibly changed font walking from / to /guide. This stack is a copy
 * of the one in app/static/styles.css and has to stay a copy: change one, change both. */
.vlanding{font-family:"Inter",-apple-system,"Segoe UI",Roboto,sans-serif;--vbg:#0b0d12;--vbg2:#12151d;--vpanel:#161a23;--vline:#242a36;--vtext:#eef1f6;--vdim:#aab3c2;--vfaint:#7c8698;--vaccent:#6e5bff;--vaccent2:#4f2bd4;--vgood:#39e08a;--vaccent-txt:#8f7bff;background:var(--vbg);color:var(--vtext);min-height:100vh;line-height:1.6;-webkit-font-smoothing:antialiased}
.vlanding *{box-sizing:border-box}
.vlanding a{color:inherit;text-decoration:none}
.vlanding .vwrap{max-width:1080px;margin:0 auto;padding:0 24px}
.vlanding .vmark{width:40px;height:40px;border-radius:11px;background:var(--vaccent2);display:inline-flex;align-items:center;justify-content:center;box-shadow:0 4px 16px rgba(79,43,212,.4);flex:0 0 auto}
.vlanding .vmark svg{width:22px;height:22px;fill:#fff;stroke:none}
/* The mark is a 40px tile by design, which is under the 44px touch minimum. Rather than
   grow the tile, stretch only the hit area: the ::after covers 44x44 and is invisible. */
.vlanding a.vmark{position:relative}
.vlanding a.vmark::after{content:"";position:absolute;inset:-2px;border-radius:13px}
.vlanding .vhead{position:sticky;top:0;z-index:10;background:rgba(11,13,18,.82);backdrop-filter:blur(10px);border-bottom:1px solid var(--vline)}
/* min-height, not height: a fixed 64px could not contain the buttons once they were
   squeezed narrow enough to wrap their own labels, and they burst out to 89px. */
.vlanding .vbar{display:flex;align-items:center;gap:12px;min-height:64px}
.vlanding .vname{font-size:18px;font-weight:600;letter-spacing:.2px}
.vlanding .vbar .vname{display:inline-flex;align-items:center;min-height:44px}
.vlanding .vbar .vspacer{flex:1}
/* line-height is spelled out because <button class="vbtn"> does not inherit the 1.6 that
   <a class="vbtn"> picks up from .vlanding, which left every submit button 39px tall
   next to an otherwise identical 44px link. */
.vlanding .vbtn{display:inline-flex;align-items:center;gap:8px;padding:10px 18px;border-radius:10px;font-size:14px;line-height:1.6;font-weight:500;border:1px solid transparent;cursor:pointer;transition:.15s;font-family:inherit}
.vlanding .vbtn-primary{background:var(--vaccent2);color:#fff}
.vlanding .vbtn-ghost{background:none;color:var(--vdim);border-color:var(--vline)}
.vlanding .vbtn-ghost:hover{color:var(--vtext);border-color:var(--vfaint)}
.vlanding .vcontact{max-width:620px;margin:0 auto;text-align:center}
.vlanding .vcontact h2{font-size:clamp(22px,3.4vw,32px);font-weight:800;letter-spacing:-.5px;margin:0 0 10px}
.vlanding .vcontact p{color:var(--vdim);font-size:15px;margin:0 0 18px}
.vlanding .vcontact a{color:var(--vgood)}
.vlanding .vcontact input,.vlanding .vcontact textarea{width:100%;background:var(--vpanel);
  border:1px solid var(--vline);border-radius:10px;color:var(--vtext);padding:11px 14px;
  font-size:14px;font-family:inherit;margin-bottom:10px;box-sizing:border-box}
.vlanding .vcontact textarea{resize:vertical}
.vlanding .vcontact input:focus,.vlanding .vcontact textarea:focus{outline:none;border-color:var(--vaccent)}
.vlanding .vc-row{display:flex;align-items:center;gap:14px;justify-content:center}
.vlanding .vc-status{font-size:13px;color:var(--vgood);text-align:left}
.vlanding .vbtn-primary:hover{background:#5c34e6}
.vlanding .vhero{padding:74px 0 48px;text-align:center;position:relative;overflow:hidden}
.vlanding .vhero::before{content:"";position:absolute;inset:-40% 0 auto;height:520px;background:radial-gradient(60% 60% at 50% 0%,rgba(110,91,255,.18),transparent 70%);pointer-events:none}
/* --vaccent-txt, not --vaccent: the brand purple is 4.26:1 on --vbg and 3.82:1 on --vpanel,
   so it fails AA everywhere it carries small text. #8f7bff is 5.96:1 and 5.36:1, and it was
   already in the palette (.vh1 .vgrad, .vtag .p). --vaccent still fills buttons and icons,
   where it only has to clear 3:1. */
.vlanding .veyebrow{display:inline-block;font-size:12.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--vaccent-txt);font-weight:600;margin-bottom:18px;position:relative}
.vlanding .vh1{font-size:clamp(34px,6vw,58px);line-height:1.05;font-weight:700;letter-spacing:-1px;margin:0 0 24px;position:relative}
.vlanding .vh1 .vgrad{background:linear-gradient(120deg,#8f7bff,#4f2bd4);-webkit-background-clip:text;background-clip:text;color:transparent}
.vlanding .vstat{margin:0 auto 18px;max-width:600px;position:relative}
.vlanding .vstat-num{display:block;font-size:clamp(28px,5vw,44px);font-weight:800;letter-spacing:-1px;line-height:1.05;background:linear-gradient(90deg,#2fd47f,#7cf0b0);-webkit-background-clip:text;background-clip:text;color:transparent}
.vlanding .vstat-sub{display:block;font-size:14px;color:var(--vdim);line-height:1.55;margin-top:10px}
.vlanding .vhsub{font-size:clamp(15px,2.2vw,18px);color:var(--vdim);max-width:560px;margin:0 auto 30px;position:relative}
.vlanding .vdl{position:relative;max-width:420px;margin:0 auto;padding:20px 20px 18px;background:var(--vpanel);border:1px solid var(--vline);border-radius:16px;text-align:left}
.vlanding .vdl-title{font-size:13px;font-weight:600;text-align:center;margin-bottom:12px}
.vlanding .vdl-title .vmuted{color:var(--vfaint);font-weight:400}
.vlanding .vdl input{width:100%;font-size:13px;padding:9px 12px;border-radius:9px;border:1px solid var(--vline);background:var(--vbg2);color:var(--vtext);font-family:inherit;margin-bottom:8px}
.vlanding .vdl input:focus{outline:none;border-color:var(--vaccent)}
.vlanding .vdl .verror{color:#ff6b6b;font-size:12px;margin-bottom:8px}
.vlanding .vdl-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:11px 14px;border-radius:9px;border:1px solid var(--vline);background:var(--vbg2);color:var(--vtext);font-size:14px;font-weight:500;cursor:pointer;font-family:inherit;margin-bottom:8px;transition:.15s}
.vlanding .vdl-btn:hover{border-color:var(--vaccent);color:var(--vaccent)}
.vlanding .vdl-btn svg{width:15px;height:15px}
.vlanding .vdl-btn.disabled{opacity:.5;cursor:not-allowed}
.vlanding .vdl-btn.disabled:hover{border-color:var(--vline);color:var(--vtext)}
.vlanding .vdl-note{font-size:11.5px;color:var(--vfaint);text-align:center;line-height:1.5;margin-top:4px}
.vlanding .vdl-have{font-size:11.5px;color:var(--vdim);text-align:center;line-height:1.5;margin-top:10px;padding-top:10px;border-top:1px solid var(--vline)}
.vlanding .vnav.on{color:var(--vtext);border-color:var(--vfaint)}

/* --- the header menu ---------------------------------------------------------------
   The bar is one flex row that needed a constant 557px no matter the screen. No handset
   has that, so below ~720px the four nav links and Sign in were laid out past the right
   edge - and because nothing wrapped, they took the whole document's width to 557px with
   them and could not be scrolled to. "Request an invite", the one button the page exists
   for, sat 84px off the side of an iPhone.

   Below the breakpoint those links move into a disclosure menu. It is <details>/<summary>
   rather than a scripted dropdown so it still opens with JavaScript off, which is the rule
   the rest of this site follows; site.js only adds Escape, tap-outside and close-on-follow.

   The links appear twice in the markup - once in .vnav-row for the wide bar, once in the
   panel - because only one of the two is ever rendered. display:none removes the other
   from the accessibility tree as well as the page, so nothing is announced twice. */
.vlanding .vnav-row{display:flex;align-items:center;gap:12px}
.vlanding .vmenu{display:none;position:relative;flex:0 0 auto}
.vlanding .vmenu > summary{display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:10px;border:1px solid var(--vline);
  background:none;color:var(--vdim);cursor:pointer;list-style:none;transition:.15s}
.vlanding .vmenu > summary::-webkit-details-marker{display:none}
.vlanding .vmenu > summary::marker{content:""}
.vlanding .vmenu > summary svg{width:20px;height:20px;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;pointer-events:none}
.vlanding .vmenu > summary:focus-visible{outline:2px solid var(--vaccent);outline-offset:2px}
.vlanding .vmenu[open] > summary{color:var(--vtext);border-color:var(--vfaint);
  background:var(--vpanel)}
.vlanding .vmenu[open] > summary .vmenu-open{display:none}
.vlanding .vmenu:not([open]) > summary .vmenu-close{display:none}
.vlanding .vmenu-panel{position:absolute;right:0;top:calc(100% + 10px);min-width:210px;
  display:flex;flex-direction:column;gap:6px;padding:10px;background:var(--vpanel);
  border:1px solid var(--vline);border-radius:14px;
  box-shadow:0 18px 50px rgba(0,0,0,.5);z-index:20}
/* Required, and not obviously so: giving a <details> child an explicit display overrides
   the closed state the browser applies for you, so the panel above hung open permanently
   until this rule put it back. */
.vlanding .vmenu:not([open]) > .vmenu-panel{display:none}
.vlanding .vmenu-panel .vbtn{width:100%;justify-content:flex-start}
/* The invite box: hero, foot of the guide, and inside one FAQ answer. */
.vlanding .vinvite{margin:0 0 10px}
.vlanding .vinvite-row{display:flex;gap:8px}
.vlanding .vinvite-row input{flex:1;min-width:0;font-size:14px;padding:11px 13px;border-radius:10px;
  border:1px solid var(--vline);background:var(--vbg2);color:var(--vtext);font-family:inherit}
.vlanding .vinvite-row input:focus{outline:none;border-color:var(--vaccent)}
.vlanding .vinvite-row .vbtn{flex:0 0 auto;white-space:nowrap}
.vlanding .vinvite-msg{font-size:13px;color:var(--vgood);margin-top:9px;line-height:1.5}
.vlanding .vinvite-msg.bad{color:#ff6b6b}
.vlanding .vinvite.compact{margin:14px 0 0;max-width:460px}
.vlanding .vinvite.compact .vinvite-row input{font-size:13.5px;padding:9px 12px}
.vlanding .vinvite.compact .vbtn{padding:9px 14px;font-size:13.5px}
@media(max-width:520px){.vlanding .vinvite-row{flex-direction:column}}

.vlanding .vfaq{border-bottom:1px solid var(--vline);padding:22px 0}
.vlanding .vfaq:last-child{border-bottom:none}
.vlanding .vfaq h3{font-size:17px;font-weight:600;margin:0 0 8px;letter-spacing:-.2px}
.vlanding .vfaq p{color:var(--vdim);font-size:15px;line-height:1.62;margin:0}

/* --- UI illustrations ---------------------------------------------------------
   Drawings of the app, not screenshots. Nick's call: real captures would go stale
   every time the UI moved, and his catalogs hold client footage that shouldn't be
   published. Kept deliberately schematic so they show the SHAPE of the product
   without impersonating it - which is both honester and survives the UI changing. */
.vlanding .vshot{background:var(--vbg2);border:1px solid var(--vline);border-radius:14px;overflow:hidden;box-shadow:0 18px 50px rgba(0,0,0,.35)}
.vlanding .vshot-bar{display:flex;align-items:center;gap:6px;padding:10px 14px;border-bottom:1px solid var(--vline);background:var(--vpanel)}
.vlanding .vshot-dot{width:9px;height:9px;border-radius:50%;background:var(--vline)}
.vlanding .vshot-title{margin-left:8px;font-size:11.5px;color:var(--vfaint)}
.vlanding .vshot-cols{display:grid;grid-template-columns:1fr 1.35fr 1.15fr;min-height:250px}
.vlanding .vshot-col{padding:14px;border-right:1px solid var(--vline)}
.vlanding .vshot-col:last-child{border-right:none}
.vlanding .vshot-lbl{font-size:10px;letter-spacing:1.1px;text-transform:uppercase;color:var(--vfaint);margin-bottom:10px}
.vlanding .vrow{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;font-size:12px;color:var(--vdim);margin-bottom:3px}
.vlanding .vrow.on{background:rgba(110,91,255,.14);color:var(--vtext)}
.vlanding .vdot{width:6px;height:6px;border-radius:50%;background:var(--vgood);flex:0 0 auto}
.vlanding .vbarline{height:7px;border-radius:4px;background:var(--vline);flex:1}
.vlanding .vframe{aspect-ratio:16/9;border-radius:8px;background:#1c2130 url(harbor.svg) center/cover no-repeat;border:1px solid var(--vline);margin-bottom:10px;position:relative;overflow:hidden}
.vlanding .vscrub{position:absolute;left:8px;right:8px;bottom:8px;height:5px;border-radius:3px;background:rgba(255,255,255,.14)}
.vlanding .vscrub i{position:absolute;left:0;top:0;bottom:0;width:38%;border-radius:3px;background:var(--vaccent);display:block}
.vlanding .vmeta{font-size:11px;color:var(--vfaint);line-height:1.9}
.vlanding .vchip{display:inline-block;font-size:10.5px;padding:2px 8px;border-radius:999px;background:rgba(110,91,255,.16);color:#b9adff;margin:0 4px 4px 0}
.vlanding .vtline{display:flex;gap:10px;font-size:12px;color:var(--vdim);padding:4px 0;line-height:1.5}
.vlanding .vtc{color:var(--vaccent-txt);font-variant-numeric:tabular-nums;flex:0 0 auto}
.vlanding .vtline.hit{color:var(--vtext)}
.vlanding .vtline.hit mark{background:rgba(57,224,138,.22);color:var(--vgood);border-radius:3px;padding:0 3px}
.vlanding .vshot-cap{font-size:12px;color:var(--vfaint);text-align:center;margin-top:12px;line-height:1.55}
.vlanding .vsearchbar{display:flex;align-items:center;gap:9px;padding:9px 12px;border:1px solid var(--vline);border-radius:9px;background:var(--vbg2);font-size:13px;color:var(--vtext);margin-bottom:12px}
.vlanding .vsearchbar svg{width:14px;height:14px;stroke:var(--vfaint);fill:none;stroke-width:2;flex:0 0 auto}
@media(max-width:720px){.vlanding .vshot-cols{grid-template-columns:1fr}.vlanding .vshot-col{border-right:none;border-bottom:1px solid var(--vline)}}
.vlanding .vsection{padding:60px 0}
.vlanding .vsec-head{text-align:center;max-width:640px;margin:0 auto 40px}
.vlanding .vsec-head h2{font-size:clamp(24px,4vw,36px);font-weight:700;letter-spacing:-.5px;margin:0 0 12px}
.vlanding .vsec-head p{color:var(--vdim);font-size:16px;margin:0}
.vlanding .vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:18px}
.vlanding .vcard{background:var(--vpanel);border:1px solid var(--vline);border-radius:16px;padding:26px;transition:.15s}
.vlanding .vcard:hover{border-color:#33405e;transform:translateY(-2px)}
.vlanding .vcard .vic{width:42px;height:42px;border-radius:11px;background:rgba(110,91,255,.14);display:flex;align-items:center;justify-content:center;margin-bottom:16px}
.vlanding .vcard .vic svg{width:22px;height:22px;stroke:var(--vaccent);fill:none;stroke-width:1.8}
.vlanding .vcard h3{font-size:17px;font-weight:600;margin:0 0 8px}
.vlanding .vcard p{color:var(--vdim);font-size:14.5px;margin:0}
.vlanding .vsteps{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px;counter-reset:vstep}
.vlanding .vstep{position:relative;background:var(--vbg2);border:1px solid var(--vline);border-radius:16px;padding:28px 24px}
.vlanding .vstep::before{counter-increment:vstep;content:counter(vstep);position:absolute;top:-16px;left:24px;width:34px;height:34px;border-radius:9px;background:var(--vaccent2);color:#fff;font-weight:700;display:flex;align-items:center;justify-content:center;font-size:15px}
.vlanding .vstep h3{font-size:16px;font-weight:600;margin:14px 0 8px}
.vlanding .vstep p{color:var(--vdim);font-size:14px;margin:0}
.vlanding .vfoot{border-top:1px solid var(--vline);padding:32px 0;color:var(--vfaint);font-size:13px}
.vlanding .vfoot-in{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.vlanding .vfoot-in .vspacer{flex:1}
/* The footer runs at 13px, so the header's 40px tile and 18px wordmark arrive here far too
   large for the row they sit in. Same lockup, scaled to the type around it. */
.vlanding .vfoot .vmark{width:30px;height:30px;border-radius:9px;box-shadow:none}
.vlanding .vfoot .vmark svg{width:17px;height:17px}
.vlanding .vfoot .vname{font-size:16px;color:var(--vdim)}
/* Below the breakpoint the seven links wrap onto three or four ragged lines pinned right by
   the spacer. Stack the lockup over a left-aligned set of links instead. */
@media(max-width:720px){
  .vlanding .vfoot-in{gap:8px}
  .vlanding .vfoot-in .vspacer{flex:0 0 100%}
  .vlanding .vfoot .vbtn{padding:8px 12px}
}
.vlanding .vstory{max-width:680px;margin:0 auto;text-align:center}
.vlanding .vstory h2{font-size:clamp(24px,4vw,34px);font-weight:700;letter-spacing:-.5px;line-height:1.15;margin:0 0 16px}
.vlanding .vstory p{color:var(--vdim);font-size:clamp(15px,2vw,17px);line-height:1.62;margin:0 0 14px}
.vlanding .vstory p:last-child{margin-bottom:0}
.vlanding .vstory .vlede{color:var(--vtext);font-weight:600}
.vlanding .vtint{background:linear-gradient(180deg,transparent,rgba(110,91,255,.06),transparent)}
.vlanding .vhonesty{max-width:640px;margin:0 auto;background:var(--vpanel);border:1px solid var(--vline);border-radius:18px;padding:32px 30px;text-align:center}
.vlanding .vhonesty h2{font-size:clamp(22px,3.4vw,30px);font-weight:700;margin:0 0 14px}
.vlanding .vhonesty p{color:var(--vdim);font-size:15px;line-height:1.6;margin:0 0 16px}
/* Scoped to .vhonesty originally, but .vtag is used in a .vstory block too, where it
   rendered as plain gray body text with none of the emphasis it exists for. */
.vlanding .vtag{font-weight:700;color:var(--vtext);font-size:clamp(15px,2.2vw,17px)}
.vlanding .vtag .g{color:var(--vgood)}
.vlanding .vtag .p{color:#8f7bff}
.vlanding .vprice{max-width:560px;margin:0 auto;text-align:center}
.vlanding .vprice h2{font-size:clamp(24px,4vw,34px);font-weight:700;margin:0 0 14px}
.vlanding .vprice h2 .g{color:var(--vgood)}
.vlanding .vprice p{color:var(--vdim);font-size:15.5px;line-height:1.6;margin:0}
.vlanding .vclose{text-align:center;padding:8px 0 4px}
.vlanding .vclose .vbig{font-size:clamp(26px,4.8vw,44px);font-weight:800;letter-spacing:-1px;line-height:1.1;max-width:760px;margin:0 auto 26px}
.vlanding .vclose .vbig .g{background:linear-gradient(120deg,#39e08a,#7cf0b0);-webkit-background-clip:text;background-clip:text;color:transparent}
/* The line under the closing headline. Narrower than the headline on purpose: it is a
   sentence to be read, not a slogan to be scanned, and full width at this size runs to
   the sort of measure nobody finishes. */
.vlanding .vclose .vclose-sub{max-width:600px;margin:-12px auto 26px;color:var(--vdim);font-size:clamp(14.5px,2vw,16px);line-height:1.6}
.vlanding .vclose .vclose-sub strong{color:var(--vtext)}
@media(max-width:720px){.vlanding .vhero{padding:52px 0 36px}.vlanding .vsection{padding:44px 0}.vlanding .vhonesty{padding:26px 20px}}

/* The landing's split hero: the pitch and the invite box on the left, the app on the
   right, so the first screen shows the product instead of describing it. Below 900px
   the two stack, pitch first, and the hero goes back to centered. */
.vlanding .vhero-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:52px;align-items:center;text-align:left;position:relative}
.vlanding .vhero-grid .vh1{font-size:clamp(34px,5vw,54px);font-weight:800;letter-spacing:-1.5px;text-wrap:balance}
.vlanding .vhero-grid .vhsub{margin:0 0 26px}
.vlanding .vhero-grid .vdl{margin:0}
.vlanding .vhero-grid .vshot-cap{margin-top:12px}
@media(max-width:900px){
  .vlanding .vhero-grid{grid-template-columns:minmax(0,1fr);gap:40px;text-align:center}
  .vlanding .vhero-grid .vhsub,.vlanding .vhero-grid .vdl{margin-left:auto;margin-right:auto}
}
/* The one number that carries the pitch, as the three facts it is made of. */
.vlanding .vstats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:56px;background:var(--vbg2);border:1px solid var(--vline);border-radius:16px;position:relative}
.vlanding .vstats > div{padding:22px 26px;border-right:1px solid var(--vline);text-align:left}
.vlanding .vstats > div:last-child{border-right:none}
.vlanding .vstats b{display:block;font-size:clamp(26px,3.6vw,34px);font-weight:800;letter-spacing:-1px;line-height:1.1}
.vlanding .vstats span{font-size:13.5px;color:var(--vfaint)}
.vlanding .vstats .g{color:var(--vgood)}
@media(max-width:620px){
  .vlanding .vstats{grid-template-columns:minmax(0,1fr)}
  .vlanding .vstats > div{border-right:none;border-bottom:1px solid var(--vline)}
  .vlanding .vstats > div:last-child{border-bottom:none}
}
/* "Not cloud storage": the argument on the left, the two cases it separates on the right. */
.vlanding .vband{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px;align-items:center;background:var(--vpanel);border:1px solid var(--vline);border-radius:18px;padding:40px 44px}
.vlanding .vband h2{font-size:clamp(22px,3.4vw,30px);font-weight:700;margin:0 0 14px}
.vlanding .vband p{color:var(--vdim);font-size:15px;line-height:1.6;margin:0}
.vlanding .vtiles{display:grid;gap:12px}
.vlanding .vtile{padding:16px 20px;border-radius:12px;border:1px solid var(--vline)}
.vlanding .vtile span{display:block;font-size:13px;color:var(--vfaint)}
.vlanding .vtile b{font-size:19px;font-weight:700}
.vlanding .vtile.g{border-color:var(--vgood)}
.vlanding .vtile.g b{color:var(--vgood)}
/* THE LANDING AS A SEQUENCE. Timeline grammar borrowed from the edit bay the reader works
   in: a playhead under the nav, timecoded section labels, in/out marks, color bars, an
   end-of-sequence slate. website/assets/sequence.js fills in the numbers; without it the
   labels still read and the playhead sits at 00:00:00:00. */
.vlanding{--vmono:ui-monospace,"SF Mono",Menlo,Consolas,monospace}
/* Sticky directly under the 64px bar and its 1px rule, so it rides along as a second rail. */
.vlanding .vplayhead{position:sticky;top:65px;z-index:9;height:20px;background:rgba(18,21,29,.92);border-bottom:1px solid var(--vline);backdrop-filter:blur(10px)}
.vlanding .vplayhead-in{position:relative;height:100%;background:repeating-linear-gradient(90deg,#2a3040 0 1px,transparent 1px 24px) 0 12px/100% 8px repeat-x;background-clip:content-box}
.vlanding .vplayhead i{position:absolute;top:0;bottom:0;left:calc(24px + (100% - 48px) * var(--at,0));width:2px;background:var(--vaccent)}
.vlanding .vplayhead i::before{content:"";position:absolute;top:0;left:-6px;border:7px solid transparent;border-top:8px solid var(--vaccent);border-bottom:0}
.vlanding .vplayhead-tc{position:absolute;right:24px;top:2px;font:500 11px/16px var(--vmono);letter-spacing:.4px;color:var(--vaccent-txt);white-space:pre}
.vlanding .vseq-tc{display:inline-block;font:500 12px/1.4 var(--vmono);letter-spacing:.6px;text-transform:uppercase;color:var(--vaccent-txt);margin-bottom:12px}
.vlanding .veyebrow.vseq{font-family:var(--vmono);font-weight:500;letter-spacing:.6px}
/* In and out marks: around the headline always, around a primary button while you point at it. */
.vlanding .vhero-grid .vh1{position:relative;padding:0 26px;margin-left:-26px;width:fit-content;max-width:calc(100% + 26px)}
.vlanding .vhero-grid .vh1::before,.vlanding .vhero-grid .vh1::after{content:"";position:absolute;top:.12em;bottom:.12em;width:11px;border:3px solid var(--vaccent)}
.vlanding .vhero-grid .vh1::before{left:0;border-right:none}
.vlanding .vhero-grid .vh1::after{right:0;border-left:none}
@media(max-width:900px){.vlanding .vhero-grid .vh1{margin-left:auto;margin-right:auto;max-width:100%}}
.vlanding .vbtn-primary{position:relative}
.vlanding .vbtn-primary::before,.vlanding .vbtn-primary::after{content:"";position:absolute;top:4px;bottom:4px;width:6px;border:2px solid var(--vaccent-txt);opacity:0;transition:opacity .15s,transform .15s}
.vlanding .vbtn-primary::before{left:-11px;border-right:none;transform:translateX(4px)}
.vlanding .vbtn-primary::after{right:-11px;border-left:none;transform:translateX(-4px)}
.vlanding .vbtn-primary:hover::before,.vlanding .vbtn-primary:hover::after,
.vlanding .vbtn-primary:focus-visible::before,.vlanding .vbtn-primary:focus-visible::after{opacity:1;transform:none}
/* Shuttle-key hint: only where there is a keyboard to press them on. */
.vlanding .vhint{display:none;margin:-12px 0 24px;font-size:13px;color:var(--vfaint)}
.vlanding .vhint kbd{display:inline-block;min-width:22px;padding:1px 6px;margin:0 1px;border:1px solid #3a4152;border-bottom-width:2px;border-radius:5px;background:var(--vbg2);font:600 12px/18px var(--vmono);color:var(--vtext);text-align:center}
@media(hover:hover) and (pointer:fine){.vlanding .vhint{display:block}}
.vlanding .vaside{margin:14px 0 0;text-align:right;font:13px/1.5 var(--vmono);color:var(--vfaint);position:relative}
@media(max-width:620px){.vlanding .vaside{text-align:left}}
/* SMPTE bars, once, as the page's one loud divider. */
.vlanding .vbars{height:8px;border-radius:3px;opacity:.7;background:linear-gradient(90deg,#c0c0c0 0 14.28%,#c0c000 0 28.57%,#00c0c0 0 42.85%,#00c000 0 57.14%,#c000c0 0 71.42%,#c00000 0 85.71%,#0000c0 0)}
.vlanding .vend{border-top:1px solid var(--vline);padding:22px 0}
.vlanding .vend-in{display:flex;flex-wrap:wrap;gap:8px 24px;justify-content:space-between;font-size:13.5px;color:var(--vfaint)}
.vlanding .vend-in b{color:var(--vtext);font-weight:600}
.vlanding .vend-in [data-tc-end]{font-family:var(--vmono);color:var(--vaccent-txt)}
/* Invite box states. Sending draws an indeterminate render bar - there is no real
   percentage to show, so it doesn't pretend to have one. */
.vlanding .vinvite-msg.busy{color:var(--vdim)}
.vlanding .vinvite-msg.busy::after{content:"";display:block;height:4px;margin-top:8px;border-radius:2px;background:linear-gradient(90deg,transparent,var(--vaccent),transparent) 0 0/40% 100% no-repeat var(--vbg2);animation:vrender 1.1s linear infinite}
@keyframes vrender{from{background-position:-40% 0}to{background-position:140% 0}}
.vlanding .vinvite-msg.bad::before{content:"MEDIA OFFLINE";display:inline-block;margin-right:8px;padding:1px 6px;border-radius:4px;background:rgba(255,107,107,.14);font:700 10.5px/16px var(--vmono);letter-spacing:.6px}
@media (prefers-reduced-motion:reduce){
  .vlanding .vinvite-msg.busy::after{animation:none;background:var(--vaccent)}
  .vlanding .vbtn-primary::before,.vlanding .vbtn-primary::after{transition:none}
}

/* THE TIMELINE RAIL: the landing's desktop layout. A sticky left rail carries the brand,
   the page's clips (a bin of the sections, the one on screen lit), the invite, sign-in and
   nav; the content runs left-aligned beside it. Only the landing opts in, with .vrailed on
   its root, and only above 900px: below that the rail is hidden and the ordinary top bar
   and playhead strip - which the rail replaces on desktop - come back. */
.vlanding .vrail{display:none}
.vlanding.vrailed [data-tc],.vlanding.vrailed #top{scroll-margin-top:100px}
@media(min-width:901px){
  .vlanding.vrailed > .vhead,.vlanding.vrailed > .vplayhead{display:none}
  .vlanding.vrailed [data-tc],.vlanding.vrailed #top{scroll-margin-top:32px}
  .vlanding.vrailed .vrail-body{display:grid;grid-template-columns:284px minmax(0,1fr)}
  .vlanding.vrailed .vrail{position:sticky;top:0;height:100vh;overflow-y:auto;display:flex;flex-direction:column;gap:26px;padding:22px 18px;background:#0e1016;border-right:1px solid var(--vline)}
  .vlanding .vrail-brand{display:flex;align-items:center;gap:10px;cursor:pointer}
  .vlanding .vrail-lbl{display:block;font-size:10.5px;letter-spacing:1.2px;text-transform:uppercase;color:var(--vfaint);font-weight:600;margin:0 0 8px}
  /* The bin, with a thin track down its left edge and a playhead that runs it as you scroll. */
  .vlanding .vrail-clips{position:relative;display:flex;flex-direction:column;gap:2px;padding-left:14px}
  .vlanding .vrail-clips::before{content:"";position:absolute;left:3px;top:26px;bottom:6px;width:1px;background:var(--vline)}
  .vlanding .vrail-clips::after{content:"";position:absolute;left:1px;width:5px;height:14px;border-radius:2px;background:var(--vaccent);top:calc(26px + (100% - 46px) * var(--at,0))}
  .vlanding .vrail-clips a{display:flex;align-items:center;gap:10px;padding:10px;border-radius:8px;font:12px/1.3 var(--vmono);color:var(--vfaint)}
  .vlanding .vrail-clips a::before{content:"";width:9px;height:9px;border-radius:2px;background:#2a3040;flex-shrink:0}
  .vlanding .vrail-clips a:hover{color:var(--vtext)}
  .vlanding .vrail-clips a.on{background:rgba(110,91,255,.16);color:var(--vtext)}
  .vlanding .vrail-clips a.on::before{background:var(--vaccent)}
  .vlanding .vrail-cta{display:flex;flex-direction:column;gap:8px}
  .vlanding .vrail-cta .vbtn{justify-content:center;min-height:44px}
  .vlanding .vrail-links{display:flex;flex-direction:column}
  .vlanding .vrail-links a,.vlanding .vrail-links button{padding:8px 10px;font-size:13.5px;color:var(--vdim);background:none;border:0;text-align:left;font-family:inherit;cursor:pointer}
  .vlanding .vrail-links a:hover,.vlanding .vrail-links button:hover{color:var(--vtext)}
  .vlanding .vrail-hint{margin:0;font-size:12.5px;color:var(--vfaint)}
  .vlanding .vrail-hint kbd{display:inline-block;min-width:22px;padding:1px 6px;margin:0 1px;border:1px solid #3a4152;border-bottom-width:2px;border-radius:5px;background:var(--vbg2);font:600 12px/18px var(--vmono);color:var(--vtext);text-align:center}

  /* Content beside the rail: left-aligned throughout, one measure. */
  .vlanding.vrailed .vrail-main .vwrap{max-width:960px;margin:0;padding:0 72px}
  .vlanding.vrailed .vhero{text-align:left;padding:80px 0 40px}
  .vlanding.vrailed .vhero-grid{grid-template-columns:minmax(0,1fr);gap:44px;text-align:left}
  .vlanding.vrailed .vhero-grid .vdl{max-width:460px}
  .vlanding.vrailed .vhero-grid .vshot-cap{text-align:left}
  .vlanding.vrailed .vhint{display:none}
  .vlanding.vrailed .vstats{background:none;border-width:1px 0;border-radius:0;margin-top:40px}
  .vlanding.vrailed .vstats > div{border-right:0;padding:20px 0}
  .vlanding.vrailed .vaside{text-align:left}
  .vlanding.vrailed .vstory,.vlanding.vrailed .vprice{max-width:700px;margin:0;text-align:left}
  .vlanding.vrailed .vsec-head{text-align:left;max-width:700px;margin:0 0 32px}
  /* How it works as a clip's life: in, hold, out, along one line. */
  .vlanding.vrailed .vsteps{gap:0;border-top:2px solid var(--vaccent)}
  .vlanding.vrailed .vstep{background:none;border:0;border-left:1px solid var(--vline);border-radius:0;padding:18px 20px 0}
  .vlanding.vrailed .vstep:first-child{border-left:0;padding-left:0}
  .vlanding.vrailed .vstep::before{position:static;display:block;width:auto;height:auto;background:none;border-radius:0;font:500 12px/1 var(--vmono);letter-spacing:.6px;color:var(--vaccent-txt)}
  .vlanding.vrailed .vstep:nth-child(1)::before{content:"IN"}
  .vlanding.vrailed .vstep:nth-child(2)::before{content:"HOLD"}
  .vlanding.vrailed .vstep:nth-child(3)::before{content:"OUT"}
  .vlanding.vrailed .vstep h3{margin:10px 0 8px}
  /* The six features as a plain list: name on the left, what it does on the right. */
  .vlanding.vrailed .vgrid{display:block}
  .vlanding.vrailed .vcard{display:grid;grid-template-columns:230px minmax(0,1fr);gap:24px;background:none;border:0;border-top:1px solid var(--vline);border-radius:0;padding:16px 0}
  .vlanding.vrailed .vcard:last-child{border-bottom:1px solid var(--vline)}
  .vlanding.vrailed .vcard:hover{transform:none}
  .vlanding.vrailed .vcard .vic{display:none}
  .vlanding.vrailed .vcard h3{margin:0;font-size:15.5px}
  .vlanding.vrailed .vband{grid-template-columns:minmax(0,1fr);gap:20px;background:none;border:0;border-radius:0;padding:0}
  .vlanding.vrailed .vtiles{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
  .vlanding.vrailed .vclose{text-align:left}
  .vlanding.vrailed .vclose .vbig{margin:0 0 26px}
  .vlanding.vrailed .vclose .vclose-sub{margin:-12px 0 26px}
  .vlanding.vrailed .vcontact{margin:0;text-align:left}
  .vlanding.vrailed .vc-row{justify-content:flex-start}
}

@media(max-width:720px){.vlanding .vband{grid-template-columns:minmax(0,1fr);padding:26px 20px;gap:24px}}

/* The two legal documents (terms.html, acceptable-use.html). Both pages are
 * GENERATED from LEGAL/*.md by scripts/build_legal_pages.py; these are the only
 * rules they need on top of the site's own. A `[PLACEHOLDER: ...]` span is an open
 * question for counsel rather than a term of the agreement, and .vtodo is what stops
 * the two looking alike. */
.vlanding .vlegal{max-width:760px;margin:0 auto;padding:0 0 20px}
.vlanding .vlegal h2{font-size:clamp(20px,3vw,27px);font-weight:700;letter-spacing:-.4px;
  line-height:1.2;margin:44px 0 12px;padding-top:8px}
.vlanding .vlegal h2:first-child{margin-top:0}
.vlanding .vlegal h3{font-size:clamp(16px,2.2vw,19px);font-weight:600;margin:28px 0 10px}
.vlanding .vlegal h4{font-size:15px;font-weight:600;margin:22px 0 8px}
.vlanding .vlegal p,.vlanding .vlegal li{color:var(--vdim);font-size:15.5px;line-height:1.68}
.vlanding .vlegal p{margin:0 0 14px}
.vlanding .vlegal ul,.vlanding .vlegal ol{margin:0 0 16px;padding-left:22px}
.vlanding .vlegal li{margin:0 0 8px}
.vlanding .vlegal strong{color:var(--vtext)}
.vlanding .vlegal a{color:var(--vgood);text-decoration:underline}
.vlanding .vlegal hr{border:0;border-top:1px solid var(--vline);margin:34px 0}
.vlanding .vlegal code.vtodo{background:rgba(255,176,60,.09);border-color:rgba(255,176,60,.35);
  color:#ffc66b}
.vlanding .vlegal code{background:var(--vbg2);border:1px solid var(--vline);border-radius:5px;
  padding:1px 5px;font-size:13px;color:var(--vtext);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.vlanding .vlegal-head{max-width:760px;margin:0 auto 30px}
.vlanding .vlegal-head .vh1{font-size:clamp(28px,5vw,42px);margin-bottom:12px}
.vlanding .vlegal-note{color:var(--vfaint);font-size:13.5px;line-height:1.6}
/* Anchors land under the 65px sticky header otherwise. Clicking "Get VAMP" at the foot of
   the page put the top 65px of the invite card - its heading included - behind the bar. */
.vlanding [id]{scroll-margin-top:80px}
.vlanding .vcta-short{display:none}

@media(max-width:720px){
  .vlanding .vhero{padding:52px 0 36px}
  .vlanding .vsection{padding:44px 0}
  .vlanding .vhonesty{padding:26px 20px}

  /* the bar collapses to: mark, wordmark, CTA, menu */
  .vlanding .vnav-row{display:none}
  .vlanding .vmenu{display:block}
  .vlanding .vbar{gap:10px;padding-top:9px;padding-bottom:9px}
  .vlanding .vbar .vbtn-primary{padding:10px 14px}

  /* 16px or iOS Safari zooms the whole page the moment a field takes focus, which is a
     rough way to treat the one action this site asks for. */
  .vlanding .vinvite-row input,
  .vlanding .vinvite.compact .vinvite-row input,
  .vlanding .vdl input,
  .vlanding .vcontact input,
  .vlanding .vcontact textarea{font-size:16px;min-height:44px}
  .vlanding .vcontact textarea{min-height:110px}

  /* small on a desktop is very small in the hand. The illustration's own labels go up
     with it, having grown to full width while their type stayed at 10px. */
  .vlanding .vdl-note,.vlanding .vdl-have{font-size:13px}
  .vlanding .vshot-lbl{font-size:11px}
  .vlanding .vchip{font-size:11.5px}
  .vlanding .vmeta{font-size:12px}
  .vlanding .vshot-cap{font-size:13px}
  .vlanding .vrow,.vlanding .vtline{font-size:13px}
  .vlanding .vshot-cols{min-height:0}
}

/* At this width "Request an invite" no longer fits beside the wordmark and the menu. */
@media(max-width:420px){
  .vlanding .vcta-full{display:none}
  .vlanding .vcta-short{display:inline}
}

/* --- 404 (website/404.html) ----------------------------------------------------------
   Served at whatever address somebody got wrong, so it has to look like the site from a
   cold start: no page-specific state, nothing to load, and it reads with the stylesheet
   missing too, which is what happens if it is opened off disk. */
.vlanding .v404{padding:48px 0 64px}
.vlanding .v404 .vh1{font-size:clamp(30px,5.2vw,48px);text-wrap:balance}
.vlanding .v404-tag{position:relative;max-width:560px;margin:0 auto 28px}
.vlanding .v404-tag-sub{display:block;margin-top:8px;font-size:15px;font-weight:400;
  color:var(--vdim)}
.vlanding .v404-doors{position:relative;display:flex;flex-wrap:wrap;gap:10px;
  justify-content:center}
.vlanding .v404-doors .vbtn:focus-visible{outline:2px solid var(--vaccent-txt);outline-offset:2px}
/* The viewer + timeline. The red is the NLE's own offline red and lives only in here:
   everywhere else on the page stays violet, so it reads as the error, not a new accent. */
.vlanding .v404-rig{--v404-red:#ff5a67;--v404-mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  position:relative;max-width:680px;margin:0 auto 34px;text-align:left}
.vlanding .v404-view{position:relative;aspect-ratio:16/9;max-width:100%;background:#040509;
  border:1px solid var(--vline);border-radius:12px 12px 0 0;overflow:hidden}
.vlanding .v404-grain{position:absolute;inset:0;width:100%;height:100%;opacity:.5}
.vlanding .v404-safe{position:absolute;inset:9% 7%;border:1px dashed rgba(124,134,152,.18);border-radius:2px}
.vlanding .v404-hud{position:absolute;left:14px;right:14px;top:10px;display:flex;justify-content:space-between;
  gap:10px;font-family:var(--v404-mono);font-size:11px;color:var(--vfaint);letter-spacing:.4px}
.vlanding .v404-tc{color:var(--vtext);font-variant-numeric:tabular-nums}
.vlanding .v404-msg{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:10px;padding:0 20px}
.vlanding .v404-stamp{font-family:var(--v404-mono);font-weight:700;font-size:clamp(18px,4.2vw,32px);
  letter-spacing:.14em;text-transform:uppercase;color:var(--v404-red);
  text-shadow:0 0 22px rgba(255,90,103,.35);animation:v404-flick 5s steps(1) infinite}
.vlanding .v404-path{font-family:var(--v404-mono);font-size:clamp(11px,1.6vw,13px);color:var(--vdim);
  max-width:100%;overflow-wrap:anywhere;text-align:center}
.vlanding .v404-path span:first-child{color:var(--vfaint)}
@keyframes v404-flick{0%,100%{opacity:1}61%{opacity:.35}62%{opacity:1}64%{opacity:.5}65%{opacity:1}}
.vlanding .v404-tl{background:var(--vbg2);border:1px solid var(--vline);border-top:0;
  border-radius:0 0 12px 12px;padding:6px 0 4px}
.vlanding .v404-tl svg{display:block;width:100%;height:auto}
.vlanding .v404-tl text{font-family:var(--v404-mono)}
/* -380 is the playhead's own x (440) less the timeline's zero (60), in viewBox units. */
.vlanding .v404-ph{animation:v404-play 2.6s cubic-bezier(.35,.1,.25,1) .3s both}
@keyframes v404-play{from{transform:translateX(-380px)}to{transform:translateX(0)}}
@media (prefers-reduced-motion:reduce){
  .vlanding .v404-stamp,.vlanding .v404-ph{animation:none}
}

/* ---------- AI keywording calculator (/ai-calculator) ---------- */
/* Two columns on desktop: what you put in on the left, what it costs on the right, so the
   number moves while you are still typing. One column below 760px, inputs first - on a
   phone the answer belongs under the thing that produced it, not above it. */
.vlanding .vcalc{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;
  max-width:980px;margin:0 auto;
}
@media (max-width:760px){ .vlanding .vcalc{grid-template-columns:1fr} }

.vlanding .vcalc-in,.vlanding .vcalc-out{
  background:var(--vpanel);border:1px solid var(--vline);border-radius:14px;padding:22px;
}
.vlanding .vcalc-out{display:flex;flex-direction:column}

.vlanding .vcalc-row{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  margin-bottom:14px;font-size:14px;color:var(--vdim);
}
.vlanding .vcalc-row > span:first-child{display:flex;flex-direction:column;gap:2px}
.vlanding .vcalc-row small{color:var(--vfaint);font-size:12px;line-height:1.4}

.vlanding .vcalc input[type="number"],.vlanding .vcalc select{
  background:var(--vbg2);border:1px solid var(--vline);border-radius:9px;
  color:var(--vtext);padding:9px 11px;font:inherit;font-size:14px;
}
.vlanding .vcalc input[type="number"]{width:84px;text-align:right}
.vlanding .vcalc select{max-width:260px;flex:1 1 auto}
.vlanding .vcalc input:focus,.vlanding .vcalc select:focus{outline:none;border-color:var(--vaccent)}

.vlanding .vcalc-dur{display:flex;align-items:center;gap:7px}
.vlanding .vcalc-dur em,.vlanding .vcalc-money em{font-style:normal;color:var(--vfaint);font-size:13px}
.vlanding .vcalc-money{display:flex;align-items:center;gap:5px}

/* NARROW SCREENS STACK EACH ROW.
   Side by side, "How much footage" plus two number boxes and their unit labels needs about
   360px of the ~316px a card actually has inside its padding on a 360px phone - so the row
   overflowed and the minutes box ran under the card edge. Stacking is the fix rather than
   shrinking the inputs, because a number box narrow enough to fit is too narrow to tap. */
@media (max-width:520px){
  .vlanding .vcalc-row{align-items:flex-start;flex-direction:column;gap:8px}
  .vlanding .vcalc select{max-width:none;width:100%}
}

.vlanding .vcalc-adv{margin-top:6px;border-top:1px solid var(--vline);padding-top:14px}
.vlanding .vcalc-adv summary{
  cursor:pointer;color:var(--vfaint);font-size:13px;margin-bottom:14px;
  list-style:none;user-select:none;
}
.vlanding .vcalc-adv summary::-webkit-details-marker{display:none}
.vlanding .vcalc-adv summary::before{content:"▸ ";}
.vlanding .vcalc-adv[open] summary::before{content:"▾ ";}
.vlanding .vcalc-adv summary:hover{color:var(--vdim)}

/* The answer. Deliberately the largest thing on the page - it is the one number somebody
   came here for, and "At most" sits above it rather than beside it so the qualifier is
   read before the figure, not after. */
.vlanding .vcalc-headline{margin-bottom:18px}
.vlanding .vcalc-label{display:block;font-size:12.5px;letter-spacing:.6px;
  text-transform:uppercase;color:var(--vfaint);font-weight:600}
.vlanding .vcalc-headline strong{
  display:block;font-size:clamp(34px,6vw,46px);line-height:1.1;color:var(--vtext);
  font-weight:700;margin:4px 0 6px;font-variant-numeric:tabular-nums;
}
.vlanding .vcalc-headline .vcalc-label:last-child{
  text-transform:none;letter-spacing:0;font-size:13.5px;font-weight:400;color:var(--vdim);
}

/* The one line under the figure. Sits above a rule rather than beside the number, because
   it qualifies the number rather than competing with it. */
.vlanding .vcalc-note{
  font-size:12.5px;color:var(--vfaint);line-height:1.6;
  margin:16px 0 0;padding-top:14px;border-top:1px solid var(--vline);
}

/* Provenance line. Small on purpose - it is not a disclaimer to hide, it is the receipt
   for every figure above it, and somebody checking the maths should be able to find it. */
.vlanding .vcalc-src{
  max-width:980px;margin:16px auto 0;font-size:12px;color:var(--vfaint);
  line-height:1.6;text-align:center;
}
