/* ValleyKeep marketing site (vk-site). Its own stylesheet, not the app's: the admin CSS carries a
   sidebar, dashboard grid and form system that a landing page never uses, and shipping it here would
   be a large download for a stranger reading three paragraphs.
   Everything is in a file rather than inline, because the platform runs a strict nonce-CSP. */

:root{
  --ink:#12231d; --ink-2:#41564e; --muted:#6b7f77;
  --paper:#ffffff; --paper-2:#f5f8f6; --line:#dde6e2;
  --brand:#117a5c; --brand-dark:#0d5f47; --brand-tint:#e6f3ee;
  --radius:12px; --wrap:1120px; --gutter:20px;
  --shadow:0 1px 2px rgba(18,35,29,.05), 0 8px 24px rgba(18,35,29,.06);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font:400 17px/1.65 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
h1,h2,h3{line-height:1.2; letter-spacing:-.02em; margin:0 0 .5em; text-wrap:balance}
h1{font-size:clamp(2rem,4.6vw,3.15rem); font-weight:800}
h2{font-size:clamp(1.4rem,2.6vw,2rem); font-weight:750}
h3{font-size:1.08rem; font-weight:700; margin-top:1.6em}
p{margin:0 0 1em; max-width:68ch}
a{color:var(--brand-dark)}
a:focus-visible,button:focus-visible{outline:3px solid var(--brand); outline-offset:2px; border-radius:4px}

.wrap{width:100%; max-width:var(--wrap); margin:0 auto; padding:0 var(--gutter)}
.narrow-col{max-width:760px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.94em}

.skip{position:absolute; left:-9999px}
.skip:focus{left:12px; top:12px; z-index:50; background:var(--paper); padding:10px 14px; border-radius:8px; box-shadow:var(--shadow)}

/* ---- header ---- */
.site-head{border-bottom:1px solid var(--line); background:rgba(255,255,255,.92); backdrop-filter:saturate(140%) blur(8px); position:sticky; top:0; z-index:20}
.head-inner{display:flex; align-items:center; gap:22px; min-height:66px}
.brand{display:flex; align-items:center; gap:9px; font-weight:800; letter-spacing:-.02em; text-decoration:none; color:var(--ink)}
.brand-mark{display:grid; place-items:center; width:28px; height:28px; border-radius:8px; background:var(--brand); color:#fff; font-weight:800}
.site-nav{display:flex; gap:20px; margin-left:auto; flex-wrap:wrap}
.site-nav a{color:var(--ink-2); text-decoration:none; font-size:.95rem; font-weight:600}
.site-nav a[aria-current="page"]{color:var(--brand-dark); box-shadow:inset 0 -2px 0 var(--brand)}
.head-cta{display:flex; gap:10px; align-items:center}

/* ---- buttons ---- */
.btn-solid,.btn-ghost{display:inline-block; border-radius:10px; padding:9px 16px; font-weight:700; font-size:.95rem; text-decoration:none; white-space:nowrap}
.btn-solid{background:var(--brand); color:#fff}
.btn-ghost{color:var(--ink); border:1px solid var(--line); background:var(--paper)}
.btn-lg{padding:13px 24px; font-size:1.02rem}

/* ---- sections ---- */
.hero{padding:84px 0 66px; background:linear-gradient(180deg,var(--brand-tint),transparent)}
.eyebrow{text-transform:uppercase; letter-spacing:.09em; font-size:.76rem; font-weight:750; color:var(--brand-dark); margin-bottom:14px}
.lede{font-size:1.16rem; color:var(--ink-2); max-width:62ch}
.hero-cta{display:flex; gap:12px; flex-wrap:wrap; margin:26px 0 12px}
.hero-note{font-size:.9rem; color:var(--muted)}
.page-hero{padding:62px 0 34px; border-bottom:1px solid var(--line)}
.band{padding:62px 0}
.band.alt{background:var(--paper-2); border-block:1px solid var(--line)}
.cta-band{padding:66px 0; background:var(--brand); color:#fff; text-align:center}
.cta-band h2{color:#fff}
.cta-band p{color:rgba(255,255,255,.92); margin-inline:auto}
.cta-band .btn-solid{background:#fff; color:var(--brand-dark)}

/* ---- grids & cards ---- */
.grid-2,.grid-3{display:grid; gap:20px; margin-top:26px}
.grid-2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.grid-3{grid-template-columns:repeat(auto-fit,minmax(268px,1fr))}
.two-col{display:grid; gap:44px; grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.card{background:var(--paper); border:1px solid var(--line); border-radius:var(--radius); padding:24px; box-shadow:var(--shadow)}
.card h2,.card h3{margin-top:0; font-size:1.12rem}
.card p{margin-bottom:0; color:var(--ink-2); font-size:.98rem}

/* ---- pricing ---- */
.plan{display:flex; flex-direction:column}
.plan-best{border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-tint), var(--shadow)}
.plan-flag{align-self:flex-start; background:var(--brand-tint); color:var(--brand-dark); font-size:.72rem; font-weight:750; text-transform:uppercase; letter-spacing:.07em; padding:4px 9px; border-radius:99px; margin:0 0 10px}
.plan-price{font-size:2.35rem; font-weight:800; letter-spacing:-.03em; margin:.1em 0 0}
.plan-unit{color:var(--muted); font-size:.88rem; margin:0 0 14px}
.plan-for{font-weight:650; color:var(--ink)}
.ticks{list-style:none; margin:0 0 20px; padding:0; flex:1}
.ticks li{position:relative; padding-left:26px; margin-bottom:9px; color:var(--ink-2); font-size:.96rem}
.ticks li::before{content:"✓"; position:absolute; left:0; color:var(--brand); font-weight:800}
.fineprint{margin-top:26px; color:var(--muted); font-size:.9rem; max-width:none}

/* ---- steps ---- */
.steps{list-style:none; margin:0; padding:0; display:grid; gap:26px; counter-reset:s}
.steps li{display:flex; gap:20px; align-items:flex-start}
.step-n{display:grid; place-items:center; flex:0 0 46px; height:46px; border-radius:50%; background:var(--brand-tint); color:var(--brand-dark); font-weight:800; font-size:1.15rem}
.steps h2{font-size:1.2rem; margin-bottom:.35em}
.steps p{color:var(--ink-2); margin-bottom:0}

.link-arrow{font-weight:700; text-decoration:none}
.link-arrow::after{content:" →"}
.big-link{font-size:1.15rem; font-weight:700}

/* ---- footer ---- */
.site-foot{border-top:1px solid var(--line); background:var(--paper-2); padding:44px 0 0; margin-top:0}
.foot-inner{display:flex; gap:32px; flex-wrap:wrap; justify-content:space-between}
.foot-brand{font-weight:800; margin:0 0 4px}
.foot-note{color:var(--muted); font-size:.93rem; margin:0}
.site-foot nav{display:flex; gap:18px; flex-wrap:wrap}
.site-foot nav a{color:var(--ink-2); text-decoration:none; font-size:.93rem}
.foot-legal{border-top:1px solid var(--line); margin-top:32px; padding-block:18px}
.foot-legal p{margin:0; color:var(--muted); font-size:.86rem}

/* ---- touch ------------------------------------------------------------------
   What separates an app from a web page on a phone is not layout, it is the first 100ms after a
   thumb lands. Three defaults work against us:
   1. Mobile browsers paint a grey/blue box over a tapped link, on touch-*up*. Native controls
      respond on touch-*down*. We remove the box and supply our own :active state instead.
   2. :hover rules "stick" on a touch screen — the tapped link stays lit until you tap elsewhere.
      Every hover style below is gated behind (hover:hover) so only a real pointer gets it.
   3. touch-action:manipulation drops double-tap-to-zoom on controls, so the browser stops waiting
      to find out whether a tap was the first half of a gesture. */
a, button, .btn-solid, .btn-ghost, .brand, .link-arrow{
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}
.btn-solid, .btn-ghost, .brand, .site-nav a, .site-foot nav a, .link-arrow{
  transition:background-color 110ms ease, border-color 110ms ease, color 110ms ease, transform 110ms ease, opacity 110ms ease;
}
.btn-solid:active, .btn-ghost:active{transform:scale(.97)}
.btn-solid:active{background:var(--brand-dark)}
.btn-ghost:active{border-color:var(--brand); color:var(--brand-dark); background:var(--paper-2)}
.brand:active, .site-nav a:active, .site-foot nav a:active, .link-arrow:active{opacity:.55}

@media (hover:hover){
  .site-nav a:hover{color:var(--brand-dark)}
  .btn-solid:hover{background:var(--brand-dark)}
  .btn-ghost:hover{border-color:var(--brand); color:var(--brand-dark)}
  .cta-band .btn-solid:hover{background:#eef7f3}
  .link-arrow:hover{text-decoration:underline}
  .site-foot nav a:hover{color:var(--brand-dark)}
}

/* `none`, not `contain`. The earlier reasoning — keep iOS's bounce, it is the one browser behaviour
   users expect — stopped applying the moment we implemented pull-to-refresh ourselves: the document
   bouncing underneath our own indicator means two things moving at once, and the browser's refresh
   gesture on Android would race ours. Owning the gesture means owning the overscroll. */
html, body{overscroll-behavior-y:none}

/* ---- safe area --------------------------------------------------------------
   viewport-fit=cover means the page owns the notch and home-indicator strips, so it has to pay the
   insets back by hand. In a browser tab these all resolve to 0px; they only become non-zero once the
   page is launched from the home screen, which is exactly when getting them wrong is most visible. */
.wrap{padding-left:max(var(--gutter), env(safe-area-inset-left));
      padding-right:max(var(--gutter), env(safe-area-inset-right))}
.site-head{padding-top:env(safe-area-inset-top)}
.foot-legal{padding-bottom:max(18px, env(safe-area-inset-bottom))}

/* Launched from the home screen there is no browser chrome to scroll away, so the sticky header is
   the only thing standing between the content and the status bar — give it a little more room. */
@media (display-mode:standalone){
  .head-inner{min-height:56px}
  .hero{padding-top:44px}
}

/* ---- mobile menu (off-canvas drawer) ----------------------------------------
   The panel slides in over the page; the page stays visible behind a scrim. That distinction is the
   whole point — a surface that covers the screen reads as having *navigated somewhere*, which is why
   a full-screen sheet still felt like a web page. A drawer reads as app chrome laid over where you
   already are.

   Anchored right, matching the button that opens it: a panel that flies in from the opposite side of
   the screen to the control you touched breaks the connection between the two. */
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
         clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0}

.menu-btn{display:none; align-items:center; justify-content:center; width:44px; height:44px; flex:none;
          border:0; background:transparent; color:var(--ink); border-radius:12px; cursor:pointer;
          -webkit-tap-highlight-color:transparent; touch-action:manipulation;
          transition:background-color 110ms ease, transform 110ms ease}
.menu-btn:active{background:var(--paper-2); transform:scale(.94)}
.menu-ico{width:24px; height:24px; display:block}

/* `visibility` is the on/off switch, carried by .is-active rather than .is-open: the panel has to
   stay visible for the length of the closing animation, and `display:none` would cut it mid-flight.
   Hidden it also leaves the a11y tree and the tab order, which is the behaviour we actually want. */
.scrim, .drawer{visibility:hidden}
.scrim.is-active, .drawer.is-active{visibility:visible}

.scrim{position:fixed; inset:0; z-index:55; background:rgba(9,32,25,.44); opacity:0;
       -webkit-tap-highlight-color:transparent; touch-action:manipulation;
       transition:opacity 300ms cubic-bezier(.32,.72,0,1)}
.scrim.is-open{opacity:1}

.drawer{position:fixed; top:0; right:0; bottom:0; z-index:60; width:min(86vw, 360px);
        display:flex; flex-direction:column; background:var(--paper);
        border-radius:22px 0 0 22px; box-shadow:-20px 0 60px rgba(9,32,25,.22);
        padding-top:env(safe-area-inset-top);
        overscroll-behavior:contain;
        /* The panel itself claims every gesture. `pan-y` here looked right but let the browser
           adjudicate the direction, and it answered by firing pointercancel one move into the swipe —
           which killed the drag before it started. Scrolling is delegated to the list below, which is
           the only part that scrolls. */
        touch-action:none;
        transform:translateX(100%);
        transition:transform 300ms cubic-bezier(.32,.72,0,1)}
.drawer.is-open{transform:none}
/* While open the page behind must not scroll under the drawer. */
.menu-open{overflow:hidden}

.drawer-head{display:flex; align-items:center; justify-content:space-between; gap:12px; flex:none;
             min-height:56px; padding:0 18px; border-bottom:1px solid var(--line)}

/* The one scrollable region — `pan-y` gives the browser the vertical axis and leaves the
   horizontal one to the swipe-to-dismiss gesture. */
.drawer-nav{display:flex; flex-direction:column; flex:1; overflow-y:auto; padding:6px 18px 0;
            touch-action:pan-y}
.drawer-nav a{position:relative; display:flex; align-items:center; justify-content:space-between;
              gap:16px; min-height:56px; padding:0 6px; margin:0 -6px; border-radius:12px;
              color:var(--ink); text-decoration:none; font-size:1.1rem; font-weight:650;
              letter-spacing:-.01em;
              -webkit-tap-highlight-color:transparent; touch-action:manipulation;
              transition:background-color 110ms ease}
/* The divider is a pseudo-element, not a border: a border on a rounded box curves with the radius,
   which drew each separator as a shallow swoosh instead of a hairline. The radius has to stay — it
   is what shapes the press highlight. */
.drawer-nav a::after{content:""; position:absolute; left:6px; right:6px; bottom:0; height:1px;
                     background:var(--line)}
.drawer-nav a:last-child::after{content:none}
.drawer-nav a:active{background:var(--paper-2)}
.drawer-nav a[aria-current="page"]{color:var(--brand-dark)}
.drawer-chev{width:20px; height:20px; flex:none; color:var(--muted)}
.drawer-nav a[aria-current="page"] .drawer-chev{color:var(--brand)}

.drawer-cta{flex:none; display:grid; gap:10px; padding:14px 18px calc(14px + env(safe-area-inset-bottom));
            border-top:1px solid var(--line)}
.btn-block{display:flex; align-items:center; justify-content:center; min-height:48px; width:100%;
           text-align:center; font-size:1rem}

/* ---- pull to refresh --------------------------------------------------------
   The indicator is the response to the gesture, which is why the native overscroll above had to go:
   a page that bounces AND shows a spinner is answering the same pull twice. Positioned under the
   drawer in the stack, so a pull can never appear over an open menu. */
.ptr{position:fixed; top:calc(env(safe-area-inset-top) + 10px); left:50%; z-index:50;
     display:none; width:38px; height:38px; border-radius:50%;
     align-items:center; justify-content:center;
     background:var(--paper); color:var(--brand);
     box-shadow:0 2px 10px rgba(9,32,25,.16), 0 0 0 1px var(--line);
     transform:translate(-50%, -60px); pointer-events:none}
.ptr.is-active{display:flex}
.ptr-dial{display:flex; width:22px; height:22px}
.ptr-ring{width:22px; height:22px; display:block}
.ptr-track{opacity:.16}
.ptr-arc{opacity:.35; transition:opacity 120ms ease}
/* Past the threshold the ring completes — the visual promise that letting go will do something. */
.ptr.is-armed .ptr-arc{opacity:1}
.ptr.is-armed{color:var(--brand-dark)}
.ptr.is-loading .ptr-arc{opacity:1; transform-origin:12px 12px; animation:ptr-spin 720ms linear infinite}
.ptr.is-loading .ptr-track{opacity:.16}
@keyframes ptr-spin{to{transform:rotate(360deg)}}

/* The switch to the drawer is set by what the header can actually hold, not by a device guess.
   Six links plus Sign in plus Start free need roughly 900px; below that the row wrapped onto two
   ragged lines — which is the exact failure the drawer was built to end. Adding Home is what pushed
   it over, so the breakpoint moved with it rather than the link being dropped. */
@media (max-width:900px){
  .head-inner{flex-wrap:wrap; gap:12px; padding-block:12px}
  /* The links move into the drawer; the bar keeps the brand, one action and the menu button. */
  .site-nav, .head-signin{display:none}
  .menu-btn{display:flex}
  .head-cta{margin-left:auto}
  .head-inner{flex-wrap:nowrap; gap:10px; min-height:56px; padding-block:6px}
  .btn-solid, .btn-ghost{padding:8px 14px; font-size:.92rem}
  .hero{padding:56px 0 44px}
  /* Footer links stack, so give each one a real row to be tapped in. */
  .site-foot nav a{display:flex; align-items:center; min-height:40px}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none !important; transition:none !important}
}

@media (min-width:901px){
  .scrim, .drawer{display:none}
}
