/* ─────────────────────────────────────────────────────────────────────────────
   mobile.css — phone and small-tablet layer for the whole site.

   Every page carries its own ~600-line <style> block, and most of the layout
   below the section level is written as inline style={{…}} in the JSX. That
   means two things for anything responsive:

     1. A rule here has to be loaded *after* the page's inline <style> to win on
        equal specificity, so the <link> goes last in <head>.
     2. Overriding an inline style needs !important. That is not laziness — an
        element's style attribute beats any stylesheet selector, so it is the
        only lever available short of rewriting every component.

   Breakpoints, smallest first in intent:
     900px  — the burger replaces the nav links; two-column page furniture stacks
     700px  — anything still multi-column becomes one column
     560px  — phone proper: type scale down, padding down, buttons go full width
     380px  — iPhone SE / older Androids

   Keep desktop untouched: nothing here applies above 900px.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Global safety ──────────────────────────────────────────────────────── */

:root{
  /* Height of the fixed nav on small screens: 16px padding + 44px burger + 16px.
     The mobile menu and every scroll-margin below are measured from this, so
     changing the nav padding only needs editing in one place. */
  --nav-h: 76px;
}

html{
  /* Stop iOS from inflating type when the device is turned to landscape. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@media (max-width: 900px){
  /* Anchored jumps land below the fixed nav rather than under it. */
  :target,
  [id]{ scroll-margin-top: calc(var(--nav-h) + 12px); }

  /* Long unbroken strings — URLs, emails, client names — must never be the
     thing that makes the page scroll sideways. */
  body{ overflow-x: hidden; }
  h1, h2, h3, h4, p, li, a, span, q, blockquote{ overflow-wrap: break-word; }

  /* Media stays inside its box no matter what width attribute it carries.
     Only raster images get height:auto — the hero's WebGL canvas is sized by
     script and the video slides are absolutely positioned, so forcing an
     intrinsic height on those would collapse them. */
  img, picture{ max-width: 100%; height: auto; }
  svg, video, iframe, canvas{ max-width: 100%; }
}

/* ── Navigation ─────────────────────────────────────────────────────────── */

@media (max-width: 900px){
  /* The panel was pinned at 59px while the bar is 76px tall, so it opened
     underneath the nav and clipped its first link. */
  .mobile-menu{
    top: var(--nav-h) !important;
    max-height: calc(100svh - var(--nav-h)) !important;
    padding-bottom: calc(22px + env(safe-area-inset-bottom)) !important;
    overscroll-behavior: contain;
  }
  /* Full-bleed rows are easier to hit than text-width ones. */
  .mobile-menu .mm-link{
    min-height: 48px;
    display: flex;
    align-items: center;
  }
  .mobile-menu .mm-cta{ min-height: 48px; display: flex; align-items: center; justify-content: center; }

  /* The burger sits over both dark heroes and light scrolled chrome; the page
     stylesheets only colour it for the dark case. */
  .nav.is-light .nav-burger span,
  .nav.is-scrolled:not(.is-dark) .nav-burger span{ background: #25282a; }

  .nav-inner{ gap: 12px; padding: 16px 0; }
  .logo img{ height: 24px; }
  /* A tap on the logo should not need precision. */
  .logo{ min-height: 44px; align-items: center; }
}

/* ── Type scale ─────────────────────────────────────────────────────────── */

@media (max-width: 900px){
  /* The page sheets set these with vw-based clamps whose floor was chosen for
     desktop; on a 390px screen the floor is what you get, and it is too big.
     !important is needed because the hero headings also carry an inline
     fontSize. */
  .display{ font-size: clamp(34px, 8.6vw, 60px) !important; line-height: 1.02; }
  .display-mid{ font-size: clamp(29px, 7.2vw, 50px) !important; line-height: 1.06; }
  .h2{ font-size: clamp(27px, 6.4vw, 44px) !important; line-height: 1.1; }
  .h3{ font-size: clamp(20px, 4.6vw, 26px) !important; }
  .lede{ font-size: 17px; line-height: 1.6; max-width: none; }
  .eyebrow{ font-size: 11px; letter-spacing: .16em; }
}

@media (max-width: 560px){
  .display{ font-size: clamp(31px, 8.2vw, 44px) !important; }
  .display-mid{ font-size: clamp(27px, 7vw, 38px) !important; }
  .h2{ font-size: clamp(25px, 6.2vw, 34px) !important; }
  .lede{ font-size: 16.5px; }
}

/* ── Buttons and tap targets ────────────────────────────────────────────── */

@media (max-width: 900px){
  /* 44px is the smallest reliably tappable target. */
  .btn, .ico-btn, .play-tab, .hero-dot, .clients-dot, .nav-burger{
    min-height: 44px;
    -webkit-tap-highlight-color: transparent;
  }
  .btn{ padding: 14px 20px; }
  /* Long CTA labels wrap rather than push the row sideways. */
  .btn{ white-space: normal; text-align: center; }
  .hero-dot, .clients-dot{
    /* Keep the dot its designed size but give it an invisible 44px target. */
    min-height: 0;
    position: relative;
  }
  .hero-dot::after, .clients-dot::after{
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
  .foot-col a, .menu-item{ min-height: 40px; display: flex; align-items: center; }
  .btn-link{ min-height: 44px; }
}

@media (max-width: 560px){
  /* A row of pill buttons at phone width reads better as a stack of full-width
     ones than as two half-width pills with wrapped labels. */
  .hero-bold .meta > div,
  .cta-final .row,
  .work-head .btn + .btn{ width: 100%; }
  .cta-final .row{ display: flex; flex-direction: column; align-items: stretch; }
  .cta-final .row .btn{ justify-content: center; width: 100%; }
  .hero-bold .meta > div{ flex-direction: column; align-items: stretch; }
  .hero-bold .meta > div .btn{ justify-content: center; }
}

/* ── Hero ───────────────────────────────────────────────────────────────── */

@media (max-width: 900px){
  .hero{
    /* 100vh on a phone is the height *without* the browser chrome, so the hero
       is taller than the screen and the fold lands mid-sentence. svh is the
       small viewport — what is actually visible with the toolbars showing. */
    min-height: 100vh;
    min-height: 100svh;
    padding-top: calc(var(--nav-h) + 24px);
    padding-bottom: 48px;
  }
  .hero[data-variant="cinematic"]{ padding-top: calc(var(--nav-h) + 24px); }
  .hero-bold .hero-content--split{ min-height: calc(100svh - var(--nav-h) - 72px); }

  /* Headline, copy and buttons in one column instead of a spread row. */
  .hero-bold .meta{
    flex-direction: column;
    align-items: stretch;
    gap: 24px;
    margin-top: 32px;
  }
  .hero-bold .meta-copy{ max-width: none; }
  .hero-bold .display-stack .word + .word{ margin-left: .18em; }
  .hero-dots{ margin-top: 32px; }

  .hero-quiet .hero-grid{ gap: 32px; }
  .hero-quiet .demo-card{ padding: 16px; border-radius: 18px; }
  .cine-meta, .hero-cine .cine-meta{ flex-direction: column; align-items: flex-start; gap: 20px; }
}

@media (max-width: 560px){
  .hero{ padding-bottom: 40px; }
  /* Below this width the stacked hero is already taller than the screen; a
     forced full-height box only adds dead space above the eyebrow. */
  .hero{ min-height: auto; }
  .hero-bold .hero-content--split{ min-height: 0; }
}

/* ── Section rhythm ─────────────────────────────────────────────────────── */

@media (max-width: 560px){
  /* Desktop breathing room (80–140px a side) is a third of a phone screen. */
  .pillars, .play, .solutions, .work, .quote-band{ padding: 64px 0 !important; }
  .cta-final{ padding: 72px 0 !important; }
  .clients{ padding: 40px 0 !important; }
  .pillars-head, .play-head, .work-head{ margin-bottom: 32px !important; }
}

/* ── Grids: the generic net ─────────────────────────────────────────────── */

/* Most multi-column layouts are inline styles on unclassed divs, so they are
   reachable only through the style attribute. Matching a substring rather than
   the full declaration keeps this working whichever way the value happens to
   serialise ("repeat(3,1fr)" vs "repeat(3, 1fr)"). Safe to be this broad:
   nothing in the site uses grid-template-rows. */
@media (max-width: 1000px){
  [style*="repeat(4"]{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [style*="repeat(6"]{ grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
}

@media (max-width: 700px){
  [style*="repeat(2"],
  [style*="repeat(3"],
  [style*="repeat(4"],
  [style*="1fr 1fr"],
  [style*="minmax(0, 1fr) minmax(0"],
  [style*="minmax(0px, 1fr) minmax(0px"]{
    grid-template-columns: minmax(0, 1fr) !important;
  }
  /* Icon-beside-text rows keep their two columns — the fixed track is small and
     stacking them would orphan the icon on its own line. */
  [style*="64px 1fr"], [style*="88px 1fr"], [style*="36px 1fr"]{
    grid-template-columns: 48px minmax(0, 1fr) !important;
    gap: 16px !important;
  }
  /* Gaps sized for a 1240px canvas leave huge holes once stacked. */
  [style*="gap: 48px"], [style*="gap: 56px"], [style*="gap: 64px"], [style*="gap: 96px"]{
    gap: 28px !important;
  }
}

/* ── Grids: named ───────────────────────────────────────────────────────── */

@media (max-width: 1000px){
  .work-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .about-team-grid{ grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
  .clients-grid{ grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
}

@media (max-width: 700px){
  .work-grid,
  .about-story-grid,
  .contact-hero-grid,
  .svc-hero-grid,
  .site-grid,
  .spotlight-grid,
  .pgrid, .pgrid.c3,
  .feat-grid, .feat-grid.c2, .feat-grid.c3,
  .rel-grid,
  .rd-inner,
  .foot-grid,
  .pillars-grid,
  .play-head, .play-stage, .pillars-head, .solutions-grid, .quote{
    grid-template-columns: minmax(0, 1fr) !important;
  }
  .about-team-grid,
  .about-values-grid,
  .clients-grid,
  .contact-interested-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

@media (max-width: 380px){
  /* Two columns of cards at 320px leaves ~140px of usable width. */
  .about-values-grid,
  .contact-interested-grid{ grid-template-columns: minmax(0, 1fr) !important; }
}

/* ── Services playground ────────────────────────────────────────────────── */

@media (max-width: 900px){
  .play-head{ gap: 20px !important; }
  .play-stage{ gap: 24px !important; }
  /* 480px of empty card before the image loads is most of a phone screen. */
  .play-preview{ min-height: 300px !important; }
  .play-card{ padding: 22px !important; }
  .play-card .pcc{ max-width: none; }

  .play-row{ grid-template-columns: 30px minmax(0, 1fr) auto !important; gap: 12px !important; padding: 15px 2px !important; }
  .play-row .name{ font-size: clamp(19px, 4.8vw, 26px) !important; }
  .play-row .name svg{ flex: none; }
  /* Hover-only affordances never fire on touch, so show the arrow outright. */
  .play-row .arrow{ opacity: .55; transform: none; }

  /* Tabs scroll rather than wrap onto three lines. */
  .play-tabs{
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-left: calc(var(--gutter) * -1);
    margin-right: calc(var(--gutter) * -1);
    padding-left: var(--gutter);
    padding-right: var(--gutter);
  }
  .play-tabs::-webkit-scrollbar{ display: none; }
  .play-tab{ flex: none; }
}

/* ── Filter chips (work.html, clients.html) ─────────────────────────────── */

@media (max-width: 900px){
  /* 6–7px of vertical padding gives a 32px button; a thumb needs 44. Padding
     rather than a min-height keeps the label optically centred in the pill. */
  .filter-chip{
    min-height: 44px;
    padding-top: 11px !important;
    padding-bottom: 11px !important;
    -webkit-tap-highlight-color: transparent;
  }
  /* Nine categories wrap to four rows at phone width and push the grid below
     the fold. One scrollable row keeps the content in view. */
  .filter-row{
    flex-wrap: nowrap !important;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-left: calc(var(--gutter) * -1);
    margin-right: calc(var(--gutter) * -1);
    padding: 2px var(--gutter);
  }
  .filter-row::-webkit-scrollbar{ display: none; }
  .filter-chip{ flex: none; white-space: nowrap; }
}

/* ── Inline card links ──────────────────────────────────────────────────── */

@media (max-width: 900px){
  /* "Learn more" / "View project" / "Visit site" are the only action in their
     card but render as bare 15–18px text. Pad them into a real target without
     changing where they sit. */
  .play-card .pcc .more,
  .btn-link,
  a.cta-inline,
  a.view, a.visit, a.url{
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}

/* ── Solutions ──────────────────────────────────────────────────────────── */

@media (max-width: 900px){
  .solutions-grid{ gap: 32px !important; }
  /* The art is a square; at full width it eats a whole screen for a decoration. */
  .solutions-art{ width: 100% !important; max-width: 420px !important; margin: 0 auto; }

  /* Desktop pushes the artwork to the right of its square (object-position) to
     open a gutter for the floating labels, because at that size they sit
     beside the stack. Here they are pinned on top of it by design, so there is
     no gutter to make and an off-centre stack would just look misaligned in a
     centred column. Put it back in the middle. */
  .solutions-art img{ object-position: center !important; }

  /* The floating labels are positioned in percentages of a much wider box, so
     on a phone they hang off the left edge. Pin them inside instead. */
  .solutions-art .tag{
    font-size: 12px;
    padding: 8px 11px;
    gap: 8px;
    max-width: calc(100% - 16px);
  }
  .solutions-art .tag.t1{ left: 0 !important; top: 20% !important; }
  .solutions-art .tag.t2{ left: 0 !important; top: 45% !important; }
  .solutions-art .tag.t3{ left: 0 !important; top: 70% !important; }

  .solutions-list{ gap: 0 !important; margin-top: 24px !important; }
  .solutions-list li{ font-size: 16px; padding: 13px 0; }
  .solutions-list .check{ width: 36px; height: 36px; border-radius: 10px; }
}

/* ── Work rail and cards ────────────────────────────────────────────────── */

@media (max-width: 900px){
  /* A card wide enough to read, narrow enough that the next one peeks in and
     advertises that the rail scrolls. */
  .work-rail .work-card{ width: min(78vw, 330px); }
  .work-rail{ gap: 16px; }
  .work-card .body{ padding: 20px; }
  .work-card .body h4{ font-size: 19px; }
  .work-head{ gap: 20px; margin-bottom: 32px; }
}

@media (max-width: 700px){
  /* work.html's project cards: the 3-up grid squeezed titles to one word per
     line. Stacked, each card gets the full column. */
  .work-grid{ gap: 20px !important; }
  /* .work-card is shared with the homepage rail, where it carries a fixed
     width:clamp(280px,32vw,420px). In a grid cell that floor leaves a 70px
     gutter down the right of every card, so let the cell decide. */
  .work-grid > .work-card{ width: 100%; }
}

/* ── Quote band ─────────────────────────────────────────────────────────── */

@media (max-width: 900px){
  .quote{ gap: 24px !important; }
  .quote q{ font-size: clamp(21px, 5.2vw, 30px) !important; line-height: 1.3; }
  .quote-author img{ width: 52px; height: 52px; }
}

/* ── Clients strip ──────────────────────────────────────────────────────── */

@media (max-width: 900px){
  .clients-page{ grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 28px 20px !important; }
  .clients-row img{ height: 68px; }
  .clients-row{ gap: 20px; }
}

@media (max-width: 560px){
  .clients-page{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 24px 16px !important; }
  .clients-row img{ height: 56px; }
}

/* clients.html's logo wall. The cells are a fixed 224px tall with 32px of side
   padding — sized for a quarter of a 1240px canvas. At two columns on a phone
   that leaves under 100px for the logo itself inside a very tall box. */
@media (max-width: 900px){
  .clients-grid > div{ height: 150px !important; padding: 18px !important; }
}
@media (max-width: 380px){
  .clients-grid > div{ height: 132px !important; padding: 12px !important; }
}

/* ── Final CTA and footer ───────────────────────────────────────────────── */

@media (max-width: 900px){
  /* The blurred colour blobs are sized in fixed px and hang past both edges;
     with overflow-x hidden they are only clipped, but they also wash out the
     text at phone scale. */
  .cta-final::before{ width: 300px !important; height: 300px !important; left: -110px !important; }
  .cta-final::after{ width: 280px !important; height: 280px !important; right: -100px !important; }

  .foot{ padding: 56px 0 calc(28px + env(safe-area-inset-bottom)) !important; }
  .foot-grid{ gap: 32px !important; }
  .foot-bottom{
    margin-top: 40px !important;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
}

/* ── Modals and lightboxes ──────────────────────────────────────────────── */

@media (max-width: 900px){
  .rm-modal-backdrop{ padding: 12px; }
  .rm-modal{
    max-height: 90svh;
    overscroll-behavior: contain;
  }
  .rm-modal-body{ padding: 24px !important; }
  /* Close buttons sit in the corner of a scrollable sheet — make them big
     enough to hit without zooming. */
  .rm-modal-close{ width: 40px; height: 40px; }
}

/* ── Contact step form ──────────────────────────────────────────────────── */

@media (max-width: 900px){
  /* The prev/next control is position:fixed bottom-right with no background,
     so it floated over the form fields and, further down, over the footer
     copy. Give it a surface of its own and lift it clear of the home bar. */
  .cf-nav{
    bottom: calc(16px + env(safe-area-inset-bottom)) !important;
    right: 16px !important;
    padding: 6px 8px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    box-shadow: 0 8px 28px -10px rgba(0, 0, 0, .35);
    border: 1px solid rgba(0, 0, 0, .07);
  }
  .cf-nav button{ width: 40px !important; height: 40px !important; }

  /* Inputs must stay at 16px or larger or iOS zooms the page on focus and
     never zooms back out. The form's own clamp already clears that; this is a
     floor for anything else on the page. */
  input, select, textarea{ font-size: max(16px, 1em); }
}

/* ── Marquees ───────────────────────────────────────────────────────────── */

@media (max-width: 560px){
  .marquee-words .track{ padding: 22px 0; gap: 40px; }
  .ticker-track{ padding: 14px 0; gap: 32px; font-size: 12px; }
}

/* Continuous marquees, the ken-burns hero and the floating art all animate
   forever. Honour the OS switch for anyone who has asked them not to. */
@media (prefers-reduced-motion: reduce){
  .ticker-track,
  .marquee-words .track,
  .solutions-art img,
  .hero-cine .hero-bg img,
  .cine-slide.active::after{
    animation: none !important;
  }
  .reveal{ opacity: 1 !important; transform: none !important; }
  *, *::before, *::after{
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
