/* ============================================================================
   77 Media · PHONE LAYER                                    9 Sep 2026 (Nitin)
   ----------------------------------------------------------------------------
   Every rule in this file sits inside a max-width query, and the sheet is linked
   LAST, after site.css / theme.css / svcpage.css / svc.css. Two consequences,
   both deliberate:

     · desktop cannot be touched by anything written here (rule C2), and
     · at equal specificity these rules win, so an existing phone rule can be
       corrected without editing the 91 KB inline sheet on the homepage.

   Written against Nitin's phone pass of 9 Sep 2026. Each block names the item.
   ========================================================================== */

@media (max-width:767px){

/* ── 1 · HERO ───────────────────────────────────────────────────────────────
   The three badges sat one per row and the two buttons stacked, because the
   badge row wraps and each button is sized to its own label. Nowrap on both,
   copy centred. The badge row can scroll if a longer set is ever added, so it
   is one line at any label length rather than one line only for these three. */
.hero--v5 .hero__copy{width:100%;max-width:100%;align-items:center;text-align:center}
.hero--v5 .hero__h1,.hero--v5 .hero__lede{text-align:center}
.hero--v5 .hero__badges{
  display:flex;flex-wrap:nowrap;justify-content:center;align-items:center;
  gap:clamp(4px,1.3vw,6px);margin:0 0 14px;max-width:100%;
  overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;-ms-overflow-style:none;
}
.hero--v5 .hero__badges::-webkit-scrollbar{display:none}
/* sized off the viewport, not off these three labels, so the row still fits on a
   360px phone and would still fit if a label were rewritten longer */
.hero--v5 .hero__badges .badge{
  flex:0 0 auto;white-space:nowrap;
  font-size:clamp(9px,2.6vw,11px);letter-spacing:.04em;padding:6px clamp(6px,1.8vw,10px);
}
/* The nav is position:fixed and 82px tall, and the hero's own padding-top was
   72px, so the badge row started at y=81 — touching it. Cleared, and the whole
   hero moves down with it (Nitin, 9 Sep). */
.hero{padding-top:118px}
/* Two lines on a phone, not four (Nitin, 9 Sep): "We run your marketing." and
   "You run your business." The markup is four <span class="hero__line"> blocks, so
   they go inline and a single hard break is injected after the second. The spans sit
   flush against each other in the HTML, hence the explicit spaces after 1 and 3.
   Sized off the viewport so each line fits the screen at any phone width. */
/* Four stacked lines, as the design has always had them (Nitin, 9 Sep: "I said I don't
   want the change to the hero text... make them in four lines, how it was before"). The
   two-line experiment is reverted in full: no display:block on the h1, no inlining of the
   reveal wrappers, no injected break. Only the size stays raised. */
/* line-height 1.02 was tuned for Fredoka, whose ascenders and descenders are short.
   Plus Jakarta Sans 800 is taller on both, so at 1.02 the 'g' of marketing ran into
   the line beneath and the line above ran under the nav. 1.14 clears both. */
.hero--v5 .hero__h1{font-size:clamp(45px,12.4vw,54px);line-height:1.06}
/* Nitin: the coloured words read as unbolded now. The weight did not change — both
   they and the words around them are 800, and 800 is the heaviest face Plus Jakarta
   ships, so there is nothing heavier to ask for. What changed is SIZE: they used to
   be 1.2em/1.12em, which is what made them sit proud of the line. A smaller bump
   brings the emphasis back without the overshoot that made them look like a
   different font. Phone only, as asked. */
.hero--v5 .hero__h1 .hl--a{font-size:1.09em}
.hero--v5 .hero__h1 .hl--b{font-size:1.07em}
/* The row was carrying `padding-right:24.9px` from further up the cascade, and
   with border-box that came off the content width — which is why the pair sat
   flush left with a gap on the right however the justification was set. Zeroed. */
.hero--v5 .hero__cta{
  display:flex;flex-wrap:nowrap;justify-content:center;align-items:stretch;
  gap:10px;width:100%;max-width:300px;margin-inline:auto;
  padding-left:0;padding-right:0;
}
/* the two are sized off the row, not off their labels, so they are the same
   button twice — and the row is capped so they read smaller than they did */
.hero--v5 .hero__cta .btn{
  flex:1 1 0;min-width:0;justify-content:center;
  padding:0 10px;font-size:13.5px;
}
.hero--v5 .hero__cta .btn__label{white-space:nowrap}
.hero--v5 .hero__cta .arrow{flex:none}

/* ── 2 · WHY WORK WITH US ───────────────────────────────────────────────────
   Was a 2x2 grid of 160px cards, so every card carried a full sentence in a
   column eight characters wide. One card per row now, and they pile up on the
   sticky offsets the happy-clients block uses, so 001 to 004 land on top of
   each other and the section ends when the last one has landed. */
.why-grid{
  display:flex;flex-direction:column;gap:14px;
  min-height:calc(100vh + 220px);
}
.why-grid .why-card{
  position:sticky;top:calc(84px + var(--i,0) * 14px);
  box-shadow:0 18px 40px rgba(10,1,28,.13);
}
.why-grid .why-card:nth-child(1){--i:0}
.why-grid .why-card:nth-child(2){--i:1}
.why-grid .why-card:nth-child(3){--i:2}
.why-grid .why-card:nth-child(4){--i:3}
.why-grid .why-card:nth-child(5){--i:4}
.why-grid .why-card:nth-child(6){--i:5}

/* ── 3 · SERVICES STACK, back on for phones ──────────────────────────────────
   It was reverted an hour ago because the workspace pane (518px) was leaking out of
   its 328px window on iOS and printing over the card's copy. That was never the
   stack's fault: `.sstk__media .shell` had `mask-image:none`, and the mask is the
   only thing that makes iOS clip a composited child. With the mask restored the
   pane crops the way it always should have, so the pile-up can come back.
   The media is 300px, not the 220px I squashed it to before — the mask now handles
   the crop, so this number only decides HOW MUCH of the workspace you see, and 300
   keeps the whole card inside the screen: 300 + copy + padding lands about 740px,
   which clears the 82px sticky line with room. */
.sstk{gap:14px}
.sstk__card{position:sticky;top:82px;height:auto;z-index:1}
.sstk__wrap{grid-template-columns:minmax(0,1fr);height:auto}
.sstk__media{order:-1;height:300px;padding:10px 10px 0}
.sstk__copy{padding:18px 18px 22px}
.sstk .svc__t{font-size:21px}
.sstk .svc__d{font-size:14.5px;margin-top:10px}
.sstk .svc__do li{font-size:13.5px}

/* ── 4 · TEAM ───────────────────────────────────────────────────────────────
   Nitin, 9 Sep: "I don't want the scroll to happen. You have made it worse.
   Restore it to the original setting with no scroll, only back and forth." The
   auto-scroll marquee is gone from mobile.js; this is the row as it was, swiped
   by hand with its snap points. Nothing here but the note, deliberately. */

/* ── 5 · PRICING ────────────────────────────────────────────────────────────
   The homepage row was already a swipe carousel but opened on Foundation.
   mobile.js parks it on Growth. The service pages were a single column, so
   they become the same carousel here and get the same starting card. */
.svcstd .pcards{
  display:flex;gap:12px;align-items:flex-start;
  overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  padding:4px var(--gutter,20px) 22px;margin-inline:calc(-1 * var(--gutter,20px));
  scrollbar-width:none;-ms-overflow-style:none;
}
.svcstd .pcards::-webkit-scrollbar{display:none}
.svcstd .pcards .pcard{flex:0 0 86%;scroll-snap-align:center;margin:0}

/* ── 6 · HAPPY CLIENTS, ON THE SERVICE PAGES ────────────────────────────────
   svc.css only pinned these at 1024px and up, so on a phone the five cards ran
   down the page with no pile. Same offsets the homepage uses. */
.svcstd .tst__cards{min-height:calc(100vh + 360px)}
.svcstd .tst__card{position:sticky;top:calc(96px + var(--i,0) * 18px)}

/* ── 7 · BOOK THE CALL ──────────────────────────────────────────────────────
   theme.css gave each button flex-basis 100%, so WhatsApp and Email us took a
   row each. They share one row now, on the homepage and the service pages. */
.cta__ways{display:flex;flex-wrap:wrap;align-items:stretch;gap:10px}
.cta__ways .btn{flex:1 1 0;min-width:0;justify-content:center;padding:0 12px;font-size:14px;min-height:44px}
.cta__ways .btn .btn__label{white-space:nowrap}
.cta__ways .cta__loc{flex:1 1 100%;order:2;text-align:center}

/* ── 8 · SERVICE PAGE PILLS ─────────────────────────────────────────────────
   Hero pills wrapped to leave one pill alone on the last row. One line now,
   scrolling only if a longer label set is ever written. */
.hpills{
  display:flex;flex-wrap:nowrap;gap:6px;
  max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
}
.hpills::-webkit-scrollbar{display:none}
.hpills .hpill{flex:0 0 auto;white-space:nowrap;font-size:11.5px;padding:6px 10px}

/* The four trust pills under the plan cards. Two of the four are long enough
   that one line is not honest at this width, so they go two per row, evenly,
   which is the fallback Nitin named: never one pill on a row of its own. */
.svcstd .trustrow{
  display:grid;grid-template-columns:1fr 1fr;gap:8px;justify-content:stretch;
}
.svcstd .trustrow .trustpill{
  display:flex;align-items:center;justify-content:center;text-align:center;
  font-size:11.5px;line-height:1.25;padding:8px 10px;margin:0;
}

/* "Also from 77 Media": five links, one line, swipeable. The fade on the right
   edge is the cue that the row keeps going, so the fifth pill reads as "more"
   rather than as a pill that got cut off. */
.svcp__rel ul{
  -webkit-mask-image:linear-gradient(90deg,#000 82%,transparent 100%);
  mask-image:linear-gradient(90deg,#000 82%,transparent 100%);
  display:flex;flex-wrap:nowrap;gap:8px;
  max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
  padding-bottom:2px;
}
.svcp__rel ul::-webkit-scrollbar{display:none}
.svcp__rel li{flex:0 0 auto}
.svcp__rel a{white-space:nowrap;font-size:13px;padding:8px 13px}

/* ── 9 · HEADLINES ──────────────────────────────────────────────────────────
   Root cause of "the alphabets are merging": theme.css tracks the round face at
   -.045em, which is -1.17px at the 26px a phone renders, and Fredoka's bowls are
   wide, so o/e/a/c touch their neighbours. Tracking is relaxed here and the
   weight is pinned to 700 — the top of the variable font's declared 300..700
   range — with synthesis off, so no engine can smear a fake 800 on top.
   The step-by-step headline is also sized up, which Nitin asked for. */
/* Nitin, 9 Sep: "the font you have used for the heading is different from what
   we have used on the homepage. Can you match it? The bold heading looks very
   junky and not crisp at all."
   Both halves of that have the same cause. The service headings are Fredoka,
   whose @font-face declares `font-weight:300 700`, and the CSS asks for 800 —
   a weight that family cannot draw, so an engine is free to fake one by
   thickening the outline, which is what "junky" is. The homepage headings are
   Plus Jakarta Sans, which ships a REAL 800 face. Matching the homepage
   therefore fixes the crispness and the mismatch in one move: same family, same
   weight, a weight that actually exists. Synthesis is switched off so no engine
   can invent one, and the tracking comes back from -.045em, which is -1.17px at
   the size a phone renders and closes the round letters into each other. */
.svcstd .svcp__h1,.svcstd .svcp__h2,.svcstd h3.svcp__h2,.svcstd .svcp__h1--big{
  font-family:var(--font-sans,"Plus Jakarta Sans",-apple-system,system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif);
  font-weight:800;
  letter-spacing:-.03em;
  font-synthesis-weight:none;-webkit-font-synthesis:none;
}
/* bigger, on his word, on every service page */
.svcstd .lphero .svcp__h1,.svcstd .lphero .svcp__h1--big{font-size:clamp(36px,9.6vw,44px);line-height:1.04}
.svcstd .svcp__h2--mid{font-size:clamp(28px,7.6vw,34px);line-height:1.14}
/* The same treatment the homepage hero got (Nitin: the service headings still look
   junky). The cause is a weight split INSIDE one heading: the coloured span computed
   at 700 while the words around it were 800, so half the line reads lighter than the
   other half. `inherit` on all three properties makes the highlight the same type as
   its heading, differing only in colour — which is what the homepage does. The line
   spacing comes down to 1.06 to match, and the tracking is eased off -.03em, which is
   -1.12px at the size a phone renders. */
.svcstd .svcp__h1 .serif,.svcstd .svcp__h1 .hl,
.svcstd .svcp__h2 .serif,.svcstd .svcp__h2 .hl,
.svcstd h3.svcp__h2 .serif,.svcstd h3.svcp__h2 .hl{
  font-family:inherit;font-weight:inherit;font-size:1em;letter-spacing:inherit;
  font-synthesis-weight:none;-webkit-font-synthesis:none;
}
.svcstd .svcp__h1,.svcstd .svcp__h1--big,.svcstd .svcp__h2,.svcstd h3.svcp__h2{
  line-height:1.06;letter-spacing:-.02em;
}
.svcstd .flow__t{letter-spacing:-.005em}
.svcstd b,.svcstd strong{font-synthesis-weight:none;-webkit-font-synthesis:none}

/* the service hero's own two buttons, on one line and the same size as each
   other, the way the homepage pair now is */
.svcstd .hcta{display:flex;flex-wrap:nowrap;gap:10px;width:100%;max-width:330px}
.svcstd .hcta .btn{flex:1 1 0;min-width:0;justify-content:center;padding:0 10px;font-size:13.5px}
.svcstd .hcta .btn .btn__label{white-space:nowrap}

/* ── 9a · ONE BUTTON SHAPE ──────────────────────────────────────────────────
   Nitin: "all the buttons should be identical in shape and size." Measured on
   the homepage they ran 44, 46, 49, 52 and 66px tall at two font sizes and four
   paddings. One height, one size, one radius, everywhere on a phone. The pill
   that carries a price line keeps its own height, because its label is two
   lines and clamping it would clip the price. */
.btn{min-height:46px;height:46px;font-size:14.5px;padding:0 18px;border-radius:999px}
.btn--sm,.btn--ghost,.btn--ink,.btn--onDark{min-height:46px;height:46px}
.btn .btn__label{font-size:inherit}
/* the offer pill is the one exception: its label runs to two lines and a fixed
   height would clip the price off the bottom */
.audit__cta .btn{min-height:auto;height:auto;padding:12px 18px}

/* ── 9b · HOW IT WORKS: the empty band around the laptop ────────────────────
   `.fsh-canvas` is height:106vh with width:auto and max-width:100%, so on a
   390px screen the BOX is 350x895 while the frame inside it, at its 2:3 ratio,
   draws as 350x525. object-fit:contain centres that, leaving **185px of empty
   space above and below** — the padding Nitin saw between the heading and the
   Mac. The box now hugs the frame. Nothing about the animation changes: same
   pixels, same size, same scrub. (The lift that used to compensate for the
   composition sitting low in that tall box is zeroed for phones in site.js,
   or the laptop would ride up out of the stage.) */
.fsh-canvas{height:auto;width:100%;max-width:100%}
/* and the frame sits at the TOP of its sticky stage rather than centred in a
   full-height one, which is the rest of the gap Nitin was looking at. The step
   card below it keeps the room it had. */
.fsh-canvas-wrap{align-items:flex-start;padding-top:6px}
.approach{padding-top:40px;padding-bottom:36px}
.approach .section-head{margin-bottom:4px}

/* ── 9c · MONTHLY UPKEEP, on the website page ───────────────────────────────
   Three care plans that ran down the page one after another. They pile up on
   the happy-clients offsets, like every other card set on a phone. */
.svcstd .upk{display:flex;flex-direction:column;gap:14px;min-height:calc(100vh + 160px)}
.svcstd .upk__c{position:sticky;top:calc(88px + var(--i,0) * 14px);box-shadow:0 16px 38px rgba(10,1,28,.12)}
.svcstd .upk__c:nth-child(1){--i:0}
.svcstd .upk__c:nth-child(2){--i:1}
.svcstd .upk__c:nth-child(3){--i:2}

/* ── 9d · THE PROCESS, PINNED ───────────────────────────────────────────────
   Nitin: the animation should hold while you scroll through the five steps, and
   only then let the page move on. mobile.js wraps the stage and the list in
   `.flow__pin` and sets --steps; the track is that many screens of scroll, and
   the pinned box stays put while the step changes under the scroll position. */
/* The track height is set by mobile.js, not here. It used to be
   `height:calc((var(--steps,5) + 1) * 74vh)`, and clean-css silently DROPPED the
   whole declaration — and with it the rule — because of the var() inside the
   calc(). The minified build then had a sticky child with no track to stick in,
   so the section scrolled straight past. The build now refuses to ship a sheet
   that loses declarations (see _site/build-production.mjs), and this expresses
   the height where the step count actually lives. */
.svcstd .flow.is-pinned{display:block;position:relative}
.svcstd .flow.is-pinned .flow__pin{
  position:sticky;top:76px;
  display:flex;flex-direction:column;gap:12px;
}
.svcstd .flow.is-pinned .flow__stage{order:1;min-height:190px;margin:0}
.svcstd .flow.is-pinned .flow__steps{order:2;margin:0}
.svcstd .flow.is-pinned .flow__step{padding:0 4px 12px}
.svcstd .flow.is-pinned .flow__d{
  max-height:0;opacity:0;overflow:hidden;
  transition:max-height .38s var(--ease-out,ease), opacity .28s ease;
}
.svcstd .flow.is-pinned .flow__step.is-live .flow__d{max-height:9em;opacity:1}

/* ── 10 · FOOTER ────────────────────────────────────────────────────────────
   Nitin's order for the phone: the logo with the socials opposite it, then Get
   in touch, then Stay in the loop full width so the email field is reachable,
   then Services and Company side by side and centred. "Boston, MA" leaves the
   social row; the address inside Get in touch stays. */
.footer--v2 .footer__head{
  flex-direction:row;align-items:center;justify-content:space-between;gap:12px;
}
.footer--v2 .footer__loc{display:none}
.footer--v2 .footer__headr{gap:0}
.footer--v2 .footer__social{gap:12px}

.footer--v2 .footer__grid{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 18px;
  text-align:center;
}
.footer--v2 .footer__col{min-width:0}
.footer--v2 .footer__col ul{align-items:center}
.footer--v2 .footer__col:nth-child(3){order:1;grid-column:1 / -1}   /* Get in touch  */
.footer--v2 .footer__col--nl        {order:2;grid-column:1 / -1}   /* Stay in the loop */
.footer--v2 .footer__col:nth-child(1){order:3}                     /* Services */
.footer--v2 .footer__col:nth-child(2){order:4}                     /* Company  */
/* Nitin's order for the phone: logo and socials, then the address, then the
   Get in touch label and its two buttons under it. */
.footer--v2 .footer__col:nth-child(3){display:flex;flex-direction:column}
/* Nitin, 9 Sep: the address comes out of the phone footer entirely. "Boston, MA"
   already left the social row; this is the "Boston, MA / United States" block under
   Get in touch. Desktop keeps both — it is a real address and belongs on the page,
   just not twice on a screen this narrow. */
.footer--v2 .footer__col:nth-child(3) .footer__addr{display:none}
.footer--v2 .footer__col:nth-child(3) .footer__ct{order:2}
.footer--v2 .footer__col:nth-child(3) .footer__btns{order:3}
.footer--v2 .footer__addr{text-align:center}
.footer--v2 .footer__btns{justify-content:center}

/* the email field was inside a half-width column and ran off the screen */
.footer--v2 .footer__col--nl .nl__form{
  display:flex;flex-wrap:nowrap;gap:8px;width:100%;max-width:420px;margin-inline:auto;
}
.footer--v2 .footer__col--nl .nl__input{flex:1 1 auto;min-width:0;width:auto}
.footer--v2 .footer__col--nl .nl__btn{flex:0 0 auto;white-space:nowrap}
.footer--v2 .footer__nlnote{max-width:34ch;margin-inline:auto}

/* The wordmark and the line under it: centred, and the wordmark a size up.
   It only gets to be bigger by giving up the page gutter — measured, its width is
   4.49x its font-size, so 78px was already exactly the 350px a 390px screen leaves
   inside the wrap. Spanning the full viewport instead buys about 10%, and 21.5vw
   holds that ratio at every phone width rather than at this one. */
.footer--v2 .footer__mark{
  text-align:center;font-size:21.5vw;
  margin-inline:calc(-1 * var(--gutter,20px));
}
.footer--v2 .footer__bot{
  justify-content:center;text-align:center;font-size:13.5px;line-height:1.6;gap:10px;
}
.footer--v2 .footer__bot > span{flex:1 1 100%}
.footer--v2 .footer__legal{width:100%;justify-content:center;flex-wrap:wrap;gap:14px}

/* ── 11 · THE PHONE CRASH: `will-change` IS NOT FREE ─────────────────────────
   Measured on a service page at a phone's 3x pixel density, BEFORE this block:
   **140.6 MB of permanently composited GPU layers**, on a page whose JavaScript
   heap is 3 MB and whose DOM is 2,088 nodes. It is not the script and it is not
   the images — it is layer memory, and iOS Safari kills a tab for that.

     pcard       x3   39.4 MB   will-change, 301x1298 each
     why-card    x6   31.6 MB   will-change AND sticky
     swall__track x2  26.2 MB   will-change, 123x3102
     tst__card   x5   16.7 MB   sticky
     .r          x2   13.6 MB   will-change
     flow__pin   x1    8.1 MB   sticky
     tst__left   x1    5.0 MB   will-change

   `will-change` promotes an element to its own GPU layer and KEEPS it there for
   the life of the page. It is declared on every element with an entrance
   animation, so fourteen large boxes hold a layer each from first paint — before
   any of them has been scrolled to, and long after they have finished animating.
   The `r--done` class that is supposed to release it was measured false on every
   one of them.

   On a phone that hint costs more than it saves: these are one-shot entrance
   transitions, and a transition runs perfectly well without pre-promotion. Cleared
   here. The sticky stacks keep their layers, but a sticky element is only promoted
   while it is actually sticking, which is transient; `will-change` never was.
   Desktop is untouched — it has the memory, and there the hint does its job. */
.r,.why-card,.pcard,.case,.tcard,.tstm__card,.hiw__card,.form,.svc,
.tst__left,.tst__card,.swall__track,.sstk__wrap,.upk__c,
.hero__logos-row,.cta__marq-row,.audit,.work__cta,.pricing__honest,
.svc__tile,
/* the two How-it-works layers that were exempted: measured at 13.6 MB on a phone, in the
   one section that was already the heaviest on the page. They transform per frame, which is
   what the hint is for, but not at that price on a device this tight. */
.fsh-card,.fsh-screen{
  will-change:auto;
}
/* `.fsh-screen` and `.fsh-card` KEEP theirs: unlike the rest, those two transform on
   every animation frame while the How-it-works section is scrubbed, which is exactly
   the case the hint is for. Eighteen `.svc__tile` boxes were holding 15.6 MB between
   them for a one-shot entrance. */


}

/* Anyone who has asked their phone to stop animating gets the plain stack: no
   pinning, no marquee. The pile-up is decoration, the content is not. */
@media (max-width:767px) and (prefers-reduced-motion:reduce){
  .why-grid{min-height:0}
  .why-grid .why-card,.sstk__card,.svcstd .tst__card{position:static;top:auto}
  .svcstd .tst__cards{min-height:0}

}
