/*
 * landing.css - the public marketing shell: the homepage and the blog.
 *
 * Lifted out of home/index.php's inline <style> when the blog arrived, because
 * two pages sharing a look cannot share it by copy-paste. Everything here is
 * scoped to .lp / .lp-* so it cannot reach the signed-in app, which styles
 * itself from app.css alone.
 *
 * CSP note: the landing pages allow no external CSS or JS (Turnstile's script
 * is the one whitelisted exception), and a stylesheet served from our own
 * origin is exactly what style-src 'self' is for.
 */

body { background: #fff; }
.lp a { text-decoration: none; }
.lp { display: flex; flex-direction: column; min-height: 100vh; }
.lp-max { max-width: 1120px; margin: 0 auto; padding: 0 20px; width: 100%; }

/* Skip link. First in the tab order, off-screen until focused - a keyboard or
   switch user used to tab the wordmark and nine header links before reaching a
   word of the page, on every page. */
.lp-skip { position: absolute; left: -9999px; top: 0; z-index: 60; }
.lp-skip:focus { left: 8px; top: 8px; background: var(--green-900); color: #fff;
                 padding: 10px 14px; border-radius: 8px; font-weight: 700; }

/* Top bar */
.lp-head { position: sticky; top: 0; z-index: 20; background: rgba(255,255,255,.92);
           backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); }
.lp-head-in { display: flex; align-items: center; gap: 18px; padding: 12px 20px; }
.lp-head .brand { color: var(--green-900); padding: 0; font-size: 1.12rem; }
/* app.css's a.brand:hover paints the wordmark WHITE - right on the app's
   dark sidebar, invisible on this white header. Same green on hover here,
   with the opacity dip carrying the "clickable" signal instead. */
.lp-head .brand:hover { color: var(--green-900); opacity: .8; }
.lp-nav { display: flex; gap: 18px; align-items: center; }
.lp-nav a { color: var(--ink-soft); font-weight: 600; font-size: .93rem; }
.lp-nav a:hover { color: var(--green-900); }
.lp-actions { display: flex; gap: 10px; align-items: center; }
.lp-actions .btn { color: #fff; }
.lp-actions .btn-outline { color: var(--green-900); }

/* The nav lives in a <details> so it can collapse on a phone with no
   JavaScript. Above the phone breakpoint the summary is hidden and the nav is
   shown unconditionally, so one element serves both layouts.

   Two rules do that, and BOTH are needed:

     1. the wrapper keeps a real box. `display: contents` here looked tidier -
        it put the links straight into the header's flex row - and it hid the
        entire desktop navigation. A closed <details> hides its contents
        through a wrapper (Chromium exposes it as ::details-content, carrying
        `content-visibility: hidden`), and with the <details> box itself
        removed by `display: contents` an author `display` on the light-DOM
        child no longer reaches past it: the nav computed to `display: flex`
        and measured ZERO pixels wide, elementFromPoint hit the hero behind
        it, and checkVisibility() returned false. Measured, not reasoned - and
        the first sweep missed it by testing `height > 0`, which was 67.
     2. ::details-content is un-hidden explicitly for the browsers that
        implement it. Older engines ignore the pseudo-element and are covered
        by rule 1 alone; nothing needs both to be true at once. */
.lp-menu { display: block; margin-left: auto; }
.lp-menu > summary { display: none; }
.lp-menu > .lp-nav { display: flex; }
.lp-menu::details-content { content-visibility: visible; }
.lp-menu-btn { list-style: none; cursor: pointer; align-items: center; gap: 8px;
               font-weight: 700; font-size: .9rem; color: var(--green-900);
               padding: 8px 12px; border: 1px solid var(--line); border-radius: 9px;
               background: #fff; white-space: nowrap; }
.lp-menu-btn::-webkit-details-marker { display: none; }
.lp-burger { width: 16px; height: 2px; background: currentColor; position: relative;
             display: inline-block; }
.lp-burger::before, .lp-burger::after { content: ""; position: absolute; left: 0;
             width: 16px; height: 2px; background: currentColor; }
.lp-burger::before { top: -5px; }
.lp-burger::after  { top: 5px; }

/* Small-laptop header: the text links plus two buttons outgrow the viewport in
   the narrow band just above the width where the menu collapses (measured at
   793px of content in a 780px window). Tighten the row there rather than
   collapsing earlier - a tablet keeps its navigation open. */
@media (max-width: 900px) {
  .lp-head-in { gap: 12px; }
  .lp-nav { gap: 11px; }
  .lp-nav a { font-size: .88rem; }
  .lp-actions .btn { padding: 9px 13px; }
}
/* Phone and small-tablet header. The text links used to be `display: none`
   here, full stop - so a phone visitor could reach the catalog, sign in or
   register, and nothing else: pricing, the FAQ, the platform tour and the
   contact form were all unreachable from the front door on the device most
   people arrive on. They now fold into a Menu button that drops a panel under
   the header. The two CTAs stay outside it and visible.
   The cut-off is 820px rather than 760: the links plus two buttons need ~795px
   of header, so between 760 and 800 the row used to overflow by a few pixels.
   Measured by sweeping 320-1400 in 10px steps, not guessed. */
@media (max-width: 820px) {
  .lp-menu > summary { display: inline-flex; }
  .lp-menu > .lp-nav {
    display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0; margin: 0;
    background: #fff; border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 24px rgba(16,24,40,.10); padding: 6px 0;
  }
  .lp-menu[open] > .lp-nav { display: flex; }
  /* ...and the ::details-content un-hiding above must NOT leak down here, or
     the panel would be permanently open on a phone. `display: none` on the
     child closes it regardless of what the wrapper is doing. */
  .lp-menu:not([open]) > .lp-nav { display: none; }
  .lp-menu[open] > .lp-nav a { padding: 13px 20px; font-size: .95rem;
                               border-top: 1px solid var(--line); }
  .lp-menu[open] > .lp-nav a:first-child { border-top: 0; }
  .lp-head-in { gap: 10px; padding-inline: 14px; position: relative; }
  .lp-actions { gap: 8px; }
  .lp-actions .btn { padding: 8px 12px; font-size: .85rem; white-space: nowrap; }
}
@media (max-width: 430px) {
  .lp-head .brand-sub { display: none; }
  /* Brand and Menu on the first row, the two CTAs stretched across a second -
     squeezing both buttons in beside the burger at 360px makes each of them a
     tap target you have to aim at. */
  .lp-head-in { flex-wrap: wrap; }
  .lp-actions { flex: 1 1 100%; }
  .lp-actions .btn { flex: 1; text-align: center; }
}

/* Hero */
.lp-hero { background: linear-gradient(160deg, #e3f6ec 0%, #f1fbf6 40%, #ffffff 72%, #ecf9f2 100%); }
.lp-hero-in { display: grid; grid-template-columns: 1.25fr 1fr; gap: 42px; align-items: center;
              padding: 64px 20px 58px; }
.lp-eyebrow { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.lp-chip { background: var(--green-100); color: var(--green-900); border-radius: 999px;
           padding: 4px 12px; font-size: .8rem; font-weight: 700; white-space: nowrap; }
/* Phones: keep the three chips on ONE row (shrunk to fit) instead of stacking.
   The row scrolls sideways on the very narrowest devices rather than wrapping
   to three lines or forcing page-wide overflow. */
@media (max-width: 560px) {
  .lp-eyebrow { flex-wrap: nowrap; gap: 6px; overflow-x: auto; scrollbar-width: none; }
  .lp-eyebrow::-webkit-scrollbar { display: none; }
  .lp-chip { flex: 0 0 auto; font-size: .56rem; padding: 4px 9px; letter-spacing: -.01em; }
}
.lp-hero h1 { font-size: clamp(1.9rem, 4.2vw, 3rem); line-height: 1.12; margin: 0 0 16px;
              color: var(--ink); letter-spacing: -.02em; }
.lp-hero h1 em { color: var(--green-700); font-style: normal; }
.lp-hero p.lead { font-size: 1.08rem; line-height: 1.65; color: var(--ink-soft); margin: 0 0 26px; max-width: 34em; }
.lp-cta { display: flex; gap: 12px; flex-wrap: wrap; }
.lp-cta .btn { font-size: 1rem; padding: 12px 22px; }
/* Hero search. Sits under the two CTAs rather than beside them: the buttons
   are the primary path and a search box on the same line competes with them,
   but somebody who already knows the SKU should not have to go via the
   catalog to type it. */
.lp-search { display: flex; gap: 8px; margin-top: 14px; max-width: 460px; }
.lp-search input[type="search"] {
  flex: 1; min-width: 0; padding: 11px 14px; font-size: .95rem;
  border: 1px solid var(--line); border-radius: 10px; background: #fff;
}
@media (max-width: 480px) { .lp-search { max-width: none; } }
.lp-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* The box is reserved before the bytes arrive. `height: auto` on an <img> with
   no width/height attributes is zero until the image decodes, so the stats
   underneath used to render against the hero heading and then jump 300px down
   the page - the worst kind of layout shift, because it happens exactly where
   somebody is reading. The uploaded photo can be any shape, so the ratio is
   the frame's and object-fit does the rest. */
.lp-photo { width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
            border-radius: 14px; box-shadow: var(--shadow);
            border: 1px solid var(--line); display: block; margin-bottom: 14px; }
.lp-stat { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 18px;
           box-shadow: var(--shadow); }
.lp-stat b { display: block; font-size: 1.45rem; color: var(--green-900); letter-spacing: -.01em; }
.lp-stat span { color: var(--muted); font-size: .85rem; line-height: 1.4; display: block; margin-top: 3px; }
@media (max-width: 880px) {
  .lp-hero-in { grid-template-columns: 1fr; padding-top: 44px; }
  /* Stronger green wash at the top on phones. Desktop leans on the taller hero
     plus the aurora for it; the shorter mobile hero needs it in the gradient. */
  .lp-hero { background: linear-gradient(180deg, #dcfce7 0%, #eaf7ef 24%, #ffffff 62%, #eef6f0 100%); }
}

/* Brand strip */
.lp-brands { border-block: 1px solid var(--line); background: #fafcfa; padding: 26px 0; }
.lp-brands-label { text-align: center; color: var(--muted); font-size: .82rem; font-weight: 700;
                   text-transform: uppercase; letter-spacing: .09em; margin-bottom: 16px; }
.lp-brand-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 26px; align-items: center; }
/* #97a3ae on #fafcfa is 2.4:1 - under the 4.5:1 a strip of company NAMES needs,
   because a wordmark tile is text a visitor is meant to read, not decoration.
   #5c6b78 clears it at 4.7:1 and still reads as a quiet strip. The uploaded
   logos get more of their own contrast back for the same reason: at .75 opacity
   over grayscale, a light logo was a rumour. */
.lp-brand { color: #5c6b78; font-weight: 800; font-size: 1.05rem; letter-spacing: .02em;
            padding: 6px 10px; white-space: nowrap; }
.lp-brand img { height: 30px; width: auto; display: block; filter: grayscale(1); opacity: .9; }

/* Sections */
.lp-sec { padding: 58px 0; }
.lp-sec.alt { background: #f7faf8; border-block: 1px solid var(--line); }
.lp-sec h2 { font-size: clamp(1.4rem, 2.6vw, 1.9rem); margin: 0 0 8px; color: var(--ink); letter-spacing: -.01em; }
.lp-sec .sub2 { color: var(--muted); margin: 0 0 30px; max-width: 46em; line-height: 1.6; }
.lp-story { display: grid; grid-template-columns: 1.1fr .9fr; gap: 40px; align-items: start; }
.lp-story p { color: var(--ink-soft); line-height: 1.7; margin: 0 0 14px; }
.lp-trust { display: grid; gap: 12px; margin: 0; padding: 0; }  /* reset <ul> default indent so bullets align flush, not pushed right */
.lp-trust li { list-style: none; background: #fff; border: 1px solid var(--line); border-radius: 12px;
               padding: 14px 16px; color: var(--ink-soft); line-height: 1.55; }
.lp-trust li b { color: var(--ink); }
.lp-feats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.lp-feat { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 20px;
           box-shadow: var(--shadow); }
.lp-feat .ic { font-size: 1.4rem; }
.lp-feat h3 { margin: 8px 0 6px; font-size: 1.02rem; }
.lp-feat p { color: var(--ink-soft); font-size: .9rem; line-height: 1.55; margin: 0; }
/* Platform cards: what the software does. Wider than the feature cards
   because each one ends in a chip list of the modules behind the claim. */
.lp-mods { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.lp-mod { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 22px;
          box-shadow: var(--shadow); display: flex; flex-direction: column; }
.lp-mod h3 { margin: 12px 0 6px; font-size: 1.05rem; }
.lp-mod p { color: var(--ink-soft); font-size: .92rem; line-height: 1.6; margin: 0; }
.lp-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 0; padding: 0; }
.lp-tags li { list-style: none; font-size: .74rem; font-weight: 700; padding: 4px 10px;
              border-radius: 999px; }
.lp-note { color: var(--muted); line-height: 1.65; max-width: 46em; margin: 26px 0 18px; }

/* Forecasting: four numbered steps, then the knobs as one chip row. */
.lp-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.lp-step { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 20px;
           box-shadow: var(--shadow); }
.lp-step h3 { margin: 12px 0 6px; font-size: 1rem; }
.lp-step p { color: var(--ink-soft); font-size: .9rem; line-height: 1.55; margin: 0; }
.lp-step .n { width: 34px; height: 34px; border-radius: 50%; display: inline-flex;
              align-items: center; justify-content: center; font-weight: 800; font-size: .95rem;
              color: #fff; background: linear-gradient(135deg, var(--green-700), var(--c-emerald)); }
.lp-tags-wide { margin-top: 20px; }

/* Pricing: one card per configured plan, or the single fallback card. */
.lp-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
            gap: 16px; max-width: 940px; }
.lp-plans.one { max-width: 620px; }
.lp-plan { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 24px;
           box-shadow: var(--shadow); display: flex; flex-direction: column; }
.lp-plan h3 { margin: 0 0 4px; font-size: 1.15rem; }
.lp-plan-for { color: var(--muted); font-size: .89rem; line-height: 1.55; margin: 0 0 14px; }
.lp-price { display: flex; align-items: baseline; gap: 5px; }
.lp-price b { font-size: 2rem; letter-spacing: -.02em; color: var(--green-900); }
.lp-price span { color: var(--muted); font-size: .9rem; }
.lp-plan-inc { list-style: none; display: grid; gap: 8px; margin: 16px 0 20px; padding: 0; }
.lp-plan-inc li { color: var(--ink-soft); font-size: .9rem; line-height: 1.45;
                  padding-left: 21px; position: relative; }
.lp-plan-inc li::before { content: "✓"; position: absolute; left: 0; font-weight: 800;
                          color: var(--green-600); }
.lp-plan-inc li b { color: var(--ink); }
.lp-plan .btn { margin-top: auto; text-align: center; }
@media (max-width: 960px) { .lp-steps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .lp-steps { grid-template-columns: 1fr; } }

/* Testimonials: three across, and narrowed when there are only one or two so
   a lone quote does not stretch to a single wide line. */
.lp-quotes { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 16px; }
.lp-quotes.few { max-width: 760px; }
.lp-quote { background: #fff; border: 1px solid var(--line); border-radius: 14px;
            padding: 22px 22px 18px; box-shadow: var(--shadow); margin: 0;
            display: flex; flex-direction: column; }
.lp-quote blockquote { margin: 0 0 14px; color: var(--ink); line-height: 1.65; font-size: .96rem;
                       position: relative; padding-top: 26px; }
.lp-quote blockquote::before { content: "\201C"; position: absolute; top: -12px; left: -2px;
                               font-size: 3.2rem; line-height: 1; color: var(--green-600);
                               opacity: .35; font-family: Georgia, "Times New Roman", serif; }
.lp-quote figcaption { margin-top: auto; border-top: 1px solid var(--line); padding-top: 12px; }
.lp-quote figcaption b { display: block; color: var(--ink); font-size: .92rem; }
.lp-quote figcaption span { display: block; color: var(--muted); font-size: .84rem; margin-top: 2px; }

/* FAQ: native <details>, so it opens with JavaScript off and find-in-page
   still reaches a closed answer. One column - a question you have to hunt
   for across two of them is a question you gave up on. */
.lp-faq { display: grid; gap: 10px; max-width: 860px; }
.lp-q { background: #fff; border: 1px solid var(--line); border-radius: 12px;
        box-shadow: var(--shadow); }
.lp-q > summary { cursor: pointer; padding: 15px 48px 15px 18px; font-weight: 700;
                  color: var(--ink); position: relative; list-style: none; line-height: 1.45; }
.lp-q > summary::-webkit-details-marker { display: none; }
.lp-q > summary::after { content: "+"; position: absolute; right: 18px; top: 50%;
                         transform: translateY(-50%); font-size: 1.45rem; line-height: 1;
                         font-weight: 400; color: var(--green-700); }
.lp-q[open] > summary::after { content: "\2212"; }
.lp-q > summary:hover { color: var(--green-900); }
.lp-q p { margin: 0; padding: 0 18px 18px; color: var(--ink-soft);
          font-size: .94rem; line-height: 1.7; }
@media (max-width: 960px) { .lp-feats, .lp-mods { grid-template-columns: 1fr 1fr; } .lp-story { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .lp-feats, .lp-mods { grid-template-columns: 1fr; } .lp-stats { grid-template-columns: 1fr 1fr; } }

/* Shop by category - the front door's links into the landing pages. */
.lp-cats { display: grid; gap: 10px; margin-top: 20px;
           grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.lp-cat { display: flex; align-items: center; justify-content: space-between; gap: 10px;
          background: #fff; border: 1px solid var(--line); border-radius: 12px;
          padding: 14px 16px; color: var(--ink); font-weight: 700; font-size: .95rem;
          transition: border-color .15s, transform .15s, box-shadow .15s; }
.lp-cat:hover { border-color: var(--green-700); transform: translateY(-1px);
                box-shadow: var(--shadow); }
.lp-cat-n { min-width: 0; }
.lp-cat-c { color: var(--muted); font-weight: 700; font-size: .8rem;
            background: #f1f5f3; border-radius: 999px; padding: 3px 9px; flex: 0 0 auto; }
@media (prefers-reduced-motion: reduce) { .lp-cat:hover { transform: none; } }

/* Contact + sign in */
.lp-ident-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex;
                 flex-wrap: wrap; gap: 8px 20px; font-size: .9rem; }
.lp-ident-list li { display: flex; align-items: center; gap: 7px; color: var(--ink-soft); }
.lp-ident-list a { color: var(--green-900); font-weight: 700; }
.lp-forms { max-width: 680px; margin: 0 auto; }
.lp-forms textarea { min-height: 150px; resize: vertical; }
.lp-card { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 24px;
           box-shadow: var(--shadow); }
.lp-card h3 { margin: 0 0 4px; }
.lp-card .hint { margin-bottom: 14px; }
.lp-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .lp-grid2 { grid-template-columns: 1fr; } }
/* Bottom margin is REAL: the zero-bottom shorthand this used to carry beat
   .flash-banner's own margin-bottom (same specificity, this file loads
   later), so the confirmation sat flush against the hero. */
.lp-banner { margin: 18px auto 22px; max-width: 1120px; padding: 0 20px; }
/* The flash itself - the pop, the pulse, the tick badge - is .flash-banner
   in app.css, defined once because the storefront shell shows the same
   guest confirmations and two copies of a flash is two flashes that drift.
   This rule only places it on the landing layout. */

/* Footer */
.lp-foot { margin-top: auto; border-top: 1px solid var(--line); background: #f7faf8;
           padding: 26px 0; color: var(--muted); font-size: .86rem; }
.lp-foot-in { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }
.lp-foot a { color: var(--ink-soft); font-weight: 600; }
.lp-foot .lp-right { margin-left: auto; }
/* The identity line: address, phone, email. Above the link row because it is
   the thing a buyer is actually looking for down here. */
.lp-ident { display: flex; gap: 8px 22px; flex-wrap: wrap; align-items: center;
            padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--line); }
/* Inherit, do NOT set --ink-soft. The footer is restyled to a dark-green
   gradient further down this file (see .lp-foot in the storefront-colour
   block), and #4b5563 on that is about 1.2:1 - the street address was
   rendering effectively invisible on the surface it exists to make credible. */
.lp-ident-i { color: inherit; }

/* ============================================================
   Motion & juice. Everything below is progressive: with JavaScript
   off nothing is hidden (reveal states are gated on html.js), and
   every keyframe animation is wrapped in prefers-reduced-motion:
   no-preference so a reduced-motion visitor gets a calm, static page.
   All movement is transform/opacity only (GPU-friendly on mobile).
   ============================================================ */

/* Thin scroll-progress bar (JS drives scaleX; 0 until then, so no-JS shows nothing). */
.lp-progress { position: fixed; inset: 0 0 auto 0; height: 3px; transform: scaleX(0);
               transform-origin: 0 50%; z-index: 40; will-change: transform;
               background: linear-gradient(90deg, var(--green-600), var(--green-900) 70%, #34d399);
               box-shadow: 0 0 12px rgba(22,163,74,.45); }

/* Reveal-on-scroll: hidden only when JS is present AND motion is welcome. */
@media (prefers-reduced-motion: no-preference) {
  html.js [data-reveal] { opacity: 0; transform: translateY(24px);
    transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1); }
  html.js [data-reveal].in { opacity: 1; transform: none; }
  html.js [data-stagger] > * { opacity: 0; transform: translateY(20px);
    transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.2,1); }
  html.js [data-stagger].in > * { opacity: 1; transform: none; }
  html.js [data-stagger].in > *:nth-child(2) { transition-delay: .07s; }
  html.js [data-stagger].in > *:nth-child(3) { transition-delay: .14s; }
  html.js [data-stagger].in > *:nth-child(4) { transition-delay: .21s; }
  html.js [data-stagger].in > *:nth-child(5) { transition-delay: .28s; }
  html.js [data-stagger].in > *:nth-child(6) { transition-delay: .35s; }
}

/* Aurora: drifting colour blobs behind the hero. */
.lp-hero { position: relative; overflow: hidden; }
.lp-hero-in { position: relative; z-index: 2; }
.lp-aurora { position: absolute; inset: -25% -12% -12%; z-index: 0; pointer-events: none;
             filter: blur(64px); opacity: .55; }
.lp-aurora span { position: absolute; display: block; border-radius: 50%; will-change: transform; }
.lp-aurora span:nth-child(1) { width: 46vmax; height: 46vmax; left: -8%; top: -22%;
  background: radial-gradient(circle at 30% 30%, #86efac, transparent 62%); }
.lp-aurora span:nth-child(2) { width: 40vmax; height: 40vmax; right: -8%; top: -10%;
  background: radial-gradient(circle at 60% 40%, #5eead4, transparent 60%); }
.lp-aurora span:nth-child(3) { width: 34vmax; height: 34vmax; left: 34%; bottom: -28%;
  background: radial-gradient(circle at 50% 50%, #bbf7d0, transparent 60%); }
@media (prefers-reduced-motion: no-preference) {
  .lp-aurora span:nth-child(1) { animation: lpFloat1 22s ease-in-out infinite; }
  .lp-aurora span:nth-child(2) { animation: lpFloat2 27s ease-in-out infinite; }
  .lp-aurora span:nth-child(3) { animation: lpFloat3 31s ease-in-out infinite; }
}
@keyframes lpFloat1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(6%,8%) scale(1.12); } }
@keyframes lpFloat2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-7%,5%) scale(1.08); } }
@keyframes lpFloat3 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(4%,-6%) scale(1.15); } }
@media (max-width: 560px) { .lp-aurora { filter: blur(46px); opacity: .62; } }

/* Hero visual gets a soft pointer parallax on desktop (JS sets transform). */
.lp-hero-visual { transition: transform .25s ease-out; will-change: transform; }

/* Gradient-shimmer on the accent word (solid-green fallback where clip:text is unsupported). */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .lp-hero h1 em {
    background: linear-gradient(100deg, var(--green-700), var(--green-600) 35%, #34d399 55%, var(--green-700));
    background-size: 220% 100%; -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent; }
  @media (prefers-reduced-motion: no-preference) {
    .lp-hero h1 em { animation: lpShimmer 7s linear infinite; }
  }
}
@keyframes lpShimmer { to { background-position: 220% 0; } }

/* Chips flip in on load (gated on html.js so no-JS keeps them visible). */
@media (prefers-reduced-motion: no-preference) {
  html.js .lp-eyebrow .lp-chip { opacity: 0; transform: translateY(-8px) scale(.92);
    animation: lpChip .55s cubic-bezier(.2,.9,.3,1.3) forwards; }
  html.js .lp-eyebrow .lp-chip:nth-child(2) { animation-delay: .1s; }
  html.js .lp-eyebrow .lp-chip:nth-child(3) { animation-delay: .2s; }
}
@keyframes lpChip { to { opacity: 1; transform: none; } }

/* Buttons: lift + a one-shot sheen on hover (scoped to the landing page). */
.lp .btn { position: relative; overflow: hidden;
           transition: transform .18s ease, box-shadow .18s ease, background .18s ease; }
.lp .btn:hover { transform: translateY(-2px); box-shadow: 0 12px 24px -10px rgba(21,128,61,.6); }
.lp .btn:active { transform: translateY(0); }
.lp .btn::after { content: ""; position: absolute; top: 0; left: -130%; width: 55%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent);
  transform: skewX(-18deg); pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .lp .btn:hover::after { animation: lpSheen .85s ease; }
}
@keyframes lpSheen { to { left: 150%; } }

/* Card life: hover-lift + green edge, springy icon on the feature cards. */
.lp-feat, .lp-stat { transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.lp-feat:hover, .lp-stat:hover { transform: translateY(-4px); border-color: var(--green-600);
  box-shadow: 0 18px 36px -16px rgba(20,83,45,.4); }
.lp-feat .ic { display: inline-flex; transition: transform .28s cubic-bezier(.2,1.6,.4,1); }
.lp-feat:hover .ic { transform: scale(1.18) rotate(-5deg); }
.lp-stat b { transition: color .2s ease; }
.lp-trust li { transition: transform .18s ease, box-shadow .18s ease; }
.lp-trust li:hover { transform: translateX(3px); box-shadow: 0 8px 20px -12px rgba(20,83,45,.35); }

/* Brand / client strips become infinite marquees (pure CSS; static & centred
   under reduced-motion). Tiles carry their own trailing gap via margin so the
   two duplicated sets loop seamlessly at translateX(-50%). */
.lp-marquee { overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.lp-marquee-track { display: flex; align-items: center; width: max-content; }
.lp-marquee .lp-brand { margin: 0 26px 0 0; padding-block: 6px; }
.lp-marquee-set { display: contents; }
@media (prefers-reduced-motion: no-preference) {
  .lp-marquee-track { animation: lpMarquee 46s linear infinite; }
  .lp-marquee.rev .lp-marquee-track { animation-direction: reverse; }
  /* :focus-within as well as :hover. A moving strip that only a mouse can stop
     is a WCAG 2.2.2 failure for everybody else - and a keyboard user tabbing
     into a logo inside it was chasing a moving target. */
  .lp-marquee:hover .lp-marquee-track,
  .lp-marquee:focus-within .lp-marquee-track { animation-play-state: paused; }
}
@keyframes lpMarquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .lp-marquee { -webkit-mask-image: none; mask-image: none; }
  .lp-marquee-track { flex-wrap: wrap; justify-content: center; width: 100%; gap: 12px 22px; }
  .lp-marquee .lp-brand { margin: 0; }
  .lp-marquee-dup { display: none; }
}

/* ============================================================
   COLOUR - a green-forward accent system (emerald, teal, lime,
   with a warm amber pop) layered over the base greens for more
   life. Static colour only: safe with JS off and reduced motion,
   and it applies identically on mobile and desktop.
   ============================================================ */
.lp { --c-emerald:#10b981; --c-teal:#14b8a6; --c-cyan:#22d3ee;
      --c-lime:#65a30d; --c-lime-b:#a3e635; --c-amber:#f59e0b; --c-mint:#ecfdf5; }

/* Richer, more colourful aurora; the 4th blob adds a warm glow. */
.lp-aurora span:nth-child(1) { background: radial-gradient(circle at 30% 30%, #6ee7b7, transparent 62%); }
.lp-aurora span:nth-child(3) { background: radial-gradient(circle at 50% 50%, #bef264, transparent 60%); }
.lp-aurora span:nth-child(4) { width: 30vmax; height: 30vmax; right: 20%; bottom: -26%;
  background: radial-gradient(circle at 50% 50%, #fcd34d, transparent 64%); }
@media (prefers-reduced-motion: no-preference) {
  .lp-aurora span:nth-child(4) { animation: lpFloat2 34s ease-in-out infinite; }
}

/* Hero chips: three distinct tints. */
.lp-chip:nth-child(2) { background: #ccfbf1; color: #0f766e; }
.lp-chip:nth-child(3) { background: #ecfccb; color: #4d7c0f; }

/* Primary buttons: a green->emerald->teal gradient (lift + sheen already set). */
.lp .btn:not(.btn-outline) {
  background: linear-gradient(120deg, var(--green-700), var(--green-600) 48%, var(--c-emerald));
  border-color: transparent; }

/* Hero stat cards: a colour bar across the top, cycling hues. */
.lp-stat { position: relative; overflow: hidden; }
.lp-stat::before { content:""; position:absolute; inset:0 0 auto 0; height:4px;
  background: linear-gradient(90deg, var(--green-600), var(--c-emerald)); }
.lp-stat:nth-child(2)::before { background: linear-gradient(90deg, var(--c-teal), var(--c-cyan)); }
.lp-stat:nth-child(3)::before { background: linear-gradient(90deg, var(--c-lime), var(--c-lime-b)); }
.lp-stat:nth-child(4)::before { background: linear-gradient(90deg, var(--c-amber), #fbbf24); }

/* Section headings get a colourful underline accent. */
.lp-sec h2 { position: relative; }
.lp-sec h2::after { content:""; display:block; margin-top:12px; width:64px; height:4px; border-radius:2px;
  background: linear-gradient(90deg, var(--green-600), var(--c-teal) 55%, var(--c-lime-b)); }

/* Brand strips: a whisper of mint instead of flat grey. */
.lp-brands { background: #f3faf6; }

/* Story trust bullets: a colour edge, cycling hues. */
.lp-trust li { border-left: 4px solid var(--green-600); }
.lp-trust li:nth-child(2) { border-left-color: var(--c-teal); }
.lp-trust li:nth-child(3) { border-left-color: var(--c-lime); }
.lp-trust li:nth-child(4) { border-left-color: var(--c-amber); }

/* Why section: mint wash, colourful icon tiles + top edges. */
.lp-sec.alt { background: linear-gradient(180deg, var(--c-mint), #ffffff 72%); }
.lp-feat { border-top: 3px solid var(--green-600); }
.lp-feat:nth-child(2) { border-top-color: var(--c-teal); }
.lp-feat:nth-child(3) { border-top-color: var(--c-lime); }
.lp-feat:nth-child(4) { border-top-color: var(--c-amber); }
.lp-feat .ic { width:52px; height:52px; border-radius:14px; display:inline-flex;
  align-items:center; justify-content:center; font-size:1.55rem;
  background: linear-gradient(135deg, #d1fae5, #a7f3d0); }
.lp-feat:nth-child(2) .ic { background: linear-gradient(135deg, #ccfbf1, #99f6e4); }
.lp-feat:nth-child(3) .ic { background: linear-gradient(135deg, #ecfccb, #d9f99d); }
.lp-feat:nth-child(4) .ic { background: linear-gradient(135deg, #fef3c7, #fde68a); }

/* Platform section: a faint wash through the middle so six white cards read
   as a block, fading to white at both edges to meet its neighbours cleanly. */
#platform { background: linear-gradient(180deg, #ffffff 0%, #f4f9f6 38%, #ffffff 100%); }

/* Platform cards: one hue per card, declared once as custom properties so the
   left edge, the icon tile and the chips move together - adding a seventh
   card means one --mod block, not four selectors. */
.lp-mod { --mod: var(--green-600); --mod-a: #d1fae5; --mod-b: #a7f3d0;
          --mod-ink: var(--green-900); --mod-bg: var(--green-100);
          border-left: 4px solid var(--mod);
          transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.lp-mod:hover { transform: translateY(-4px); box-shadow: 0 18px 36px -16px rgba(20,83,45,.4); }
.lp-mod .ic { width: 46px; height: 46px; border-radius: 13px; display: inline-flex;
              align-items: center; justify-content: center; font-size: 1.35rem;
              background: linear-gradient(135deg, var(--mod-a), var(--mod-b));
              transition: transform .28s cubic-bezier(.2,1.6,.4,1); }
.lp-mod:hover .ic { transform: scale(1.14) rotate(-5deg); }
.lp-tags li { color: var(--mod-ink); background: var(--mod-bg); }
.lp-mod:nth-child(2) { --mod: var(--c-teal);    --mod-a:#ccfbf1; --mod-b:#99f6e4; --mod-ink:#0f766e; --mod-bg:#ccfbf1; }
.lp-mod:nth-child(3) { --mod: var(--c-lime);    --mod-a:#ecfccb; --mod-b:#d9f99d; --mod-ink:#4d7c0f; --mod-bg:#ecfccb; }
.lp-mod:nth-child(4) { --mod: var(--c-amber);   --mod-a:#fef3c7; --mod-b:#fde68a; --mod-ink:#92400e; --mod-bg:#fef3c7; }
.lp-mod:nth-child(5) { --mod: var(--c-cyan);    --mod-a:#cffafe; --mod-b:#a5f3fc; --mod-ink:#155e75; --mod-bg:#cffafe; }
.lp-mod:nth-child(6) { --mod: var(--c-emerald); --mod-a:#dcfce7; --mod-b:#86efac; --mod-ink:#166534; --mod-bg:#dcfce7; }

/* Forecast steps and plan cards lift like every other card here; the step
   numbers cycle the same four hues so the pipeline reads left to right. */
.lp-step, .lp-plan { transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.lp-step:hover, .lp-plan:hover { transform: translateY(-4px); border-color: var(--green-600);
  box-shadow: 0 18px 36px -16px rgba(20,83,45,.4); }
.lp-step:nth-child(2) .n { background: linear-gradient(135deg, #0f766e, var(--c-teal)); }
.lp-step:nth-child(3) .n { background: linear-gradient(135deg, var(--c-lime), #4d7c0f); }
.lp-step:nth-child(4) .n { background: linear-gradient(135deg, #b45309, var(--c-amber)); }
.lp-tags-wide li { color: var(--green-900); background: var(--green-100); }

/* Pricing: a faint wash through the middle, like the platform section, and a
   colour bar across the top of each plan card. */
#pricing { background: linear-gradient(180deg, #ffffff 0%, #f4f9f6 40%, #ffffff 100%); }
.lp-plan { position: relative; overflow: hidden; }
.lp-plan::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--green-600), var(--c-emerald), var(--c-teal)); }

/* Testimonials lift like the other cards, and cycle the same hues. */
.lp-quote { border-top: 3px solid var(--green-600);
            transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.lp-quote:hover { transform: translateY(-4px); box-shadow: 0 18px 36px -16px rgba(20,83,45,.4); }
.lp-quote:nth-child(2) { border-top-color: var(--c-teal); }
.lp-quote:nth-child(3) { border-top-color: var(--c-lime); }
.lp-quote:nth-child(4) { border-top-color: var(--c-amber); }
.lp-quote:nth-child(5) { border-top-color: var(--c-cyan); }
.lp-quote:nth-child(6) { border-top-color: var(--c-emerald); }

/* FAQ: the open question gets a green edge, so the one you are reading is
   obvious in a stack of eight. */
.lp-q { border-left: 3px solid transparent; transition: border-color .18s ease, box-shadow .18s ease; }
.lp-q[open] { border-left-color: var(--green-600); box-shadow: 0 10px 24px -14px rgba(20,83,45,.45); }

/* Contact: a soft tint band + a colour bar across the card top. */
#contact { background: linear-gradient(180deg, #ffffff, var(--c-mint)); }
.lp-card { position: relative; overflow: hidden; }
.lp-card::before { content:""; position:absolute; inset:0 0 auto 0; height:5px;
  background: linear-gradient(90deg, var(--green-600), var(--c-teal), var(--c-lime-b), var(--c-amber)); }

/* Footer: a deep-green gradient with a bright accent hairline on top and
   light text (links brighten to lime on hover). */
.lp-foot { position: relative; padding: 32px 0; color: rgba(255,255,255,.72);
  background: linear-gradient(135deg, #0b2a1a 0%, #14532d 52%, #0e3b28 100%); }
.lp-foot a { color: rgba(255,255,255,.9); }
.lp-foot a:hover { color: var(--c-lime-b); }
.lp-foot::before { content:""; position:absolute; inset:0 0 auto 0; height:3px;
  background: linear-gradient(90deg, var(--green-600), var(--c-teal), var(--c-lime-b), var(--c-amber)); }

/* ============================================================
   BLOG - the list, one post, and the prose inside it. Shares the
   .lp shell above, so a post looks like the homepage rather than
   like a different company's site.
   ============================================================ */

.lp-blog-h { font-size: clamp(1.8rem, 3.4vw, 2.4rem); margin: 0 0 8px; letter-spacing: -.02em; }

.lp-posts { display: grid; grid-template-columns: repeat(auto-fit, minmax(288px, 1fr)); gap: 18px; }
.lp-post { display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line);
           border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); color: inherit;
           transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.lp-post:hover { transform: translateY(-4px); border-color: var(--green-600);
                 box-shadow: 0 18px 36px -16px rgba(20,83,45,.4); }
.lp-post-shot { display: block; background: #fff; aspect-ratio: 16 / 9; overflow: hidden; }
.lp-post-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lp-post-body { display: block; padding: 18px 20px 20px; }
.lp-post-meta { display: block; color: var(--muted); font-size: .8rem; font-weight: 600;
                text-transform: uppercase; letter-spacing: .05em; }
.lp-post-t { display: block; margin: 8px 0 6px; font-size: 1.08rem; font-weight: 700;
             color: var(--ink); line-height: 1.35; }
.lp-post:hover .lp-post-t { color: var(--green-900); }
.lp-post-d { display: block; color: var(--ink-soft); font-size: .92rem; line-height: 1.6; }
.lp-post-by { display: block; margin-top: 10px; color: var(--muted); font-size: .84rem; }

.lp-pager { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 28px; }
.lp-pager a, .lp-pager span { min-width: 38px; text-align: center; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink-soft);
  font-weight: 700; font-size: .9rem; }
.lp-pager a:hover { border-color: var(--green-600); color: var(--green-900); }
.lp-pager .on { background: var(--green-700); border-color: var(--green-700); color: #fff; }

/* One post: a single measured column - prose wider than about 70 characters
   loses the reader's place on the way back to the next line. */
.lp-article { max-width: 720px; margin-inline: auto; }
/* One or two cards must not stretch into full-width bands - same rule the
   plan and testimonial grids use. */
.lp-posts.few { max-width: 760px; }
.lp-article h1 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); line-height: 1.2; letter-spacing: -.02em;
                 margin: 10px 0 10px; color: var(--ink); }
.lp-back { display: inline-block; color: var(--green-700); font-weight: 700; font-size: .9rem; }
.lp-back:hover { color: var(--green-900); }
.lp-article-hero { margin: 20px 0 4px; }
.lp-article-lede { font-size: 1.1rem; line-height: 1.65; color: var(--ink); margin: 18px 0 0;
                   padding-left: 16px; border-left: 4px solid var(--green-600); }

.lp-prose { margin-top: 22px; }
.lp-prose p { color: var(--ink-soft); line-height: 1.8; margin: 0 0 18px; font-size: 1.02rem; }
.lp-prose h2 { font-size: 1.32rem; line-height: 1.35; color: var(--ink); margin: 34px 0 12px;
               letter-spacing: -.01em; }
.lp-prose ul { margin: 0 0 18px; padding: 0; display: grid; gap: 8px; }
.lp-prose li { list-style: none; color: var(--ink-soft); line-height: 1.7; font-size: 1.02rem;
               padding-left: 22px; position: relative; }
.lp-prose li::before { content: ""; position: absolute; left: 4px; top: .62em; width: 7px; height: 7px;
                       border-radius: 50%; background: var(--green-600); }

/* Homepage teaser strip. */
.lp-sec .lp-posts + .lp-cta { margin-top: 26px; }

/* ============================================================================
 * Sign in / sign up
 *
 * These were a dark green slab with a small white card floating in it - a
 * different product from the homepage a visitor had just been reading. They
 * now use the same vocabulary: the hero's gradient and aurora, .lp-chip for
 * the badges, .lp-stat for the proof cards, .lp-brands for the strip. Reusing
 * those classes rather than imitating them is the point - restyle the hero and
 * these follow.
 *
 * Two columns on desktop: the form on white, the proof beside it. One column
 * on a phone, FORM FIRST - somebody reaching for sign-in has already decided,
 * and making them scroll past marketing to reach a password field is a tax on
 * the people who are already customers.
 * ========================================================================== */
.au { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }
.au-only { grid-template-columns: 1fr; }              /* the short flows */

/* --- the form side ------------------------------------------------------- */
/* Three rows: the wordmark sits at the top, the footer at the bottom, and the
   form takes the space between and centres in it. Two auto margins on nested
   boxes fought each other and bunched everything against the middle-left. */
.au-form { display: grid; grid-template-rows: auto 1fr auto; justify-items: center;
           padding: 30px clamp(20px, 5vw, 64px) 30px; background: #fff; }
/* All three rows share one column width, so the wordmark's left edge lines up
   with the form's rather than hugging the viewport. */
.au-form > * { width: 100%; max-width: 400px; }
.au-wide .au-form > * { max-width: 520px; }
.au-form-in { align-self: center; padding-block: 28px; }
/* Takes the shared column width from .au-form > * and lays its own contents
   out from the left, so the mark sits directly above the form's first label. */
.au-brand { display: flex; align-items: center; justify-content: flex-start; gap: 10px;
            color: var(--green-900); font-weight: 700; font-size: 1.12rem; text-decoration: none; }
.au-brand:hover { text-decoration: none; }
.au-h1 { font-size: clamp(1.5rem, 2.6vw, 1.95rem); line-height: 1.16; letter-spacing: -.02em;
         color: var(--ink); margin: 0 0 6px; }
.au-lede { color: var(--ink-soft); font-size: .95rem; line-height: 1.6; margin: 0 0 20px; }
.au-form form { display: flex; flex-direction: column; gap: 13px; margin-top: 4px; }
.au-form .btn { width: 100%; justify-content: center; text-align: center; white-space: normal; }
.au-links { margin-top: 16px; display: flex; flex-direction: column; gap: 7px; font-size: .9rem; }
.au-links a { color: var(--green-700); font-weight: 600; }
.au-links a:hover { color: var(--green-900); }
.au-foot { color: var(--muted); font-size: .82rem; }
.au-foot a { color: var(--muted); font-weight: 600; }

/* A divider that says "or" without a table or a pseudo-element per side. */
.au-or { display: flex; align-items: center; gap: 10px; margin: 14px 0;
         color: var(--muted); font-size: .85rem; }
.au-or::before, .au-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.au-error { background: var(--red-bg); color: var(--red); padding: 10px 13px; border-radius: 10px;
            font-size: .89rem; margin-bottom: 14px; }
.au-error div + div { margin-top: 4px; }
.au-ok { background: var(--green-100); color: var(--green-900); padding: 10px 13px;
         border-radius: 10px; font-size: .89rem; margin-bottom: 14px; }

/* --- the proof side ------------------------------------------------------ */
.au-aside { position: relative; overflow: hidden; display: flex; flex-direction: column;
            justify-content: center; padding: 44px clamp(24px, 4vw, 56px);
            background: linear-gradient(160deg, #e3f6ec 0%, #f1fbf6 40%, #ffffff 72%, #ecf9f2 100%);
            border-left: 1px solid var(--line); }
.au-aside-in { position: relative; z-index: 1; max-width: 460px; margin: 0 auto; width: 100%; }
.au-aside h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); line-height: 1.2; letter-spacing: -.02em;
               color: var(--ink); margin: 0 0 12px; }
.au-aside h2 em { color: var(--green-700); font-style: normal; }
.au-aside p { color: var(--ink-soft); line-height: 1.62; margin: 0 0 22px; }
.au-aside .lp-stats { grid-template-columns: 1fr 1fr; }
/* The hero visual under the stats - the drawn shelves, or the uploaded hero
   photo when the homepage has one. Sized to the room the viewport actually
   has: the column already fills a 900px screen with copy and stat cards, and
   a picture that pushes the pitch past the fold - or shoves the FORM's
   centre down with it - sells worse than no picture. So it shrinks on short
   screens and yields entirely on very short ones; the copy is the proof, the
   picture is garnish. */
.au-aside .lp-photo { margin: 24px auto 0; max-width: 400px; }
@media (max-height: 1120px) { .au-aside .lp-photo { max-width: 300px; } }
@media (max-height: 980px)  { .au-aside .lp-photo { max-width: 220px; } }
@media (max-height: 840px)  { .au-aside .lp-photo { display: none; } }
.au-aside .lp-brands { border: 0; background: none; padding: 26px 0 0; }
.au-aside .lp-brand { font-size: .92rem; padding: 4px 6px; }

/* One column below the split. The proof follows the form rather than leading
   it, and drops its own min-height so a phone is not two full screens. */
@media (max-width: 900px) {
  .au { grid-template-columns: 1fr; min-height: 0; }
  .au-form { min-height: 100vh; justify-content: center; }
  .au-aside { border-left: 0; border-top: 1px solid var(--line); padding-block: 36px; }
  .au-aside .lp-stats { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .au-form { padding-inline: 18px; min-height: 0; padding-block: 26px 30px; }
  .au-aside { padding-inline: 18px; }
  .au-brand { font-size: 1rem; }
}

/* The short flows - forgot, reset, 2FA, notices - have no proof panel, so the
   form column carries the gradient instead of sitting on flat white. */
.au-only .au-form { background: linear-gradient(160deg, #e8f7ee 0%, #f4fbf7 46%, #ffffff 100%); }
.au-only .au-form-in { background: #fff; border: 1px solid var(--line); border-radius: 16px;
                       padding: 28px 26px 26px; box-shadow: 0 18px 46px rgba(12,58,32,.10); }
.au-only .au-brand { margin-bottom: 18px; }
.au-only .au-foot { padding-top: 18px; }
