/* ============================================================
   Mobile layer for the 2026-09 marketing site.

   The pages are exported from design artboards at a fixed 1440px and
   carry an inline style="" on almost every element, with no breakpoints
   of their own. Two consequences shape this file:

   1. Nearly every rule needs !important. An inline style beats any
      stylesheet rule otherwise, and the export is entirely inline.
   2. The export is regenerated from the artboards (build.py, dist.py),
      so this lives in its own file, injected at publish time by
      inject_mobile.py. Rules written into the HTML would be lost on the
      next export.

   Only takes effect below 860px. Above that the artboard layout stands
   exactly as designed.
   ============================================================ */

@media (max-width: 860px) {

  /* ---------- the thing that was actually broken ----------
     The artboard container clips whatever is wider than it. With fixed
     pixel widths up to 1360px inside, a phone did not scroll sideways;
     the overflowing right-hand side was silently cut off and could not
     be reached at all. */
  #top { overflow: visible !important; }
  /* clip, not hidden: hidden on both html and body turns body into a
     scroll container that never scrolls, and the pinned header (header.css)
     would then stick to body instead of the screen, i.e. never stick. The
     hidden line stays as the fallback for browsers without clip. */
  html, body { overflow-x: hidden; overflow-x: clip; max-width: 100%; }

  /* Nothing may exceed the screen. This has to cover every element, not
     only those carrying an inline width: the hero's two panels and the
     use-case column are sized from the page's own <style> block, so a
     selector keyed on the style attribute missed them, and a max-width
     cap only cascades if nothing in the chain escapes it. */
  #top * { max-width: 100% !important; }
  /* The logo marquee is supposed to be wider than the screen. It animates
     inside an overflow:hidden wrapper, so capping it stops the scroll.
     Note the #top prefix: `#top *` above is (1,0,0) and beats a bare class
     even when both carry !important. */
  #top .mq, #top .mq * { max-width: none !important; }
  /* The announcement bar and nav live outside #top, in the pinned header
     inject_header.py builds, so they need the same cap of their own. */
  .kr-head * { max-width: 100% !important; }

  /* The 40px artboard gutter is too wide at this size. Matching on both
     substrings keeps this to elements that actually set that gutter. */
  #top [style*="padding"][style*="40px"] {
    padding-left: 20px !important;
    padding-right: 20px !important;
  }

  /* Legal copy carries long unbroken tokens (addresses, urls) that have no
     wrap opportunity and run past the edge. */
  #top p, #top li, #top span, #top a, #top strong, #top td, #top th {
    overflow-wrap: break-word !important;
  }

  /* A comparison table cannot shrink below the natural width of its cells.
     Rather than crushing the type, the table itself scrolls sideways. */
  #top table {
    display: block !important;
    overflow-x: auto !important;
    max-width: 100% !important;
  }
  #top table th, #top table td { padding-left: 10px !important; padding-right: 10px !important; }

  /* ---------- rows become stacks ---------- */
  #top > div { flex-wrap: wrap !important; }
  #top [style*="width: 46%"],
  #top [style*="width: 54%"] { width: 100% !important; }
  /* Card rows - the four pricing tiers, the split feature sections - are
     equal-width flex children of a stretch row. Left as a row they do not
     overflow, they just squeeze to ~78px and wrap one letter per line,
     which is why "nothing is clipped" was not the same as "readable". */
  #top [style*="display: flex"][style*="align-items: stretch"] {
    flex-direction: column !important;
  }

  /* Side-by-side text/art sections carry big vertical padding meant for
     a tall desktop viewport. */
  #top [style*="padding: 128px"],
  #top [style*="padding: 96px"],
  #top [style*="padding: 88px"],
  #top [style*="padding: 80px"],
  #top [style*="padding: 76px"] {
    padding-top: 48px !important;
    padding-bottom: 48px !important;
  }

  /* ---------- nav ----------
     The bar is a single 84px flex row with hover dropdowns. It wraps to
     as many rows as it needs instead. Hover menus are unusable on touch,
     but each parent is itself a link to the section, so tapping still
     goes somewhere sensible. */
  .kr-nav > div {
    height: auto !important;
    min-height: 0 !important;
    flex-wrap: wrap !important;
    gap: 10px 16px !important;
    padding: 14px 20px !important;
  }
  /* Anchored to its trigger, a menu opened from the right-hand end of the
     row ran off the screen. Making the trigger static hands positioning to
     the nav bar, which is the nearest positioned ancestor, so the menu
     becomes one full-width panel beneath the whole nav. */
  .kr-head .navdd { position: static !important; }
  .kr-head .navmenu {
    left: 20px !important;
    right: 20px !important;
    top: calc(100% + 6px) !important;
    min-width: 0 !important;
    /* The blanket cap above resolves against the containing block, which for
       an absolutely positioned menu was its trigger - about 86px. That turned
       each dropdown into a tall ribbon reaching halfway down the page. */
    max-width: none !important;
    width: auto !important;
    /* The menu lives in the pinned header, so scrolling the page no longer
       brings its lower entries into view. On a phone held sideways the
       Use cases list is taller than the screen, so it scrolls itself.
       No overscroll containment: once the list reaches its end the scroll
       must pass to the page, which is what moves the announcement out of
       the way when the menu is opened at the top of the page. */
    max-height: calc(100vh - var(--kr-pin-h, 101px) - 12px) !important;
    max-height: calc(100dvh - var(--kr-pin-h, 101px) - 12px) !important;
    overflow-y: auto !important;
  }
  /* Hover and focus-within cannot open these on touch, so below the
     breakpoint the menus answer to a class that mobile.js toggles on tap.
     The hover rules are neutralised here so a sticky :hover cannot leave a
     menu open after the tap that navigated away from it. */
  .navdd:hover .navmenu,
  .navdd:focus-within .navmenu {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
  }
  .navdd.nav-open .navmenu {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }
  .navdd:hover .navchev { transform: none; }
  .navdd.nav-open .navchev { transform: rotate(180deg) !important; }

  /* Wrapping alone left Sign up stranded on a third row, left-aligned under
     the links. The section links take a row of their own so the mark, Log in
     and Sign up share the first one, with the two actions pushed right. */
  .kr-nav > div > div:nth-of-type(2) {
    order: 2 !important;
    flex-basis: 100% !important;
    gap: 18px !important;
  }
  .kr-nav > div > a { order: 1 !important; }
  .kr-nav > div > a:first-of-type { margin-left: auto !important; }
  /* Black against a page of brand blue, directly under a white pill in the
     announcement bar: three button styles in the top 200px. */
  .kr-nav a.btn {
    background: #343CED !important;
    color: #FFFFFF !important;
  }

  /* ---------- display type ----------
     48px and 40px headings set for a 1440px canvas are far too large on
     a 390px screen; these track down with the viewport instead. */
  #top h1 {
    font-size: clamp(27px, 7.4vw, 36px) !important;
    letter-spacing: -1.2px !important;
  }
  #top h2 {
    font-size: clamp(23px, 6.1vw, 30px) !important;
    letter-spacing: -0.9px !important;
  }

  /* ---------- the announcement bar ----------
     Fixed at 64px with its copy and its button on one line. At this width
     they wrap, so the button sat at bottom:88 - outside the bar - and
     showed as a sliver cut in half by the nav below it. The side padding
     keeps the wrapped copy clear of the close button (header.css). */
  .kr-ann {
    height: auto !important;
    min-height: 0 !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 10px !important;
    padding: 14px 44px !important;
  }

  /* ---------- hero ----------
     The stage is a fixed height with its two panels centred absolutely and
     cross-dissolved. The answer panel runs 432-661px depending on which
     channel is showing, so a fixed stage clipped it in every state. On a
     phone the panels become ordinary flow content and the inactive one is
     removed, so the stage is exactly as tall as what it is showing. */
  #heroSwap {
    width: 100% !important;
    height: auto !important;
  }
  #heroSwap > div {
    position: relative !important;
    left: auto !important;
    top: auto !important;
    transform: none !important;
  }
  #heroSwap.ask #boxOut { display: none !important; }
  #heroSwap.out #boxAsk { display: none !important; }

  /* The panel inside the stage keeps a 56px desktop gutter, which left the
     ask field 101px and its placeholder cut to "Alert me whe". */
  #heroSwap [style*="padding: 44px 56px"] { padding: 22px 18px !important; }
  #heroSwap input { font-size: 15px !important; min-width: 0 !important; }

  /* ---------- the source carousel ----------
     38s to cross a 1440px canvas reads as barely moving on a phone. */
  .mq { animation-duration: 16s !important; }

  /* ---------- the chain diagram ----------
     Four cards absolutely placed at left: 80/400/720/1040 inside a
     1360px band. Shrinking the band alone would leave them stranded off
     screen, so they become a stacked list over the painting and the
     connecting arrows (which no longer describe the layout) are hidden. */
  #crosslink .art {
    height: auto !important;
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
    padding: 16px !important;
    /* The band is content-box, so the padding above would otherwise be
       added to its width and push it past the gutter. */
    box-sizing: border-box !important;
  }
  #crosslink .art > svg { display: none !important; }
  #crosslink .xbox {
    position: static !important;
    width: 100% !important;
    height: auto !important;
    min-height: 74px !important;
    padding: 14px 16px !important;
  }

  /* ---------- the use-case accordion ----------
     The closed row is mark + a fixed 140px label + the heading, which left
     the heading 149px and clipped it mid-word. The open body is a text
     column beside a 300px image that collapsed to nothing. Both stack. */
  .ucsum {
    flex-wrap: wrap !important;
    gap: 8px 14px !important;
    padding: 20px 18px !important;
  }
  .ucsum > span[style*="width: 140px"] { width: auto !important; flex-shrink: 1 !important; }
  .ucsum > span[style*="font-size: 26px"] {
    flex-basis: 100% !important;
    font-size: 20px !important;
    letter-spacing: -0.6px !important;
  }
  #uses details.uc > div {
    flex-direction: column !important;
    gap: 18px !important;
    padding-left: 18px !important;
    padding-right: 18px !important;
  }
  #uses details.uc [style*="width: 300px"] {
    width: 100% !important;
    height: 190px !important;
    flex-shrink: 1 !important;
  }
  /* The two labelled notes inside a use-case sit side by side at ~110px each. */
  #uses details.uc [style*="display: flex"][style*="gap: 26px"],
  #uses details.uc [style*="display: flex"][style*="gap: 22px"] { flex-wrap: wrap !important; }

  /* The three labelled notes inside an open use-case are equal flex
     columns; at this width each got ~112px and the third fell off the
     edge. Stacked, their left rules read as a list instead. */
  #uses [style*="align-items: flex-start"][style*="margin-bottom: 4px"] {
    flex-direction: column !important;
    gap: 16px !important;
  }
  #uses [style*="flex: 1"][style*="border-left"] {
    padding: 2px 0 2px 14px !important;
  }
  /* The open body is indented 74px to clear the marker column. */
  #uses [style*="34px 74px"] { padding: 2px 18px 26px 18px !important; }

  /* ---------- the "Read as it publishes" band ----------
     White type sits on the blurred painting, which is pale just there:
     1.28:1 against a 3.0 minimum for large text. The text column is a
     positioned sibling after the image, so a ground of its own paints over
     it without touching the artwork. Mobile only, by request; desktop
     keeps the design as drawn and stays at 1.82:1. */
  #how > div:nth-of-type(2) {
    /* Full strength over the type; only the last sliver softens, so the
       band does not end as a hard rectangle. Fading it earlier dropped the
       heading to 2.2:1, which defeats the point of the scrim. */
    background: linear-gradient(180deg,
      rgba(16,26,85,0.72) 0%,
      rgba(16,26,85,0.70) 86%,
      rgba(16,26,85,0.40) 100%) !important;
  }

  /* ---------- source logo strip ----------
     The static variant spaces eleven logos across a full desktop row. */
  .mq-static {
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 18px 22px !important;
    padding: 0 8px !important;
  }
  /* The marks keep their desktop size, which on a 390px strip means one
     wordmark spanning 40% of the screen. */
  /* Each mark sits in a span padded 46px each side for the desktop strip.
     Kept at that spacing, the smaller marks read as a nearly empty rail. */
  #top .mq > span { padding: 0 19px !important; }
  #top .mq img {
    height: auto !important;
    width: auto !important;
    /* Both bounds: capping height alone let the wide wordmarks grow to fit
       it, which made the worst offender larger, not smaller. */
    max-height: 26px !important;
    max-width: 104px !important;
  }

  /* The lime call-out is a single row of copy plus button; the button ran
     70px past the edge. */
  #top [style*="#D8FD49"] {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 20px !important;
    padding: 26px 22px !important;
  }

  /* The chain band is the one element still bleeding past the gutter. */
  #crosslink .art { width: 100% !important; }

  /* ---------- footer ---------- */
  #top [style*="grid-template-columns: repeat(4"] {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 22px !important;
  }
  /* The logo column and the link column (built by inject_footer.py) sit
     side by side, which on a phone squeezes the links off the screen. They
     stack instead: the tagline and button first, as before, then the links,
     then the logo closing the footer. The #top prefix outranks the generic
     gap rules at the end of this block. */
  #top .ftr .ftr-main { flex-direction: column !important; gap: 40px !important; }
  #top .ftr .ftr-side { gap: 30px !important; }
  #top .ftr .ftr-cta {
    order: -1 !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 16px !important;
  }
  /* 280px of cube is most of a phone screen; half that still reads as the
     mark, not a stray icon. */
  #top .ftr .ftr-mark { order: 1 !important; width: 150px !important; gap: 14px !important; }
  /* Bottom bar: copyright and address stop fighting for one line. Direct
     children only: the logo and link columns also space-between. */
  .ftr > [style*="justify-content: space-between"] {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }

  /* The legal pages set a 250px flex-shrink:0 contents sidebar beside the
     body. At this width that left the body 68px, which turned the privacy
     page into a 63,000px tall ribbon of one-word lines. */
  #top [style*="max-width: 1100px"][style*="display: flex"],
  #top [style*="max-width: 900px"][style*="display: flex"] {
    flex-direction: column !important;
    gap: 22px !important;
  }
  #top [style*="width: 250px"][style*="flex-shrink: 0"] { width: 100% !important; }

  /* ---------- pages built as a narrow column beside a wide one ----------
     Support and About put a fixed-width title column next to the body. */
  #top [style*="width: 300px"],
  #top [style*="width: 460px"] { width: 100% !important; flex-shrink: 1 !important; }

  /* Gaps sized for a 1360px row are far too large once stacked. */
  #top [style*="gap: 80px"] { gap: 28px !important; }
  #top [style*="gap: 56px"] { gap: 26px !important; }
}

/* Large phones on their side (861-932px wide) get the desktop footer, but the
   280px logo stands 375px tall, more than the room under the pinned nav, so
   the top of the cube was always hidden. flex-end keeps the cube on the
   wordmark once the column is shorter than the links beside it. */
@media (min-width: 861px) and (max-height: 540px) {
  #top .ftr .ftr-mark {
    width: 180px !important;
    gap: 14px !important;
    justify-content: flex-end !important;
  }
}

/* Narrow phones: the artboard's smallest assumptions stop holding. */
@media (max-width: 520px) {
  #top [style*="padding"][style*="40px"],
  .kr-nav > div {
    padding-left: 16px !important;
    padding-right: 16px !important;
  }
  /* Pricing and use-case cards set their own inner gutters. */
  #top [style*="padding: 34px 36px"] { padding: 22px 20px !important; }
  /* The mock browser chrome's right-hand icon cluster is flex-shrink:0 and
     is the last thing that will not give. It is decorative. */
  #wire [style*="padding: 11px 16px"] > div:last-child { display: none !important; }
  /* The mock email's timestamp is flex-shrink:0 and is the last thing over
     the edge on a 320px screen. Decorative. */
  #wire [style*="font-size: 12.5px"][style*="flex-shrink: 0"] { display: none !important; }
}
