/* ===================================================================
   HOPIN MOBILE — shared stylesheet
   Loaded on every page. All rules are scoped:
   - Touch-device overrides:           (hover: none) and (pointer: coarse)
   - Viewport mobile overrides:         (max-width: 767px)
   Desktop (>= 768px + pointer:fine) never reads these rules.
   =================================================================== */

@media (hover: none) and (pointer: coarse) {
  ::selection { background: #d1d5e1 !important; color: #000 !important; }
}

/* ===================================================================
   MOBILE — kill ALL animations, transitions, and transforms that
   cause scroll jank, broken tap targets, and layout thrash on phones.
   Exceptions:
   - .ig-track / .ig-track-reverse: the company-logos marquee is a pure
     CSS keyframe translateX animation on a composited element. It runs
     off the compositor thread and has zero scroll cost, so we keep it.
   =================================================================== */
@media (max-width: 767px) {
  *:not(.ig-track):not(.ig-track-reverse),
  *::before,
  *::after {
    animation: none !important;
    animation-delay: 0s !important;
    animation-duration: 0s !important;
    transition: none !important;
    transition-delay: 0s !important;
    transition-duration: 0s !important;
  }

  /* Re-assert the marquee keyframe animations (in case some earlier
     inherited !important rule killed them). Faster on mobile — at 36s
     only 2-3 logos are visible on a 393px screen, making the scroll
     imperceptible. 20s gives a noticeable, smooth flow. */
  #integrations-wrap .ig-track {
    animation: ig-scroll-left 20s linear infinite !important;
    will-change: transform;
  }
  #integrations-wrap .ig-track.ig-track-reverse {
    animation: ig-scroll-right 20s linear infinite !important;
  }

  .gsap-fade-up,
  .gsap-fade-in,
  .gsap-scale-in,
  .gsap-slide-right,
  .gsap-slide-left {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }

  [data-section-reveal] {
    opacity: 1 !important;
    transform: none !important;
    will-change: auto !important;
  }

  #scroll-text-reveal {
    padding: 0 20px !important;
  }
  #scroll-text-container {
    font-size: clamp(1.2rem, 5vw, 1.8rem) !important;
  }

  #fp-section {
    top: 60px !important;
    height: calc(100vh - 60px) !important;
    padding: 0 16px !important;
  }
  #fp-section > div > div[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
  }
  .fp-dots {
    display: none !important;
  }
  #fp-video-stage {
    width: 100% !important;
    height: auto !important;
    aspect-ratio: 720 / 560;
    max-width: 340px !important;
    margin: 0 auto;
  }
  .fp-text-block h3 {
    font-size: 18px !important;
  }
  .fp-text-block p {
    font-size: 13px !important;
  }

  /* --- Hero: allow wrapping on narrow screens --- */
  #hero-copy-stack {
    width: 100% !important;
  }
  #hero-top-line {
    white-space: normal !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    font-size: clamp(18px, 5.5vw, 28px) !important;
  }
  #hero-bottom-line {
    white-space: normal !important;
    font-size: clamp(18px, 5.5vw, 28px) !important;
  }

  #hp-shield { display: none !important; }

  html.lenis, html.lenis body,
  .lenis.lenis-smooth {
    scroll-behavior: auto !important;
  }

  /* Page grain, on — but resized for a phone.
     The noise is an AVIF tile inside .framer-m7bx2v, drawn at
     background-size:153.5px. Enabling it at that size is what made the
     cream look dirty: 153.5px is 10.7% of a 1440px desktop viewport but
     39% of a 390px phone, so the same tile reads as fine texture on a
     laptop and as coarse blotches on a phone. The grain was not too
     strong, it was too big.
     Dividing the tile by the device pixel ratio makes each grain the same
     physical size as it is on the laptop. */
  .framer-m7bx2v { display: block !important; opacity: .13 !important; }
  .framer-m7bx2v > div { background-size: 77px !important; }
}
@media (max-width: 767px) and (min-resolution: 2.5dppx) {
  .framer-m7bx2v > div { background-size: 51px !important; }
  #cmp-wrap .cmp-row.cmp-header { background-size: auto, 51px !important; }
}
@media (max-width: 767px) {

  .rp-pillar,
  .rp-eyebrow,
  .rp-title,
  .rp-sub {
    opacity: 1 !important;
    transform: none !important;
  }

  [data-framer-appear-id] {
    opacity: 1 !important;
    transform: none !important;
  }

  #hopin-intro { display: none !important; }

  [data-tc-reveal],
  [data-ig-reveal],
  [data-cmp-reveal],
  [data-faq-reveal],
  [data-fc-reveal] {
    opacity: 1 !important;
    transform: none !important;
    will-change: auto !important;
  }

  #perfectly-results-wrap .framer-1qs8pbp-container,
  #perfectly-results-wrap .framer-aetetz,
  #perfectly-results-wrap .framer-1y8vbyu,
  #perfectly-results-wrap .framer-xm1cb0,
  #perfectly-results-wrap .framer-d9rgpg-container,
  #perfectly-results-wrap .framer-q7q29i-container {
    opacity: 1 !important;
    transform: none !important;
  }

  .framer-1oov14a { pointer-events: none !important; }

  /* Hero BG: kill the will-change compositor layers that cause the image
     to visually shift/lag relative to surrounding content during scroll. */
  .framer-1a0h3hm,
  .framer-1bgsizk {
    will-change: auto !important;
    transform: none !important;
  }

  /* =================================================================
     Hero text blur was previously patched here with a stack of
     !important overrides. The actual root causes — JS-applied
     `transform:translateX(-50%)` on the h1, `transform:translateY(0)`
     idle state on #hero-rotating-person, and `filter:blur(0px)` +
     `will-change:transform` on the bubble span — are now fixed AT
     THE SOURCE in index.html (search for "Hero headline — flex-based
     centering"). No mobile overrides are needed; the fix applies
     identically on every viewport.

     The one exception kept here is the "See all tools" 1.5px border
     → whole-pixel 1px, which only shimmers on phone DPR values
     anyway and isn't really a compositor issue.
     ================================================================= */
  .framer-r77l27 a[href="#fp-section-wrapper"] {
    border-width: 1px !important;
  }
}

/* --- The mobile nav trigger + panel are hidden on desktop --- */
#mn-bar,
#mobile-nav { display: none; }

/* --- Defensive global kill for any stale #fp-mobile-cards from a cached
       build of mobile.js. The real Three.js slab is the single source of
       truth on all devices now. --- */
#fp-mobile-cards { display: none !important; }

/* =================================================================
   MOBILE LAYOUT — everything below triggers only at <= 767px
   ================================================================= */
@media (max-width: 767px) {
  html, body { -webkit-text-size-adjust: 100%; }
  /* `clip` (not `hidden`) prevents horizontal scroll without creating a
     scroll container, so position:sticky still works on descendants. */
  body { overflow-x: clip !important; }

  /* --- Hide desktop navs (Framer nav variants on index + hpn-nav on other pages) --- */
  .framer-1g8rqds-container,
  .framer-1q437l8-container,
  [class*="framer-"][class*="container"] > nav[class*="framer-"],
  nav.hpn-nav { display: none !important; }
  /* Hide any fixed-position Framer element containing nav links (defensive) */
  [class*="framer-"] > nav { display: none !important; }

  /* --- Mobile top bar: no boxes, floats on the page bg.
     Absolutely-positioned so it scrolls away with the page. --- */
  #mn-bar {
    position: absolute;
    top: 22px;
    left: 24px;   /* Hopin logo nudged slightly right of the edge */
    right: 18px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    z-index: 150;
    pointer-events: none; /* children re-enable */
  }
  #mn-bar .mn-logo-pill {
    pointer-events: auto;
    height: 40px;
    padding: 0;
    background: transparent;
    border: none;
    display: flex;
    align-items: center;
    text-decoration: none;
  }
  #mn-bar .mn-logo-pill img {
    height: 24px;
    width: auto;
    display: block;
    filter: none;
    opacity: 1;
  }

  /* Right group: login button + hamburger side-by-side */
  #mn-bar .mn-right-group {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 14px;
  }

  /* Main-screen login CTA (matches desktop's hopin-login-btn styling) */
  #mn-bar .mn-login-top {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #6F7FAD;
    color: #fff;
    font-family: 'Manrope', sans-serif;
    font-size: 13px;
    font-weight: 500;
    padding: 9px 16px;
    border-radius: 8px;
    text-decoration: none;
    box-shadow: 0 1px 3px rgba(111,127,173,0.3);
    transition: background 0.2s ease, transform 0.2s ease;
  }
  #mn-bar .mn-login-top:active { background: #5A6A94; transform: translateY(-1px); }
  /* Hide the main-screen login when the menu is open — only the X should
     live next to the logo in the open state. */
  #mn-bar.is-open .mn-login-top {
    opacity: 0;
    pointer-events: none;
    transform: translateX(8px);
    transition: opacity 0.2s ease, transform 0.25s ease;
  }
  #mn-bar .mn-login-top .dg {
    display: inline-grid;
    grid-template-columns: repeat(2, 3px);
    gap: 2px;
    margin-left: 4px;
  }
  #mn-bar .mn-login-top .dg i {
    width: 3px; height: 3px; background: #fff; border-radius: 1px;
    display: block;
  }

  /* Hamburger — Freeport-style 2 asymmetric lines, right-aligned */
  #mn-bar .mn-trigger {
    width: 30px;
    height: 40px;
    justify-content: center;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
  }
  #mn-bar .mn-trigger .ml-stack {
    position: relative;
    width: 24px;
    height: 12px;
  }
  #mn-bar .mn-trigger .ml {
    position: absolute;
    right: 0;
    height: 1.8px;
    background: #6F7FAD;
    border-radius: 0;
    transform-origin: 100% 50%;
    transition: transform 0.4s cubic-bezier(0.7, 0, 0.3, 1),
                opacity 0.2s ease,
                width 0.3s ease,
                background-color 0.25s ease;
  }
  #mn-bar .mn-trigger .ml-top { top: 2px; width: 14px; }
  #mn-bar .mn-trigger .ml-bot { bottom: 2px; width: 24px; }

  /* Open state: become an X (both lines equal length, rotated) */
  #mn-bar.is-open .mn-trigger .ml-top {
    top: 50%;
    width: 20px;
    transform: translateY(-50%) rotate(-45deg);
    transform-origin: 50% 50%;
    right: 2px;
  }
  #mn-bar.is-open .mn-trigger .ml-bot {
    bottom: auto;
    top: 50%;
    width: 20px;
    transform: translateY(-50%) rotate(45deg);
    transform-origin: 50% 50%;
    right: 2px;
  }

  /* --- Mobile nav panel --- */
  #mobile-nav {
    position: fixed;
    inset: 0;
    z-index: 140;
    pointer-events: none;
    display: block;
    visibility: hidden;
  }
  #mobile-nav.is-open,
  #mobile-nav.is-closing { visibility: visible; pointer-events: auto; }
  #mobile-nav.is-closing { pointer-events: none; }

  #mobile-nav .mn-backdrop {
    position: absolute;
    inset: 0;
    /* Same cream + noise recipe as the rest of the page so the menu
       panel blends with the site and doesn't read as a lighter sheet. */
    background:
      linear-gradient(rgba(255, 254, 246, 0.87), rgba(255, 254, 246, 0.87)),
      url('noise.avif') top left repeat;
    opacity: 0;
    transition: opacity 0.35s cubic-bezier(0.2, 0.7, 0.25, 1);
  }
  #mobile-nav.is-open .mn-backdrop { opacity: 1; }
  #mobile-nav.is-closing .mn-backdrop { opacity: 1; }

  /* Panel content — Freeport-style: logo area at top (just empty space
     since our logo stays in the fixed nav bar), links VERTICALLY
     CENTERED in the middle via .mn-links-wrap (flex: 1), Login pill +
     socials stacked at the bottom. */
  #mobile-nav .mn-content {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    padding: 100px 28px 36px;
    overflow: hidden;
  }
  #mobile-nav .mn-links-wrap {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    min-height: 0;
  }
  #mobile-nav .mn-links-wrap > .mn-links { width: 100%; }

  /* Links */
  #mobile-nav .mn-links {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-bottom: 28px;
  }
  #mobile-nav .mn-links a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 18px 0;
    font-family: 'General Sans', 'Manrope', sans-serif;
    font-size: 26px;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: #1a1a1a;
    text-decoration: none;
    border-bottom: 1px solid rgba(26, 26, 26, 0.08);
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s cubic-bezier(0.2, 0.7, 0.25, 1),
                transform 0.6s cubic-bezier(0.2, 0.7, 0.25, 1),
                color 0.2s ease;
  }
  #mobile-nav .mn-links a:active { color: #6F7FAD; }
  #mobile-nav .mn-arrow {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px;
    transition: transform 0.2s ease;
  }
  #mobile-nav .mn-arrow-img {
    width: 22px; height: 22px;
    object-fit: contain;
    display: block;
  }
  #mobile-nav .mn-links a:active .mn-arrow { transform: translate(3px, -3px); }
  /* Label wrapper holds both the active dot and the text so the arrow
     can stay on the far right of the flex container. */
  #mobile-nav .mn-links .mn-label {
    display: inline-flex;
    align-items: center;
    gap: 12px;
  }
  #mobile-nav .mn-links .mn-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #6F7FAD;
    flex: none;
  }

  #mobile-nav.is-open .mn-links a { opacity: 1; transform: none; }
  #mobile-nav.is-open .mn-links a:nth-child(1) { transition-delay: 0.28s; }
  #mobile-nav.is-open .mn-links a:nth-child(2) { transition-delay: 0.36s; }
  #mobile-nav.is-open .mn-links a:nth-child(3) { transition-delay: 0.44s; }
  #mobile-nav.is-open .mn-links a:nth-child(4) { transition-delay: 0.52s; }

  /* Footer: Login full-width + Socials centered below. Matches
     Freeport's stacked CTAs-then-socials layout. */
  #mobile-nav .mn-footer {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
    padding-top: 16px;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s ease 0.58s, transform 0.6s ease 0.58s;
  }
  #mobile-nav.is-open .mn-footer { opacity: 1; transform: none; }

  #mobile-nav .mn-socials { display: flex; gap: 16px; }
  /* No boxes behind the social icons — they sit directly on the cream. */
  #mobile-nav .mn-soc {
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent;
    border: none;
    border-radius: 0;
    text-decoration: none;
  }
  #mobile-nav .mn-soc img {
    width: 26px; height: 26px; display: block; object-fit: contain;
    filter: none;
  }

  #mobile-nav .mn-login {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    background: #6F7FAD; color: #fff;
    font-family: 'Manrope', sans-serif;
    font-size: 15px; font-weight: 500;
    padding: 15px 28px;
    border-radius: 12px;
    text-decoration: none;
    box-shadow: 0 2px 10px rgba(111, 127, 173, 0.35);
    width: 100%;
  }
  #mobile-nav .mn-login .dg {
    display: inline-grid;
    grid-template-columns: repeat(2, 4px);
    gap: 2px; margin-left: 6px;
  }
  #mobile-nav .mn-login .dg i {
    width: 4px; height: 4px; background: #fff; border-radius: 1px;
    display: block;
  }
  /* Socials centered below the login */
  #mobile-nav .mn-socials { justify-content: center; }

  /* Body scroll lock while nav open */
  body.mn-scroll-lock { overflow: hidden; touch-action: none; }

  /* =================================================================
     Other mobile polish (hero, hero-img, section padding compensation)
     ================================================================= */

  /* Pad top of first content to clear the fixed mobile bar */
  body { padding-top: 0; }

  /* Scroll-text-reveal — keep the sticky pinning exactly like desktop.
     Increased height so phrases take MORE scroll distance to appear
     (Caretta-style slow reveal, not rapid-fire on a fast scroll). */
  #scroll-text-wrapper {
    height: 320vh !important;
  }
  #scroll-text-reveal {
    padding: 0 20px !important;
    /* overflow must stay visible so sticky works */
  }
  #scroll-text-container {
    max-width: 100% !important;
    font-size: clamp(22px, 6.5vw, 32px) !important;
    line-height: 1.25 !important;
  }
  #scroll-text-container .scroll-phrase {
    white-space: normal !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
    display: inline !important;
  }

  /* =================================================================
     3D SLAB SECTION — keep the real Three.js animation on mobile.
     Overrides the desktop 2-col grid to 1-col (text above, canvas below),
     rescales the canvas stage to fit the viewport, and shrinks the
     progress dots + text blocks for a mobile body.
     ================================================================= */
  #fp-section-wrapper {
    display: block !important;
    height: 450vh !important;
  }
  #fp-section {
    top: 24px !important;
    padding: 24px 18px 24px !important;
    height: 100vh !important;
    align-items: flex-start !important;
  }
  #fp-section > div { width: 100%; max-width: 100%; }
  /* Section heading "Tools designed for success" — bigger, dramatic */
  #fp-section h2 {
    font-size: clamp(22px, 3.1vw, 38px) !important;
    margin-bottom: 24px !important;
    line-height: 1.2 !important;
  }
  /* Desktop inline grid: `grid-template-columns:1fr 1fr;gap:40px` — force stack */
  #fp-section > div > div[style*="grid-template-columns:1fr 1fr"] {
    grid-template-columns: 1fr !important;
    gap: 16px !important;
    align-items: start !important;
  }
  /* Left column: dots + text block side-by-side */
  #fp-section > div > div[style*="grid-template-columns:1fr 1fr"] > div:first-child {
    gap: 14px !important;
  }
  #fp-section .fp-dots {
    margin-top: 0 !important;
    gap: 8px !important;
    flex-shrink: 0;
  }
  #fp-section .fp-dot {
    width: 7px !important;
    height: 7px !important;
  }
  #fp-section .fp-dot-active {
    width: 7px !important;
    height: 32px !important;
  }
  #fp-text-container {
    max-width: 100% !important;
    min-height: 0 !important;
    flex: 1 1 auto !important;
    width: 100% !important;
  }
  .fp-text-block h3 {
    font-size: 20px !important;
    line-height: 1.2 !important;
  }
  .fp-text-block p {
    font-size: 13.5px !important;
    line-height: 1.5 !important;
    margin-top: 10px !important;
  }
  /* Right column: Three.js canvas stage — full-width, taller on mobile */
  #fp-section > div > div[style*="grid-template-columns:1fr 1fr"] > div:nth-child(2) {
    min-height: 0 !important;
    align-items: flex-start !important;
    padding: 0 !important;
    overflow: hidden !important;
  }
  #fp-video-stage {
    width: calc(100% + 36px) !important;
    height: auto !important;
    aspect-ratio: 720 / 560;
    max-width: none !important;
    margin: 8px -18px 0 !important;
  }
  #slab-canvas {
    width: 100% !important;
    height: 100% !important;
    display: block !important;
  }

  /* Kill the old mobile card-stack (no longer needed — real slab section is visible) */
  #fp-mobile-cards { display: none !important; }

  /* Section padding — generous enough to feel like distinct rooms */
  #perfectly-results-wrap,
  #tc-wrap,
  #integrations-wrap,
  #cmp-wrap,
  #faq-wrap { padding: 56px 0 !important; }

  /* =================================================================
     Comparison table — "logo header + feature / values" stacked layout
     ================================================================= */
  #cmp-wrap .cmp-heading { margin-bottom: 24px !important; }
  #cmp-wrap .cmp-inner { padding: 0 16px !important; }
  /* Remove the continuous Hopin column tint (doesn't align in stacked layout) */
  #cmp-wrap .cmp-row > .cmp-cell:nth-child(2),
  #cmp-wrap .cmp-header > .cmp-cell:nth-child(2) { background: transparent !important; }

  /* Logo row: sticky with the page's grain texture baked directly into
     its own background as a layered image — a translucent cream gradient
     over noise.avif.

     Why this (and not a ::after pseudo, an opaque bg + z-index bump, or
     the global noise overlay): on index.html the page-wide grain comes
     from a Framer-generated `.framer-m7bx2v` layer (opacity 0.13,
     z-index 5) inside the framer root. `position: sticky` on the
     header creates a stacking context that lifts it above that grain,
     so anything we put under the bar reads as brighter/cleaner than
     the surrounding page. Painting the noise locally INTO the bar's
     own background — at the same effective intensity as the framer
     grain (~87% cream + 13% noise) — sidesteps the stacking-context
     issue entirely and matches the surrounding page to within 1 RGB
     unit per channel.

     The gradient alpha (0.87) and the noise image are calibrated
     against pixel samples of the feature rows: page averages
     RGB(228, 227, 220); the bar now averages RGB(229, 228, 221). */
  #cmp-wrap .cmp-row.cmp-header {
    display: grid !important;
    grid-template-columns: 1fr 1fr 1fr !important;
    gap: 6px !important;
    padding: 14px 0 14px !important;
    border: none !important;
    border-bottom: 1px solid rgba(26, 26, 26, 0.04) !important;
    position: sticky;
    top: 0;
    z-index: 6;
    /* Flat cream here left the bar reading as a white band now that the
       page grain is on again — measured (233,233,229) against a page of
       (228,227,220). Painting the noise into the bar at the same 87/13
       cream-to-noise ratio as the page layer closes that gap, which is
       what the note above always intended. Tile matches the page grain's
       physical size (see the .framer-m7bx2v rules). */
    background:
      linear-gradient(rgba(255,254,246,.87), rgba(255,254,246,.87)),
      url('noise.avif') repeat !important;
    background-size: auto, 77px !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    margin: 0 !important;
  }
  #cmp-wrap .cmp-row.cmp-header .cmp-cell.cmp-spacer { display: none !important; }
  #cmp-wrap .cmp-row.cmp-header .cmp-cell {
    padding: 4px 6px !important;
    min-height: 44px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: transparent !important;
    border-radius: 0 !important;
  }
  #cmp-wrap .cmp-row.cmp-header .cmp-cell.cmp-col-self {
    background: rgba(26, 26, 26, 0.06) !important;
    border-radius: 14px !important;
    padding: 12px 8px !important;
    position: relative;
  }
  #cmp-wrap .cmp-row.cmp-header .cmp-brand-logo {
    max-height: 20px !important;
    max-width: 92px !important;
    width: auto !important;
    height: auto !important;
    filter: none !important;
    opacity: 1 !important;
    /* logo-unstop.jpg is a JPEG, so it carries an opaque white box. On
       desktop the page grain layer paints over the logos and hides it; the
       sticky bar sits above that layer, so on a phone the box was showing
       as a white patch on the grain. Multiply drops the white out and lets
       the bar's texture read through, matching the laptop. */
    mix-blend-mode: multiply;
  }
  #cmp-wrap .cmp-row.cmp-header .cmp-brand-logo.cmp-brand-hopin {
    max-height: 18px !important;
  }

  /* Group label row: full width, span all 4 columns */
  #cmp-wrap .cmp-row.cmp-group-row {
    grid-template-columns: 1fr !important;
    padding-top: 18px !important;
  }
  #cmp-wrap .cmp-row.cmp-group-row .cmp-cell { padding: 0 4px !important; min-height: 0 !important; }
  #cmp-wrap .cmp-row.cmp-group-row .cmp-cell:not(.cmp-group-label) { display: none !important; }

  /* Feature row: feature name on top, 3 values in a row below */
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) {
    grid-template-columns: 1fr 1fr 1fr !important;
    grid-template-areas: "feat feat feat" "val1 val2 val3" !important;
    gap: 6px !important;
    padding: 14px 4px !important;
    border-top: 1px solid rgba(26, 26, 26, 0.08) !important;
    align-items: stretch !important;
  }
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) .cmp-feature {
    grid-area: feat !important;
    padding: 0 4px 8px !important;
    min-height: 0 !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    color: #1a1a1a !important;
    justify-content: flex-start !important;
  }
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) .cmp-val {
    grid-area: auto !important;
    min-height: 50px !important;
    padding: 12px 6px !important;
    border-radius: 10px !important;
    background: rgba(26, 26, 26, 0.03) !important;
    font-size: 13px !important;
    justify-content: center !important;
    text-align: center !important;
    white-space: normal !important;
  }
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) .cmp-val:nth-child(2) { grid-area: val1 !important; background: rgba(111, 127, 173, 0.12) !important; color: #1a1a1a !important; font-weight: 500 !important; }
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) .cmp-val:nth-child(3) { grid-area: val2 !important; }
  #cmp-wrap .cmp-row:not(.cmp-header):not(.cmp-group-row) .cmp-val:nth-child(4) { grid-area: val3 !important; }

  /* Blog sidebar: already handled at 720px breakpoint */

  /* Blog post: cut excessive top padding */
  .article { padding-top: 100px !important; }

  /* Mobile-apply animation area — keep the full 288px height on
     mobile too. The earlier 220px crop caused the diagonal streaks
     to cluster into a dark visible band where the canvas met the
     content section below. */
  .mw-rain-logo { width: 160px !important; }
  /* Remove the hard 1px seam between animation + content; add a
     cream gradient fade at the bottom of the canvas so streaks
     dissolve into the content zone smoothly. */
  body .mw-content { border-top: none !important; }
  body .mw-animation { position: relative; }
  body .mw-animation::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 60px;
    background: linear-gradient(180deg, rgba(255,254,246,0) 0%, rgba(255,254,246,0.85) 100%);
    pointer-events: none;
    z-index: 3;
  }

  /* Hero buttons stacking */
  .framer-r77l27 [data-framer-name="Content"] div[style*="display:flex;gap:16px"] {
    flex-direction: column !important;
    gap: 10px !important;
    width: 100%;
  }

  /* FAQ heading scale */
  #faq-wrap .faq-inner { padding: 0 20px !important; }

  /* FAQ aside ("Can't find what you're looking for? / Contact us")
     should sit BELOW the questions list on mobile. Grid is single-col
     at <=960px via the inline styles, so we just reorder with `order`. */
  #faq-wrap .faq-grid {
    display: flex !important;
    flex-direction: column !important;
    gap: 32px !important;
  }
  #faq-wrap .faq-main { order: 1 !important; }
  #faq-wrap .faq-side { order: 2 !important; }
  #faq-wrap .faq-side-label { font-size: 15px !important; }

  /* Calculator "reveal" bars — wider + smaller text so time values like
     "2h 25m hrs" never overflow the narrow With Hopin column. */
  #tc-wrap .tc-bars {
    gap: 28px !important;
  }
  #tc-wrap .tc-bar-col {
    width: 112px !important;
    min-width: 112px !important;
    height: 160px !important;
  }
  #tc-wrap .tc-bar-value {
    font-size: 14px !important;
    line-height: 1.2 !important;
    padding: 0 8px !important;
    text-align: center !important;
  }

  /* iOS safe-area bottom */
  #mobile-nav .mn-content { padding-bottom: calc(36px + env(safe-area-inset-bottom, 0px)); }
  #final-cta-wrap .fc-content { padding-bottom: calc(100px + env(safe-area-inset-bottom, 0px)) !important; }

  /* =================================================================
     Integrations marquee — smaller logo cards on mobile
     ================================================================= */
  #integrations-wrap { overflow-x: hidden !important; }
  /* 132px cards + a 12px gutter is a 144px pitch, so only 2.7 logos are
     ever on screen at once. 92 + 10 = a 102px pitch, which shows 3.8. */
  #integrations-wrap .ig-item {
    width: 92px !important;
    height: 50px !important;
    border-radius: 10px !important;
    margin-right: 10px !important;
  }
  #integrations-wrap .ig-item img {
    max-width: 78% !important;
    max-height: 66% !important;
  }
  #integrations-wrap .ig-inner { padding: 0 16px !important; }

  /* =================================================================
     Final CTA — tighter padding, full-width button on small phones
     ================================================================= */
  #final-cta-wrap {
    min-height: 100vh !important;
  }
  #final-cta-wrap .fc-content {
    padding-top: 90px !important;
    padding-left: 20px !important;
    padding-right: 20px !important;
    padding-bottom: 48px !important;
    min-height: 100vh !important;
  }
  #final-cta-wrap .fc-btn { padding: 14px 24px !important; width: auto; }

  /* =================================================================
     Perfectly-results ("Apply less. Land more.") — Framer exported
     only the Desktop variant HTML. On mobile, its flex-row layout
     crunches the heading column to ~97px and the h2 wraps one letter
     per line. Force the entire Framer tree to stack vertically and
     take full width.
     ================================================================= */
  #perfectly-results-wrap { padding: 40px 16px !important; }
  #perfectly-results-wrap section[class*="framer-"],
  #perfectly-results-wrap .framer-iebpqi,
  #perfectly-results-wrap .framer-12ghyet {
    flex-direction: column !important;
    align-items: stretch !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    gap: 24px !important;
  }
  #perfectly-results-wrap .framer-1sejwfw,
  #perfectly-results-wrap .framer-4b8sot,
  #perfectly-results-wrap .framer-aetetz,
  #perfectly-results-wrap .framer-1y8vbyu,
  #perfectly-results-wrap .framer-xm1cb0 {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    flex: 0 0 auto !important;
  }
  /* "Our Results" pill — Framer gives the inner pill a fixed width that's
     narrower than the "Our Results" text at mobile font-size, so the text
     overflows both pill edges. Let the pill hug its content. */
  #perfectly-results-wrap .framer-1qs8pbp-container {
    width: max-content !important;
    max-width: 100% !important;
    flex: 0 0 auto !important;
    min-width: 0 !important;
  }
  #perfectly-results-wrap .framer-1qs8pbp-container > * {
    width: max-content !important;
    max-width: 100% !important;
    flex: 0 0 auto !important;
  }
  #perfectly-results-wrap .framer-1qs8pbp-container p {
    white-space: nowrap !important;
    padding: 0 !important;
    width: auto !important;
  }
  #perfectly-results-wrap .framer-aetetz h2,
  #perfectly-results-wrap .framer-aetetz h2 span,
  #perfectly-results-wrap .framer-aetetz h2 span.framer-text {
    font-size: clamp(28px, 8vw, 42px) !important;
    line-height: 1.06 !important;
    letter-spacing: -0.025em !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
    white-space: normal !important;
  }
  #perfectly-results-wrap .framer-1y8vbyu p {
    font-size: 15px !important;
    line-height: 1.5 !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
    hyphens: auto !important;
  }
  /* Force every descendant in the Framer tree to wrap — nothing should
     overflow the viewport (was clipping "Too many co..." on the right) */
  #perfectly-results-wrap p,
  #perfectly-results-wrap h1,
  #perfectly-results-wrap h2,
  #perfectly-results-wrap h3 {
    max-width: 100% !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
    white-space: normal !important;
  }
  /* Stats: "3x interviews" + "Under 10 min" — side by side like desktop */
  #perfectly-results-wrap .framer-xm1cb0 {
    flex-direction: row !important;
    gap: 10px !important;
    padding: 16px 10px !important;
    border-radius: 22px !important;
  }
  #perfectly-results-wrap .framer-d9rgpg-container,
  #perfectly-results-wrap .framer-q7q29i-container {
    max-width: 50% !important;
    flex: 1 1 0 !important;
    width: 50% !important;
    height: auto !important;
    min-height: 0 !important;
  }
  /* Framer gives the Bottom wrap a fixed 860-ish px height from its
     "Stats" variant. Override so it just hugs the 2 cards + padding. */
  #perfectly-results-wrap .framer-4b8sot,
  #perfectly-results-wrap .framer-xm1cb0 {
    height: auto !important;
    min-height: 0 !important;
  }
  /* City photo is position:absolute filling the stats wrap. Set it to a
     smaller, fixed height so the wrap (and the cards above it) collapse. */
  #perfectly-results-wrap .framer-1hjuds6 {
    height: 100% !important;
    min-height: 0 !important;
  }
  /* Stats card — translucent glass matching desktop */
  #perfectly-results-wrap .framer-mPG8o {
    padding: 20px 14px !important;
    border-radius: 22px !important;
    background-color: rgba(255, 255, 255, 0.35) !important;
    backdrop-filter: blur(24px) saturate(1.4) !important;
    -webkit-backdrop-filter: blur(24px) saturate(1.4) !important;
    border: 1px solid rgba(255, 255, 255, 0.25) !important;
  }
  #perfectly-results-wrap .framer-mPG8o h1 {
    font-size: clamp(20px, 5.5vw, 30px) !important;
    color: rgba(255, 255, 255, 0.95) !important;
    text-shadow: 0 1px 8px rgba(0,0,0,0.15) !important;
    --framer-text-color: rgba(255, 255, 255, 0.95) !important;
    --extracted-gdpscs: rgba(255, 255, 255, 0.95) !important;
  }
  #perfectly-results-wrap .framer-mPG8o p {
    font-size: 10px !important;
    margin-top: 6px !important;
    color: rgba(255, 255, 255, 0.85) !important;
    --framer-text-color: rgba(255, 255, 255, 0.85) !important;
    --extracted-r6o4lv: rgba(255, 255, 255, 0.85) !important;
  }
  #perfectly-results-wrap .framer-1hjuds6 img {
    object-position: center !important;
  }

  /* =================================================================
     Scroll-text-reveal phrases — tighter line-height on mobile
     ================================================================= */
  #scroll-text-container {
    font-size: clamp(22px, 6.5vw, 36px) !important;
    line-height: 1.2 !important;
  }

  /* =================================================================
     Hero (Framer) — buttons stack, headline wraps naturally
     ================================================================= */
  .framer-r77l27 div[style*="display:flex;gap:16px"] {
    flex-direction: column !important;
    width: 100% !important;
    gap: 10px !important;
  }
  .framer-r77l27 div[style*="display:flex;gap:16px"] > a {
    width: 100% !important;
    justify-content: center !important;
  }
  /* Kill the desktop 32px right-shift on headline/subtext (looks weird wrapping on mobile) */
  h1.framer-text > span:nth-child(2),
  [data-framer-name="Supporting text"] + div p,
  [data-framer-name="Supporting text"] p,
  div[style*="display:flex;gap:16px"] {
    padding-left: 0 !important;
  }
  /* Framer sets white-space:nowrap on hero h1 spans which clips on
     phones. Force natural wrapping so words break cleanly at viewport
     edges. (The compositor-layer blur problem that previously also
     required `transform:none; left:auto` here is now fixed at the
     source — see the hero JS + .framer-1yyzufc override in index.html.)

     EVERY selector in this block is scoped to `h1.framer-text`, and that
     matters. It used to be a bare `h1`, which meant a fix written for one
     headline on the homepage applied to every H1 on the site at 720px and
     below: blog posts, /blog, /calculator, /hiring-index, /browse, /roles,
     /cold-emails. All of them got `text-align:center` and an extra 16px of
     left padding they were never designed with, so on a phone the headline
     sat centred and indented while the byline, the date and every paragraph
     under it stayed flush left. It read as a layout accident because it was
     one. Only index.html emits `h1.framer-text`, so the scope is exact. */
  h1.framer-text {
    white-space: normal !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 16px !important;
    box-sizing: border-box !important;
    text-align: center !important;
  }
  h1.framer-text > span,
  h1.framer-text > span > span {
    white-space: normal !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
  }
  h1.framer-text > span {
    display: block !important;
  }
  #hero-copy-stack {
    width: 100% !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
  }
  #hero-copy-stack,
  #hero-top-line,
  #hero-bottom-line,
  #hero-rotating-person,
  #hero-line {
    white-space: normal !important;
    flex-wrap: wrap !important;
    word-break: normal !important;
    overflow-wrap: break-word !important;
  }
  #hero-top-line,
  #hero-bottom-line {
    font-size: clamp(18px, 5.8vw, 28px) !important;
    justify-content: center !important;
    text-align: center !important;
    width: 100% !important;
  }
  #hero-rotating-person {
    font-size: inherit !important;
  }
  .framer-1hpalyd span,
  .framer-1hpalyd p span {
    white-space: normal !important;
  }

  /* =================================================================
     Hopin intro splash letters — scale down on narrow screens
     ================================================================= */
  #hopin-intro-word {
    height: clamp(44px, 10vh, 80px) !important;
  }

  /* =================================================================
     Section headings — all tuned for mobile-native scale
     ================================================================= */
  #cmp-wrap .cmp-heading {
    font-size: clamp(30px, 9vw, 44px) !important;
    line-height: 1.05 !important;
    margin-bottom: 32px !important;
  }
  #faq-wrap .faq-h {
    font-size: clamp(36px, 10vw, 52px) !important;
    line-height: 1.04 !important;
  }
  #tc-wrap .tc-heading {
    font-size: clamp(30px, 9vw, 46px) !important;
    line-height: 1.06 !important;
  }
  #integrations-wrap .ig-heading {
    font-size: clamp(26px, 8vw, 38px) !important;
    line-height: 1.08 !important;
    padding: 0 16px !important;
  }
  #integrations-wrap .ig-sub {
    font-size: 14px !important;
    padding: 0 24px !important;
    margin-top: 12px !important;
  }
  #final-cta-wrap .fc-heading {
    font-size: clamp(36px, 11vw, 56px) !important;
    line-height: 1.02 !important;
  }
  #final-cta-wrap .fc-sub {
    font-size: 15px !important;
    margin: 14px 0 28px !important;
  }

  /* =================================================================
     Noise overlay — a touch lighter on mobile (smaller screen, less
     space to absorb grain)
     ================================================================= */
  .hopin-noise { opacity: 0.08 !important; }

  /* =================================================================
     BLOG PAGE — sidebar → horizontal chip bar
     ================================================================= */
  /* minmax(0,1fr) rather than 1fr, and min-width:0 down the chain, because
     `1fr` is `minmax(auto,1fr)` and that `auto` floor is the item's MIN-CONTENT
     width. The category chips below are a nowrap horizontal scroll strip, and
     `overflow-x:auto` does not by itself let a box shrink under its content -
     its min-width is still `auto`. So the chips' combined width propagated all
     the way up: .cat-list refused to go below ~476px, .sidebar inherited that
     floor, the grid track blew out to 476px inside a 358px content box, and
     Chrome then widened the layout viewport to 492px to fit it.
     Measured at 390px before this fix: 102px of horizontal overflow, every card
     heading and paragraph clipped mid-word. */
  body .page {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 24px !important;
    padding: 32px 16px 60px !important;
  }
  body .page .sidebar,
  body .page .posts {
    min-width: 0;
  }
  body .page .sidebar {
    position: static !important;
    display: flex;
    flex-direction: column;
    gap: 14px;
  }
  body .page .sidebar h1 {
    font-size: 26px !important;
    margin: 0 !important;
  }
  body .page .sidebar .search { margin-bottom: 0 !important; }
  /* iOS Safari zooms the whole page in when a text field under 16px takes
     focus, and it does not zoom back out when the field is blurred. The search
     box was 14px, so tapping it left the reader on a magnified page they had to
     pinch their way out of. 16px is the threshold, not a preference. */
  body .page .sidebar .search input { font-size: 16px !important; }
  body .page .sidebar .cat-list {
    flex-direction: row !important;
    gap: 8px !important;
    overflow-x: auto;
    /* The strip is 493px of chips in a 358px box with the scrollbar hidden, so
       "Founder Notes" sits entirely off-screen with nothing on the page saying
       so. The mask fades the last 26px, which is the standard way of saying
       there is more to the right when you cannot show a scrollbar. */
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent);
    /* The pair that actually makes the strip scroll instead of stretch. Without
       min-width:0 the flex item keeps a min-content floor the width of all the
       chips laid end to end, and the scrollbar never engages because there is
       nothing to scroll - the container simply grew. */
    min-width: 0;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  body .page .sidebar .cat-list::-webkit-scrollbar { display: none; }
  body .page .sidebar .cat-link {
    flex: none !important;
    padding: 8px 14px !important;
    border: 1px solid rgba(26, 26, 26, 0.1) !important;
    border-radius: 999px !important;
    font-size: 13px !important;
    white-space: nowrap;
  }
  body .page .sidebar .cat-link.active {
    background: rgba(111, 127, 173, 0.12) !important;
    border-color: rgba(111, 127, 173, 0.35) !important;
  }

  /* Blog hero image: shrink to leave more room above the fold */
  body .blog-hero {
    height: 22vh !important;
    min-height: 160px;
  }
  /* Mirrors the two numbers directly above. The logo is not inside the hero
     - it's an <img>, nothing can be - so anything that wants to sit at the
     photo's foot has to recompute its height. Change one, change both. */
  body.blog-index {
    --hero-h: max(22vh, 160px);
  }

  /* The wordmark is #6F7FAD sitting on a mid-tone photograph for the whole
     first screen of /blog, which measures around 1.9:1 - under the 3:1 a mark
     this size needs to stay legible. brightness(0) flattens every pixel to
     black and invert(1) lifts it to white while keeping the original alpha,
     so the rabbit stays a cut-out instead of filling in. If a purpose-made
     white PNG ever exists, point the src at it and delete this rule.

     `#mn-bar .mn-logo-pill img` rather than `.hpn-logo`: below 720px
     mobile.js hides the desktop bar and builds its own, so the logo a phone
     actually renders is this one - and it sets `filter:none` a few hundred
     lines up, which is what this has to override.

     No `:not(.nav-glass)` guard here, unlike the desktop rule in blog.html.
     #mn-bar is position:absolute, so it scrolls away with the page instead of
     following it down. It is only ever over the photo. */
  body.blog-index #mn-bar .mn-logo-pill img {
    filter: brightness(0) invert(1) !important;
  }

  /* The wordmark drops to the foot of the hero; the hamburger keeps the top
     right. The top-left corner is the brightest part of this photograph: a
     white mark measures 1.4:1 against the sky there and 1.1:1 over the
     brightest cloud, so it half-dissolves. The bottom-left is foliage and
     shadowed stone.

     A transform rather than flex alignment on #mn-bar: the same bar carries
     the open menu, where the photo is hidden behind the cream backdrop and
     the mark belongs back beside the X. transform animates between the two;
     align-items would snap.

     The pill sits 22px down and is 40px tall with a 24px image centred in
     it, so the image's own bottom starts at 54px. Landing it 24px above the
     hero's edge, matching #mn-bar's 24px left inset, is (H - 24) - 54. */
  body.blog-index #mn-bar .mn-logo-pill {
    transform: translateY(calc(var(--hero-h) - 78px));
    transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.25, 1);
  }
  body.blog-index #mn-bar.is-open .mn-logo-pill {
    transform: none;
  }
  /* Back beside the X the ground is cream, not photograph. White on cream is
     the same vanishing act with the values swapped. */
  body.blog-index #mn-bar.is-open .mn-logo-pill img {
    filter: none !important;
  }

  /* Post card font sizes */
  body .post-card h2 { font-size: 20px !important; }
  body .post-card p { font-size: 14px !important; }
  body .post-card { padding: 22px 0 !important; }

  /* =================================================================
     Blog post article — trim top padding under the fixed mobile bar
     ================================================================= */
  body .article { padding: 100px 18px 70px !important; }
  body .article h1 { font-size: clamp(28px, 7.5vw, 36px) !important; }
  body .article p { font-size: 16px !important; }
  body .article h2 { font-size: 22px !important; margin-top: 30px !important; }
  /* The blanket h2 rule above outranks the smaller sizes the design gives the
     two utility blocks, so "Read next" and "How we counted" came out shouting
     at exactly the same volume as a section of the argument. They are
     signposts, not sections. */
  body .article .readnext h2,
  body .article .method h2 { font-size: 18px !important; }

  /* Read next is a stack of cards now, and the description inside one is a <p>
     inside .article - so the blanket 16px rule above wins on !important alone
     and the card's own 14.5px never lands. The title needs the same treatment
     for the same reason. Only these two, and only because the rule they are
     fighting is !important. */
  body .article .readnext .rn-desc { font-size: 14.5px !important; }
  body .article .readnext .rn-title { font-size: 16px !important; }
  body .article .readnext .rn-item { padding: 14px 32px 14px 14px !important; }

  /* Paragraphs were stepped down to 16px here and lists were not, so a bullet
     rendered a point larger than the sentence above it. Nobody reads that as a
     hierarchy; it reads as a mistake, which is what it was. */
  body .article ul,
  body .article ol,
  body .article li { font-size: 16px !important; }

  /* Tap targets. "Back to blog" was 19px tall and the category link 18px,
     against a 24px floor in WCAG 2.5.8 and 44px in Apple's guidance. Both are
     standalone controls rather than links inside a sentence, so neither gets
     the inline exemption. The padding is vertical only, so nothing moves
     sideways; the margins come down to pay for the height. */
  body .article .back { padding: 12px 0 !important; margin-bottom: 14px !important; }
  body .article .meta { margin-bottom: 10px !important; }
  body .article .meta .cat { display: inline-block; padding: 6px 0; }

  /* -----------------------------------------------------------------
     Tables. The article sets `table{min-width:440px}` and wraps it in an
     `overflow-x:auto` div, which is the standard answer for a wide table and
     the wrong one here. At 390px the article is 354px wide, so 86px of the
     table hung off the right edge - and the column that hung off was the
     numbers. On the recruiters post a reader on a phone got four channel
     names and not one percentage, which is the entire finding. The caption is
     part of the table box, so "20,392 internship postings" was cut to
     "20,3" as well, and nothing on screen said any of it could scroll.

     These tables are two and three narrow columns. They fit if we let them:
     min-width goes, the type steps down, the padding tightens, and the
     horizontal scroll stays as a fallback for anything genuinely too wide.
     ----------------------------------------------------------------- */
  body .article table { min-width: 0 !important; font-size: 14px !important; }
  body .article th,
  body .article td { padding: 10px 8px !important; line-height: 1.45 !important; }
  body .article th { font-size: 13px !important; background: rgba(111, 127, 173, 0.13) !important; }
  body .article caption { font-size: 13px !important; line-height: 1.45 !important; }

  /* Second half of the table problem, and the one that survives the width fix:
     with no outer border and hairline row rules on a cream, noise-textured
     background, a table on a phone reads as a loose list of sentences rather
     than as a grid. Give it an edge, a corner radius and a faint wash so it
     sits on the page as one object, and darken the header so the top row
     announces itself as a header. The caption is a child of <table>, so it
     comes inside the box and becomes the card's title; it gets its own padding
     so it does not hug the border. */
  body .article .tbl-wrap {
    margin-bottom: 24px !important;
    border: 1px solid rgba(26, 26, 26, 0.12) !important;
    border-radius: 12px !important;
    background: rgba(255, 255, 255, 0.5) !important;
  }
  body .article .tbl-wrap caption {
    caption-side: top;
    padding: 10px 12px 8px !important;
  }
  body .article .tbl-wrap th:first-child,
  body .article .tbl-wrap td:first-child { padding-left: 12px !important; }
  body .article .tbl-wrap th:last-child,
  body .article .tbl-wrap td:last-child { padding-right: 12px !important; }

  /* The email templates: long unbroken URLs and placeholders would otherwise
     be the one thing on a guide able to push the viewport open. */
  body .article .tpl { padding: 18px 16px !important; }
  body .article .tpl p { font-size: 14.5px !important; overflow-wrap: break-word; }

  /* =================================================================
     MOBILE-APPLY — give card some breathing room; form vertical already
     ================================================================= */
  body .mw-page { padding: 100px 14px 20px !important; }
  body .mw-card { border-radius: 16px !important; }
  body .mw-content { padding: 30px 22px !important; }
  body .mw-title { font-size: 28px !important; }
}

/* ===================================================================
   HERO — centre the copy block (match the desktop composition)
   ===================================================================
   #hero is a flex column pinned to `justify-content:flex-start` with
   `padding:160px 16px 96px`, so on a 390x844 screen the copy ends at
   409px and the bottom 435px is dead photo. Centring the stack puts
   the block on the optical centre and lets the bridge deck read as
   the floor of the composition, the way it does on desktop.
   =================================================================== */
@media (max-width: 767px) {
  #hero {
    justify-content: center !important;
    padding-top: 96px !important;
    padding-bottom: 96px !important;
  }
  /* Desktop fills the hero with the photo and centres the copy on it.
     The phone must read the same way. The phone art is 2:3 and the hero
     box is 0.46, so `cover` would keep only the middle 69% of the width,
     cutting the clock tower off one side and the city off the other.

     So the phone gets a phone-shaped version of the same photograph:
     hero-m-tall.webp, 1024x2216. Nothing is cropped from the original —
     its own sky is extended upward, column by column, so the join cannot
     be seen. 1024/2216 = 0.462, which is the aspect of every modern phone
     hero (390x844, 430x932, 360x780 are all 0.461-0.462), so plain `cover`
     fills the hero edge to edge and discards essentially nothing.

     The hero then behaves exactly like desktop: one photograph filling the
     viewport with the copy centred on it. */
  #hero [data-framer-name="BG"] img,
  #hero .framer-1bgsizk img {
    object-fit: cover !important;
    object-position: center bottom !important;
  }

  /* --- The grade and the fade, restored ------------------------------
     Desktop grades the hero photo and lays Framer's white fade over it;
     together they are what make it read warm and high-key. On phones both
     were switched off: the text-clarity block at index.html:547 blanket
     kills `filter` on every styled descendant of #hero, which takes the
     grade with it, and the fade is cleared below 809px. So the phone hero
     was rendering flat and grey while the laptop glowed.

     Same values as desktop, no new ones. The grade goes on the <img>
     itself, never an ancestor — a filter on an ancestor would create a
     containing block and put a compositor layer over the hero text, which
     is the exact problem that blanket rule exists to prevent. */
  #hero [data-framer-name="BG"] img,
  #hero .framer-1bgsizk img {
    filter: saturate(1.28) contrast(1.10) brightness(1.03) sepia(.07) !important;
    -webkit-filter: saturate(1.28) contrast(1.10) brightness(1.03) sepia(.07) !important;
  }
  #hero .framer-1oov14a {
    background: linear-gradient(
      rgba(255,255,255,.38) 39.6396%,
      rgba(255,255,255,.53) 112%
    ) !important;
  }
  /* The fade lives in the same wrapper as the photo and carries z-index:2,
     the same as the copy. On desktop that wrapper is its own stacking
     context (Framer sets an inline transform on it), so photo + fade
     composite together underneath the text. On mobile those inline
     transforms are stripped for text clarity, the context disappears, and
     the fade — later in the DOM at equal z-index — paints over the
     headline and the button, greying both out. Re-establishing the
     context puts the fade back under the copy without reintroducing a
     transform. */
  #hero .framer-1a0h3hm { isolation: isolate !important; }
}

/* ===================================================================
   HOW IT WORKS (#hiw-wrap) — mobile
   ===================================================================
   The blanket `animation: none` at the top of this file kills every
   keyframe below 767px. How-it-works was built after that rule and
   uses those keyframes to REVEAL its content: .rise, .pile .jc and
   .count all start at opacity:0 and are only made visible by their
   animation. With the animation gone they never appear, so on a phone
   the WhatsApp panel renders as bare wallpaper (no green header, no
   bubbles) and Hidden jobs renders as an empty photo.

   Fix: show the end state outright instead of animating to it. The
   pile's fanned layout is also 490px wide (cards are 288px and fan
   +/-100px), so on a 390px screen it is replaced by a plain vertical
   stack that fits the column.
   =================================================================== */
@media (max-width: 767px) {
  /* Everything the reveal keyframes were responsible for showing.
     Audited against every `opacity:0` in the section's stylesheet:
       .rise, .pile .jc, .count, .ivc  -> content, must be shown
       .glow                           -> settles at .35, shown at rest
       .aa-wash, .aa-stamp, .confetti i-> transient states inside a loop,
                                          correctly stay hidden
       .card-bg .bgimg                 -> toggled by .on, not by animation */
     No !important on any of these: an !important declaration outranks a
     CSS animation, so it would freeze the very motion re-enabled below.
     These rules sit later in the cascade at equal specificity, so they
     beat the opacity:0 base on their own and act purely as the resting
     state the animation settles into. */
  #hiw-wrap .rise,
  #hiw-wrap .ivc,
  #hiw-wrap .pile .count { opacity: 1; }
  #hiw-wrap .glow { opacity: .35; }

  /* --- Tabs: 2x2 grid ------------------------------------------------
     Four labels cannot share one 390px line at full size, and letting
     them wrap orphaned the active underline on the row above. Two
     deliberate rows keep every label at its real name and full size. */
  #hiw-wrap .tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 8px;
    margin-top: 26px;
  }
  #hiw-wrap .tab {
    text-align: left;
    font-size: 16.5px;
    padding: 11px 0 12px;
  }
  /* Underline stops short of the gutter so the two columns stay read
     as separate cells. */
  #hiw-wrap .tab.on::after,
  #hiw-wrap .tab .pg { right: 8px; }

  /* --- The job-card fan ----------------------------------------------
     This is the desktop composition, not a new one: seven cards thrown
     from the centre with the --tx/--ty/--rot each card carries inline,
     which is exactly where the deal animation leaves them. Reproducing
     that end state is all the phone needs.

     The fan spans ~504px (288px cards thrown +/-100px, plus rotation)
     and the phone card is 346px, so the whole pile is scaled down to fit
     rather than rearranged. Scaling keeps the arrangement identical to
     the laptop and crops nothing. */
  #hiw-wrap .pile .jc {
    opacity: 1;
    transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty)))
               rotate(var(--rot));
  }
  /* Measured: at .65 the fan spans 323px inside the 346px card — 11px
     clear on each side, nothing clipped — and fills 93% of the stage,
     against 91% on desktop. The same picture, just smaller. */
  #hiw-wrap .pile {
    transform: scale(var(--pile-k, .65));
    transform-origin: center center;
  }

  /* --- One height for every tab ---------------------------------------
     Desktop pins `.card{height:580px}`, so all four tabs are the same size
     and switching between them never moves the page. On mobile the card
     was `height:auto`, which is why Hidden jobs, Auto-apply, WhatsApp and
     Exclusive interviews were all different heights. Same idea as desktop:
     one fixed height, the stage takes whatever the copy does not, and each
     mock centres inside it.

     Desktop is two columns: the photo panel holding the animation on the
     left, the copy on the right. On a phone that becomes two stacked
     blocks — photo-with-animation on top, copy in its own box below —
     and the split has to be clean, with no fade bleeding one into the
     other.

     The animation block is 635px on every tab: the tallest mock is the
     WhatsApp chat at 545px, plus the stage's 40/50 padding. Fixing it
     means switching tabs never resizes the picture. The copy box then
     takes the rest of the fixed card height. */
  #hiw-wrap .card {
    display: flex !important;
    flex-direction: column !important;
    height: var(--card-h, 1066px) !important;
  }
  /* The stage's own padding is 40 top / 50 bottom, which left every mock
     sitting 10px closer to the top than the bottom. Evened up so the
     animation is optically centred in its block. 45/45 keeps the same
     545px of inner room, which is exactly the WhatsApp chat's height. */
  #hiw-wrap .stage {
    flex: 0 0 var(--stage-h, 635px) !important;
    min-height: 0 !important;
    padding: 45px 22px !important;
  }
  #hiw-wrap .copy  { flex: 1 1 auto !important; }

  #hiw-wrap .stagewrap { width: 100% !important; }

  /* --- The backdrop photo --------------------------------------------
     Desktop's card is 1008x522, a 1.93 landscape box, and the photos are
     1600x900 to match. The phone's card is 346 wide by 800-1250 tall —
     roughly 1:3 — so `cover` scales those same photos to the height and
     throws away ~72% of the width. What is left is a meaningless vertical
     sliver, which is why the photo reads as noise on a phone.

     Instead of demanding an impossible 1:3 source, the photo runs full
     width at its own aspect ratio, anchored to the top, and dissolves
     into the card's cream below. Nothing is cropped, so any ordinary
     portrait export works, and the composition stays intact.
     Desktop is untouched — every rule here is inside the 767px gate. */
  /* The card carries a second photo of its own (.bg-bridge / .bg-sky),
     which would show through below the band. On phones the .bgimg layer
     is the only photo. */
  #hiw-wrap .card {
    background-image: none !important;
    background-color: #FFFEF6 !important;
  }
  /* The photo covers the animation block edge to edge and stops there —
     it is the backdrop for the animation, not for the copy. Desktop does
     exactly this: its 1600x900 photo fills a 534x522 panel, cropping the
     sides. Here it fills 346x635, cropping top and bottom, so the full
     width of the scene survives. */
  #hiw-wrap .card-bg,
  #hiw-wrap .card::before {
    height: var(--stage-h, 635px) !important;
    bottom: auto !important;
  }
  #hiw-wrap .card-bg .bgimg {
    background-size: cover !important;
    background-position: center !important;
    background-repeat: no-repeat !important;
  }
  /* Phone art. Portrait crops of the same four scenes the desktop uses,
     so the two views read as the same place. 1156x1360 each. */
  #hiw-wrap .card-bg .bgimg[data-b="0"] { background-image: url('hiw-bg/m-hidden.webp') !important; }
  #hiw-wrap .card-bg .bgimg[data-b="1"] { background-image: url('hiw-bg/m-autoapply.webp') !important; }
  #hiw-wrap .card-bg .bgimg[data-b="2"] { background-image: url('hiw-bg/m-whatsapp.webp') !important; }
  #hiw-wrap .card-bg .bgimg[data-b="3"] { background-image: url('hiw-bg/m-exclusive.webp') !important; }

  /* No dissolve. The photo block and the copy box are two clean blocks,
     the way the two columns are on desktop. */
  #hiw-wrap .card-bg .bgimg::after { display: none !important; }

  /* --- Motion, re-enabled for this section only -----------------------
     The rule at the top of this file kills every animation and transition
     under 767px. It predates How-it-works, which is why the section sat
     completely still on a phone while the laptop animated.

     Re-enabled here for #hiw-wrap alone, so the blanket still covers the
     rest of the page. Every value is the section's own, copied from its
     stylesheet — no new timings.

     The blanket also forces `animation-delay:0s !important`, which beats
     the inline delays on the markup, so each stagger is restored
     explicitly below. Without them all seven cards would deal at once. */
  #hiw-wrap * { transition: revert; }

  #hiw-wrap .gv[data-v="0"].on .pile .jc {
    animation: hiw-deal .6s cubic-bezier(.2,.8,.25,1) both !important;
  }
  /* Per-element delays are restored by restoreHiwDelays() in mobile.js —
     it re-applies each element's own inline delay with priority, which is
     the only thing that outranks the blanket rule. That keeps the exact
     authored staggers, including the confetti's randomised offsets. */
  #hiw-wrap .gv[data-v="0"].on .pile .count {
    animation: hiw-cRise .5s ease 1.05s both !important;
  }

  #hiw-wrap .gv:not([data-v="0"]).on .rise {
    animation: hiw-rise .5s cubic-bezier(.2,.7,.2,1) both !important;
  }

  /* Auto-apply: the swipe-and-send loop. */
  #hiw-wrap .aa-card.run { animation: hiw-aaLoop 2.7s cubic-bezier(.4,0,.2,1) infinite !important; }
  #hiw-wrap .aa-card.run .aa-wash { animation: hiw-aaWash 2.7s cubic-bezier(.4,0,.2,1) infinite !important; }
  #hiw-wrap .aa-card.run .aa-stamp { animation: hiw-aaStamp 2.7s cubic-bezier(.4,0,.2,1) infinite !important; }

  /* Exclusive interviews: card pops in, glow blooms behind it. */
  #hiw-wrap .gv[data-v="3"].on .ivc { animation: hiw-pop .6s cubic-bezier(.2,.85,.25,1) .15s both !important; }
  #hiw-wrap .gv[data-v="3"].on .glow { animation: hiw-glow 2.6s ease-out both !important; }

  /* WhatsApp: the tap on "Apply for me" that flashes the button green. */
  #hiw-wrap .gv[data-v="2"].on .wa-qr button.tap-target {
    animation: hiw-tapWA .46s ease 2.6s both !important;
  }

  /* Exclusive interviews: the confetti burst. The 26 pieces are built in
     JS with a random 0-0.7s delay set inline, and the blanket rule
     flattened to 0s by the blanket rule; mobile.js puts them back. */
  #hiw-wrap .gv[data-v="3"].on .confetti i {
    animation: hiw-fall 2.4s cubic-bezier(.25,.6,.35,1) forwards !important;
  }

  /* Live dots and the tab's progress bar. */
  #hiw-wrap .pile .count .d,
  #hiw-wrap .aa-count .dot { animation: hiw-pulse 1.4s infinite !important; }
  #hiw-wrap .tab.on.auto .pg { animation: hiw-prog var(--dwell, 5s) linear forwards !important; }

  /* The card's drop shadow is tuned for a 1008px panel; at 346px the same
     0 40px 80px -40px bloom reads as a heavy smudge under the card. */
  #hiw-wrap .card {
    box-shadow: 0 18px 44px -26px rgba(40,40,40,.30) !important;
  }
}

/* ===================================================================
   WHAT PEOPLE ARE SAYING (#results-r7) — the quote cards
   ===================================================================
   These are notifications: each quote drops in from -38px, blurred and
   transparent, then springs into place while the one before it settles
   back. The whole effect is built from transitions, and the blanket rule
   at the top of this file kills `transition` under 767px — so on a phone
   the quotes were cutting from one to the next with no motion at all.

   Re-enabled with the section's own timings, copied from its stylesheet.
   =================================================================== */
@media (max-width: 767px) {
  #results-r7 .r7-stack .r7-nc {
    transition: transform .62s cubic-bezier(.22,1,.36,1),
                opacity .5s ease,
                filter .5s ease !important;
  }
  #results-r7 .r7-stack .r7-nc.r7-landed {
    transition: transform .78s cubic-bezier(.16,1.28,.32,1),
                opacity .34s ease,
                filter .34s ease !important;
  }
}

/* ===================================================================
   Extra-small phones (<= 380px): tighter spacing
   =================================================================== */
/* At 349px and below a tab cell is ~134px, which "Exclusive interviews"
   overruns at 16.5px and wraps to two lines, making the two rows uneven.
   14px keeps every label on one line down to 320px. */
@media (max-width: 349px) {
  #hiw-wrap .tab { font-size: 14px !important; }
}

@media (max-width: 380px) {
  #mobile-nav .mn-links a { font-size: 22px; padding: 16px 0; }
  #mobile-nav .mn-content { padding: 92px 22px 32px; }
  #mn-bar { left: 12px; right: 12px; height: 50px; }
  #mn-bar .mn-logo-pill,
  #mn-bar .mn-trigger { height: 50px; border-radius: 12px; }
  #mn-bar .mn-trigger { width: 50px; }

  /* Same landing as the wider phones, re-derived: the bar hugs 12px from the
     left here, and the pill grows to 50px, so the 24px image's bottom starts
     at 59px and wants to finish 12px above the hero: (H - 12) - 59. */
  body.blog-index #mn-bar .mn-logo-pill {
    transform: translateY(calc(var(--hero-h) - 71px));
  }
  body.blog-index #mn-bar.is-open .mn-logo-pill {
    transform: none;
  }
}
