/* =========================================================================
   mobile-n12.css — the responsive pass, in one place.

   Every section already collapsed to one column and nothing overflowed
   horizontally at any width from 360 to 1920. What was wrong was subtler
   and, on a phone, worse: three competing left edges, a section whose
   entire content had been hidden rather than reflowed, evidence shrunk
   past the point of being evidence, and almost nothing big enough to hit
   with a thumb.

   This loads last and fixes those four things. It does not restyle
   anything that was already working.
   ========================================================================= */

/* ============================ 1. one left edge ============================

   --hx-inset (the sections) and --n12-gutter (the hero) were set
   independently, so on a 390px phone the hero's copy started at 20px, the
   sections at 44px and the footer at 24px. Three edges on a screen too
   narrow to afford one wasted pixel -- 44px of inset is 23% of a 390px
   screen spent on nothing.

   Below the breakpoint where the hero stops being two columns, the inset
   simply follows the gutter. Above it the hero is a split layout whose
   gutter is internal to the panel, which is a different problem, so the
   clamp is left alone. */

@media(max-width:1024px){
  :root{--hx-inset:var(--n12-gutter,32px)}
  .site-footer{padding:18px var(--n12-gutter,32px)}
}

/* On a tablet the hero keeps a real photograph rather than the phone's
   strip, and hero-v1 sizes it at min(560px,70vh). 560 against 744 of
   width is a 1.33 frame, which is squarer than the picture's own 1.5 --
   so it was both taller than it needed to be and cropped harder than it
   needed to be.

   480 fixes the crop and buys back 80px, which the offerings needed:
   pairing their size to the section heads grew them from 26px to 38 here,
   and that had pushed the hero's buttons just past the bottom of an iPad
   mini (1169 of ink against 1133 of screen). Now 1089. */
@media(min-width:641px) and (max-width:1024px){
  .n12-photo{min-height:min(480px,58vh)}
}

/* ====================== 2. the before/after labels ======================

   shift-x.css hid .hx-tab small below 900px, which left four bare numbers.
   "01 02 03 04" is not a summary of anything -- the category names ARE the
   section's content, and the stage below only shows the statements for
   whichever one is live.

   So they come back, stacked under the number instead of beside it, with
   the tracking pulled in enough to fit four across 360px. Stacking also
   takes the tap target from 15px tall to over 44, which it needed anyway.

   The tabs stay in ONE ROW deliberately. A 2x2 grid would fit the labels
   more comfortably, but the sweep times each number from its left offset
   as a fraction of the bar; in two rows those offsets stop increasing and
   the timers collapse onto each other. */

/* Visible from 900 down -- that part has to stay at 900, because that is
   where shift-x.css hides the labels and this is the rule that overrides
   it. STACKED only from 640 down, below. Between the two the labels sit
   beside their number as they do on a desktop, which is right: at 744px a
   quarter of the bar is 186px and "built-in continuity" needs about 171. */
@media(max-width:900px){
  /* 11.5 here, where the labels are inline beside their number on a
     tablet; 10.5 below 640, where they stack in a quarter of a phone. The
     desktop 12px with .17em of tracking does not fit a quarter of 744px --
     "built-in continuity" wants about 179px and has 137. */
  .lf-block .hx-tab small{
    display:block;
    font-size:11.5px;letter-spacing:.05em;line-height:1.25;
  }

  /* Centred, all four, and the statements under them too. On a phone the
     stage stacks and its arrow turns to point straight down the middle --
     once that arrow is centred, everything it connects has to be, or the
     one centred element on the screen looks like the mistake. This is the
     only band on the page that is not set to the left edge, and it earns
     it: it is a symmetrical construct, a pair either side of an arrow. */
  .lf-block .hx-stage .hx-side--b,
  .lf-block .hx-stage .hx-side--a{align-items:center;text-align:center}
  .lf-block .hx-stage{justify-items:center}
}

/* Stacked, and only on a phone. */
@media(max-width:640px){
  .hx-tabs{gap:8px;align-items:stretch}
  .hx-tab{
    flex-direction:column;align-items:center;text-align:center;gap:5px;
    padding:4px 0 8px;min-height:44px;
  }
  /* 10.5, the largest that fits "continuity" -- the longest word of the
     four -- inside a quarter of a 360px screen.

     Each label is two words in two spans, so all four break in the same
     place on every device. Left to the wrap, "more capacity" -- the
     shortest pair -- could fit on one line while the other three took
     two, which reads as one column being wrong rather than as a line. */
  .lf-block .hx-tab small{font-size:10.5px;letter-spacing:.04em}
  .lf-block .hx-tab small span{display:block}
  .hx-tab b{font-size:17px}
}

/* ==================== 3. the proof section, on a phone ===================

   The spine stays. It was hidden here for one pass on the reasoning that
   it is a device for alternating rows and there is nothing to alternate in
   one column -- but that is only true of the alternation. The line itself
   is doing something else: it says these three are one sequence rather
   than three unrelated blocks, and it is the only piece of drawn structure
   on a page that is otherwise columns of text. It runs down the left with
   a node per row, and the scroll still fills it.

   What makes room for it is the order. Each row now reads label, headline,
   PICTURE, explanation, result -- the picture arrives where you have just
   been told what you are about to look at, instead of before it. The
   screenshots go back into rounded, bordered containers, because they are
   pictures of software and should look like it; edge to edge with square
   corners they read as page background.

   The row is a flex column and .tr-body is display:contents, so the five
   pieces sit in one order-able list even though the markup nests four of
   them. The node is taken out of the flow and pinned to the spine. */

@media(max-width:900px){
  .tr-list{margin-top:40px}
  .tr-spine{left:25px}

  .tr-row,
  .tr-row:nth-of-type(even){
    display:flex;flex-direction:column;
    /* stretch, explicitly. The desktop rule is a grid with
       align-items:center, which is right for centring a picture against a
       column of text. Carried into a flex COLUMN it centres on the cross
       axis instead -- every item shrinks to its content and sits in the
       middle, so the three labels started at 68, 120 and 79px. */
    align-items:stretch;
    position:relative;
    padding:30px 0 30px 48px;
    text-align:left;
  }
  .tr-node{
    display:block;position:absolute;left:0;top:36px;
    margin:0;justify-self:auto;align-self:auto;
  }
  /* The tick reaches all the way to the text on a phone, where the gap
     between the spine and the content is a fixed 37px, so it can actually
     connect the two rather than just gesture at them. */
  .tr-node::after,
  .tr-row:nth-of-type(even) .tr-node::after{
    left:100%;right:auto;margin-left:4px;margin-right:0;
    width:28px;
    background:linear-gradient(90deg,var(--lf-accent,#B28479),rgba(178,132,121,.15));
  }
  .tr-body,
  .tr-row:nth-of-type(even) .tr-body{display:contents}

  .tr-label{order:1}
  .tr-claim{order:2}
  /* 20 under, not 4. The caption hangs off the bottom of the figure, so a
     small margin put it hard against the paragraph that follows and the
     two read as one block of text. */
  .tr-figure,.tr-row:nth-of-type(even) .tr-figure{order:3;margin:18px 0 20px}
  .tr-note{order:4}
  .tr-result,
  .tr-row:nth-of-type(even) .tr-result{
    order:5;margin-top:18px;
    border-left:2px solid var(--lf-accent,#B28479);border-right:0;
    padding-left:14px;padding-right:0;
  }

  /* An app, not a background. */
  .tr-shot{
    width:100%;
    border:1px solid rgba(246,241,234,.14);
    border-radius:12px;
  }
  .tr-cap,.tr-row:nth-of-type(even) .tr-cap{
    position:static;margin:10px 0 0;text-align:left;
  }

  /* "the automation" and the client on separate lines. Side by side with a
     middot between them the pair ran to three lines and the break landed
     mid-company-name. */
  .tr-label{line-height:1.35}
  .tr-label span{display:block;margin-top:3px}
  .tr-label span::before{content:none}

  /* One reveal for the whole row. .tr-body is display:contents here, which
     removes its box entirely -- so opacity and transform on it do nothing
     and its children would simply appear. The row is the thing that
     arrives. */
  .rv .tr-figure,.rv .tr-body,
  .rv .tr-row:nth-of-type(even) .tr-figure,
  .rv .tr-row:nth-of-type(even) .tr-body{opacity:1;transform:none;transition:none}
  .rv .tr-row{
    opacity:0;transform:translateY(20px);
    transition:opacity .6s cubic-bezier(.16,1,.3,1),transform .6s cubic-bezier(.16,1,.3,1);
  }
  .rv .tr-row.is-in{opacity:1;transform:none}
}

/* ============= 3b. the testimonial goes after the evidence ==============

   On a phone the quote sat between the section's own subhead and the first
   example, so it read as a claim being made before anything had been
   shown. After the three examples it is what it should be: someone else
   agreeing with what you have just seen.

   .tr-wrap is display:contents so the lede and the quote become items of
   the section itself and can be ordered around .tr-list, which is their
   sibling's sibling. Its padding has to be restated on both children,
   since a display:contents box has none. */

@media(max-width:900px){
  .lf-block.tr{display:flex;flex-direction:column}
  .tr-wrap{display:contents}
  .tr-lede{order:1;padding:0 var(--n12-gutter,20px)}
  .tr-list{order:2}
  .tr-quote{order:3;margin:44px var(--n12-gutter,20px) 0}
}

/* 11.5px was under the 12px floor at every width, not just on phones. */
.tr-cap{font-size:12px}

/* ====================== 4. things you hit with a thumb ==================

   Everything below was under the 44px minimum: the menu button at 28x18,
   the three "find your starting point" links at 21px tall, the about link
   in the proof lede at 20, and both footer links at 14-16.

   The hit area is extended with a pseudo-element rather than by padding
   the elements, because these are underlined text links -- padding them
   to 44px would drag the underline a long way from the words it belongs
   to. This keeps every one of them looking exactly as it does now. */

/* Up to 1024, not 900: a tablet held in portrait is a touch screen, and
   the menu button and the text links are the same size there as on a
   phone. */
@media(max-width:1024px){
  .n12-help,.st-link,.cl-link,.tr-link,.n12-toggle,.hx-tab,
  .pl-btn-text,.pl-outcome-software a,
  .site-footer-built a,.site-footer-meta a{position:relative}
  .n12-help::after,.st-link::after,.cl-link::after,.tr-link::after,
  .n12-toggle::after,.hx-tab::after,
  .pl-btn-text::after,.pl-outcome-software a::after,
  .site-footer-built a::after,.site-footer-meta a::after{
    content:"";position:absolute;
    /* 46, not 44. At exactly 44 the box's own half-pixel centre rounds the
       measurable area to 43 on some of these, which is inside the target
       but outside the requirement. 46 puts it past the rounding. */
    left:-6px;right:-6px;top:50%;height:46px;
    transform:translateY(-50%);
  }
  /* The menu button is 28x18 and sits hard against the right gutter, so
     it gets the pseudo-element too. Padding it to 44 grew the box instead
     of the target and pushed it 13px off the right edge of the screen --
     the only horizontal overflow this page has ever had. */
  .n12-toggle::after{left:-13px;right:-13px;height:48px}

  /* THE FILTER ROWS AND THE ICON LINKS, on the same mechanism.
     Measured at 440: the blog topics are 31px tall, the automation
     filter chips 36, the pricing switch 39, the article's category nav
     27 and the two social icons 21 square. All of them are things you
     tap, and none of them reached 44.

     They take the pseudo-element rather than padding for the reason
     above: padding grows the BOX, which would reflow four chips that
     currently fit on one line, and the target is the only part that
     needs to be bigger. */
  .bl12-filters button,
  .pc-switch button,
  .cs-filter-chip,
  .ct12-social a,
  .post-category-nav a{position:relative}
  .bl12-filters button::after,
  .pc-switch button::after,
  .cs-filter-chip::after,
  .ct12-social a::after,
  .post-category-nav a::after{
    content:"";position:absolute;
    left:-6px;right:-6px;top:50%;height:46px;
    transform:translateY(-50%);
  }
  /* the icons are 21 square, so they need width as well as height */
  .ct12-social a::after{left:-12px;right:-12px}

  /* THE BILLING DISCLOSURE CANNOT USE THE PSEUDO-ELEMENT: its ::after
     is the + / - marker. Padding with a matching negative margin grows
     the target to 44 and leaves the box 28 in layout, so the label
     still lines up with the link beside it. */
  .pc-details summary{padding:8px 0 !important;margin:-8px 0 !important}

  /* THE WORDMARK, which this block had never covered -- the device
     sweep measured it at 40px tall, just under. The nav links beside
     it need nothing: .n12-nav is display:none at every width this
     block applies to, and the menu that replaces it sets its own
     links at full width when it opens. */
  .n12-logo{position:relative}
  .n12-logo::after{
    content:"";position:absolute;
    left:-8px;right:-8px;top:50%;height:48px;
    transform:translateY(-50%);
  }
}

/* ========================= 5. one button layout =========================

   The hero stacked its buttons full-width, the close centred a 205px one,
   and where-to-start left-aligned the same button. Three treatments of the
   identical pair. On a phone they all read the same way. */

@media(max-width:640px){
  /* Side by side, the way they sit on a desktop, and left with the copy.

     Fitting the pair on one row inside 320px (a 360px screen) is tight:
     the button was 230px minimum and the link is 184, which is 30px over
     before any gap. The button drops its floor and some horizontal
     padding, and both come down a point. flex-wrap stays on as the safety
     net -- if a narrower screen or a larger text setting ever does run
     them out of room, they stack rather than spill off the edge. */
  .n12-actions,.st-actions,.cl-actions{
    flex-direction:row;align-items:center;justify-content:flex-start;
    flex-wrap:wrap;gap:14px 13px;
  }
  .cl-actions{align-self:stretch}
  .st-foot{display:block;padding-top:34px}
  /* All three at .lf-block specificity, not just the hero's.

     shift-anim pins .lf-block .n12-cta, and cta-n12.css pins
     .lf-block .st-btn and .lf-block .cl-btn -- so a bare .st-btn here
     could not reach them. The hero button took the 14.5px and the other
     two stayed on the desktop 17.5, which is why the first one on the page
     was a different size from the rest. 161x43 against 188x46.

     League Spartan here and Questrial on the desktop: at this size it is
     the weight that reads, not the letterform. */
  /* .pl-btn-primary and .pl-btn-text are in here because cta-n12.css
     defines them beside these three on the desktop -- one button
     wherever it is -- and the phone step was the one place the planning
     page had been left out. It was Questrial 16 on a 26px inset beside
     the home page's League Spartan 14.5 on 15. */
  .n12-cta,.st-btn,.cl-btn,.pl-btn-primary,.sw-btn--primary,
  .lf-block .n12-cta,.lf-block .st-btn,.lf-block .cl-btn{
    width:auto;min-width:0;
    padding:14px 15px;font-size:14.5px;
    font-family:'League Spartan',sans-serif;letter-spacing:-.01em;
    justify-content:center;
  }
  /* 13.5px is the phone size for EVERY text CTA, secondary and tertiary
     alike. Audited at 390 across the three pages and three were missing
     from this list, so they stayed at their desktop 16 and read a size
     larger than the ones beside them:

       .swx-fit-foot--links a   the three column links
       .tr-link                 home's why-we-built
       .n12-cta-3               the proof band's more-about
       .swx-build-link          the add-on links

     The primaries are already uniform: 14.5px, 700, 43px tall on all
     three pages. */
  /* SIZE for all of them; align-self for only some.

     align-self:center belongs to the CTAs that sit in a ROW beside a
     primary -- those rows stack at this width and the pair centres
     together. It does not belong to the ones that sit under copy inside
     a column, and putting .st-more in this list centred home's three
     "see how it works" links while the paragraphs above them stayed
     left. The list below is split accordingly. */
  .n12-help,.st-link,.cl-link,.pl-btn-text,.sw-btn--text,
  .pl-fail-link a,.pl-why-link a,
  .swx-fit-foot--links a,.tr-link,.n12-cta-3,.swx-build-link,.st-more,
  .lf-block .n12-help{font-size:13.5px}
  .n12-help,.st-link,.cl-link,.pl-btn-text,.sw-btn--text,
  .lf-block .n12-help{align-self:center}
  /* and the ones under copy stay where their copy starts */
  .st-more,.tr-link,.n12-cta-3,.swx-build-link,
  .pl-fail-link a,.pl-why-link a{align-self:flex-start}
  /* The arrow scales with the type it sits beside. */
  .n12-help svg,.st-link svg,.cl-link svg,.sw-btn--text svg,
  .pl-fail-link a svg,.pl-why-link a svg,.swx-fit-foot--links a svg,
  .tr-link svg,.n12-cta-3 svg,.swx-build-link svg,
  .st-more svg{width:16px;height:14px}
  .n12-help span,.st-link span,.cl-link span,.pl-btn-text span,.sw-btn--text span{margin-left:-2px}
}

/* ======================= 6. the hero, on a phone =======================

   The frame was 480px tall with the desktop crop, which on a phone meant a
   band of empty sky at the top, the car small in the middle, and a long
   run of dune underneath it. Shorter, and pulled in, so the car fills the
   frame and the bottom edge lands about where the sand starts coming off
   the wheels -- which is where the panel and the buttons now begin. */

@media(max-width:640px){
  /* A strip, and everything under it inside the first screen.

     220px tall at 390 wide is a 1.77:1 box, but the photograph is 1.5:1 --
     WIDER than the source. So `cover` would scale to the width and show
     almost the whole frame, sky and all, just squashed into a band. The
     only way to get the car alone is to zoom past cover: the background is
     sized to 150% of the width, which makes the image 585px wide and 389
     tall behind a 220px window, so the window shows 57% of the height and
     the crop picks which 57%. Tighter than this (185%) and the car's nose
     runs off the right edge.

     The strip's HEIGHT is set further down, in the block that balances the
     hero against the fold, because it has to move whenever the panel's
     contents do. It used to be repeated here at 220px and silently lost to
     that one. */
  .n12-photo::before,.n12-photo-sky,.n12-photo-glow{
    background-size:150% auto;
    background-position:55% 44%;
  }
  /* The sky layer's fade is measured against the old 480px frame; over
     220px it would wash out the whole strip. */
  .n12-photo-sky{
    -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.5) 34%,transparent 62%);
    mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.5) 34%,transparent 62%);
  }

  /* The three offerings are the hero's content, not a list under it: on
     desktop each is a full-width statement you click. They get the room to
     read that way here too -- 26px rows are the desktop padding, and the
     titles come up to 28px.

     The eyebrow gets its margin back. It was zeroed to claw back height
     and sat 0px off the first offering, where desktop gives it 44 -- so
     the eyebrow read as a label attached to "one-page business plan"
     rather than as a line about the company. */
  /* 34, up from 26, so the gap between titles goes 53 -> 69 and each
     offering reads as its own statement rather than a row in a list.

     34 is the ceiling, not a preference. The hero has to end inside a
     phone's usable viewport, around 745px: at 34 the button's bottom edge
     lands at 736, at 38 it is 760 and under the fold. More than this has
     to come off the photograph -- 40px of padding with the strip cut to
     168 also fits, but that is 38px of picture for 12px of air. */
  .lf-block .n12-services a{padding-top:34px;padding-bottom:34px}
  /* 30, now that the rows have the height to carry it. The titles are the
     hero's content on a phone -- they are what you read after the
     photograph. Their SIZE is set with the section heads further down, as
     a ratio of them, so the two cannot drift apart. */

  /* The claim moves UNDER the offerings.

     Above them it was the first thing on the panel, alone, with 76px over
     it and 34 under -- which frames a 10.5px tracked uppercase line as a
     heading and makes you read it before the three things it is supporting.
     On a desktop it recedes because the offerings sit beside it in a much
     bigger block; stacked, nothing outranks it.

     Underneath, it does the job it was written for: a credibility line
     directly above the ask. The offerings lead, which is what they are for.

     The panel becomes a flex column so order can move it without touching
     the markup, which the desktop layout still depends on. */
  .lf-block .n12-panel{display:flex;flex-direction:column}
  .lf-block .n12-services{order:1}
  /* The claim now belongs to the ask, so it sits close to the buttons and
     the pair is separated from the offerings: 60 above it, 18 below.

     And it stops being a label. Uppercase, bold, tracked out, it carried
     more visual weight than the cream button underneath it -- which is the
     wrong way round however it is positioned. Set as a note instead:
     sentence case in the body face, italic, smaller, dimmer. The one thing
     it keeps is enough contrast to read (4.95:1 on this ground).

     NOTE: Questrial ships no italic, so this is a synthetic oblique -- the
     browser slanting the roman. At 13px in one short line that is fine;
     it is the same limitation that made the CTA's bold look weak, and
     worth knowing rather than discovering. */
  .lf-block .n12-claim{
    order:2;margin:34px 0 0;
    font-family:'Questrial',sans-serif;
    font-size:13px;font-weight:400;font-style:italic;
    text-transform:none;letter-spacing:0;line-height:1.5;
    color:rgba(246,241,234,.5);
  }
  .n12-actions{order:3;padding-top:18px}

  /* The toggle was three 28px bars against a wordmark that is 52px here,
     not the 34 hero-v1 asks for -- shift-anim sets .lf-block .n12-logo at
     a specificity the plain class cannot reach. So it was less than half
     the height of the thing it balances.

     Bigger, and aligned on the wordmark's OPTICAL centre, which is NOT
     its line box. Measured off the font metrics: the line box runs 26..78
     so its centre is 52, but the glyphs only run 29..65 -- "next 12." has
     no descenders, so the box carries 13px of empty space underneath and
     anything centred against it sits low. The ink centre is 47. The
     toggle is 27px tall and its centre needs to come up 5px.

     -10, not -5: the toggle is centred by align-items, and alignment
     accounts for margins, so a negative top margin moves the centre by
     HALF its value. -5 closed 6px of offset to 2.5, not to 0. */
  .n12-toggle{gap:9px;margin-top:-10px}
  .n12-toggle span{width:38px;height:3px}

  /* THE WORDMARK, BACK UP TO 44. hero-v1 sets 34 at this width, and the
     comment above is now stale: it describes a 52px wordmark held by
     shift-anim's higher-specificity rule, which no longer reaches here --
     measured, all four pages render 34. So the toggle has been balancing
     a wordmark less than three quarters the size it was tuned against,
     which is what she noticed.

     44 rather than back to 52: the toggle's bars are 38px wide, and at
     52 the wordmark ran 123px of a 390px screen with the burger crowding
     it. -8 rather than -10 on the toggle for the same reason the -10 was
     chosen -- the wordmark has no descenders, so its ink centre sits
     about 4px above its line box centre at this size, and alignment
     halves a margin. */
  .n12-logo{font-size:44px}
  .n12-toggle{margin-top:-8px}
}

/* ==================== 7. type: the claim and the heads ==================

   The claim ran to two lines with "businesses" alone on the second, which
   is the worst possible break for a single line of tracked uppercase. It
   is sized off the viewport now so it fits on one line from 320px up, and
   the tracking comes in because tracking is what was costing the room. */

@media(max-width:900px){
  /* The claim's size and tracking used to be set here, to squeeze a line
     of tracked uppercase onto one line. It is a sentence-case note now and
     is styled with the rest of the hero above -- a viewport clamp here
     would just override that, which it did: 10.5px instead of 13. */

  /* The section heads were clamping to their 26px floor on every phone,
     which put them barely above the body copy. They are the only signpost
     a reader gets while scrolling; they should be unmistakably bigger. */
  /* One variable for both, because they have to keep a relationship.

     The heads were on a vw clamp and the hero's offerings on a fixed px
     per height tier, so the two drifted apart: the head grew with the
     screen and hit its 34px ceiling while the offering stayed at 30, and
     on a Pro Max the offerings -- the hero's actual content, the things
     you tap -- ended up 4px SMALLER than a section signpost. They were
     under on every phone: -1.5 at 360, -2.2 at 393, -3.8 at 375x667.

     Now the tiers only move --n12-mhead and the ratio holds everywhere. */
  :root{--n12-mhead:clamp(29px,8.2vw,34px)}
  .lf-block .hx-head,
  .st-head,.tr-head,.cl-head{font-size:var(--n12-mhead)}
  .lf-block .n12-services strong{font-size:calc(var(--n12-mhead) * 1.12)}
  /* and the numeral's box tracks it, for the same reason it does in
     shift-anim.css: it is centred in a box one title-line tall, so that
     box has to follow whatever the title's size turns out to be */
  .lf-block .n12-services b{height:calc(var(--n12-mhead) * 1.12 * .95)}
}

/* ================== 8. one vertical rhythm for the bands ================

   Measured on a phone the four bands below the hero were 135/135, 84/78,
   118/118 and 72/72 -- every one different, and the first nearly twice the
   last. One value for all of them. */

@media(max-width:900px){
  .lf-block .hx{padding-top:76px;padding-bottom:76px}
  .st{padding:76px 0}
  .lf-block.tr{padding:76px 0}
  .cl{padding:76px 0}
}

/* ===================== 9. fewer lines on a phone ========================

   Stacked, the three offerings were separated by a full-width rule each,
   and with the section divider and the tab underline above them the screen
   had four horizontal lines in a row. The space between the columns is
   already doing the separating. */

@media(max-width:980px){
  /* The rule moves from inside each offering to the END of it.

     Stacked, a rule between the bullets and the price sits mid-card, and a
     horizontal line across a single column reads as the end of one thing
     and the start of the next -- so the price and the link looked like the
     opening of the offering below rather than the close of the one above.
     Moved to the bottom edge, it does what it looked like it was doing.
     (This is the same line I removed from between the offerings a pass
     ago; the position was the problem, not the line.) */
  /* Stacked, there is nothing to align across and no auto to guard
     against, so the paragraph's floor comes off and the gap is just the
     14px here. */
  .st-cost{border-top:0;padding-top:0;margin-top:14px}
  .st-body{margin-bottom:0}
  .st-col{
    padding-top:38px;padding-bottom:38px;
    border-top:0;
    border-bottom:1px solid var(--n12-line);
  }
  /* No rule under the last one. It sat immediately above the section's own
     buttons, so it read as separating them from the offerings when they
     are the thing the offerings lead to. */
  .st-col:last-of-type{border-bottom:0}
}

/* ====================== 10. the testimonial, quieter ====================

   Full width, tinted, with a 4px rule down one side, it read as a panel
   dropped into the middle of the section rather than as something someone
   said. On a phone it loses the fill and the heavy edge and keeps a
   hairline, which is enough to mark it as a quote. */

@media(max-width:900px){
  /* No fill and no heavy edge. It had a clay bar down the left for a
     while, which was removed further down because it sat 20px from the
     spine running the same way -- so it is simply not drawn here any
     more, rather than drawn and then undrawn. */
  .tr-quote{
    background:none;
    border-right:0;
    border-left:0;
    padding:2px 0;
  }
  /* 21px, up from 17. The attribution is bold, uppercase and tracked out,
     which is a lot of weight for 12px -- against a 17px quote it was
     winning, and the quote is the thing somebody said. The quote goes up
     and the name comes down to 10.5 with the tracking pulled in, so the
     gap between them is about 2:1 instead of 1.4:1.

     The colour stays at .52. Dimming it further is where it fails contrast
     at this size: .44 measures 4.3:1 against this ground. */
  .tr-quote cite{justify-content:flex-start;margin-top:14px}
}

/* The size pair is a PHONE ratio and belongs below 640. Between 640 and
   900 the quote is on the desktop clamp at 18px, so a 10.5px attribution
   under it was both out of proportion and under the 12px floor. */
@media(max-width:640px){
  .tr-quote p{font-size:21px;line-height:1.32}
  .tr-quote cite{font-size:10.5px;letter-spacing:.12em}
}

/* ========================= 11. the footer, quieter ======================
   13px for a build credit and a privacy link is louder than the page above
   it needs at the very bottom of a phone screen. */

/* Phones only. A tablet has the room for the desktop 13px, and 11.5 there
   was just small text for no reason. */
@media(max-width:640px){
  .site-footer-built,.site-footer-meta{font-size:11.5px}
}

/* ===================== 11b. the menu, full screen ======================

   It was a 420px drawer sliding out of the masthead, which on an 844px
   screen leaves half the hero showing underneath and reads as a dropdown
   on top of the page rather than as a change of place.

   Now it takes the whole viewport: the links get room to be the only thing
   you are looking at, sized to be tapped rather than aimed at.

   Animating max-height to 100vh cannot be transitioned smoothly and would
   jump, so the panel is always full height and slides in on transform
   instead -- which is composited, so it is smooth on a phone. visibility
   keeps it out of the tab order while it is closed, and it transitions
   discretely at the end so it is not hidden mid-slide. */

@media(max-width:1024px){
  .n12-menu{
    position:fixed;inset:0;
    top:0;left:0;right:0;
    z-index:60;
    max-height:none;height:100%;
    overflow-y:auto;
    display:flex;flex-direction:column;justify-content:center;
    gap:2px;
    padding:96px var(--n12-gutter,20px) 40px;
    background:#090707;
    /* IT FADES, IT DOES NOT SLIDE.

       This ran transform:translateY(-100%) -> 0, a panel dropping in from
       above the fold. next12.ca does not do that and she does not want
       it: measured on the live old site, its mobile menu is position
       fixed over the whole viewport with NO transform at all, appearing
       by opacity and visibility alone.

       visibility is still doing the same job it did before -- keeping the
       panel out of the tab order and out of the way of taps while it is
       closed -- and still switches discretely at the end of the fade
       rather than part-way through it. Only the movement is gone. */
    opacity:0;
    visibility:hidden;
    transition:opacity .24s ease,visibility 0s linear .24s;
  }
  .is-menu-open .n12-menu{
    max-height:none;
    opacity:1;
    visibility:visible;
    transition:opacity .24s ease,visibility 0s linear 0s;
  }
  .n12-menu a{
    border-top:0;
    padding:15px 0;
    /* EXPLICITLY LEFT, because text-align inherits and the three heroes
       do not agree. .sw-hero-simple is text-align:center and the menu's
       markup lives inside it, so on the software page every link centred
       while home and planning -- whose heroes are start -- stayed left.
       One shared rule, three different results, and nothing in the menu's
       own CSS to show why. */
    text-align:left;
    font-family:'League Spartan',sans-serif;
    font-weight:700;letter-spacing:-.02em;text-transform:lowercase;
    font-size:clamp(26px,7.5vw,34px);
    line-height:1.05;
    color:var(--n12-cream);
  }
  /* The toggle has to stay above the panel and keep working as the close. */
  .n12-head{z-index:70}

  /* THE PHONE BAR: 56px, logo and button, nothing else. The nav is
     already display:none here, so the stuck state is only a question
     of height and of how far the wordmark comes down -- 52px of logo
     in a 56px bar leaves no bar. safe-area padding because on a
     notched phone in landscape the left inset is real and the
     wordmark would otherwise sit under the cutout. */
  .n12-head.is-stuck{
    height:56px;
    padding-left:env(safe-area-inset-left,0px);
    padding-right:env(safe-area-inset-right,0px);
  }
  .n12-head.is-stuck .n12-logo{font-size:30px}
  /* AND THE BUTTON COMES DOWN WITH IT. The wordmark shrinks from 52 to
     30 in the stuck bar and the hamburger did not move, so at 28x22 it
     was suddenly the largest thing in a 56px strip. 22x17 keeps the
     same proportion to the mark it had at rest.

     The 48px tap target is unaffected -- it is the ::after pseudo
     further up this file, which is sized in absolute pixels and does
     not care how big the bars are. */
  .n12-head.is-stuck .n12-toggle{gap:5px}
  .n12-head.is-stuck .n12-toggle span{width:22px;height:2px}
  .n12-toggle{transition:gap .22s ease}
  .n12-toggle span{transition:width .22s ease,transform .3s cubic-bezier(.33,1,.68,1),opacity .18s ease}
  /* the X still has to close: the bars are 2px on a 5px gap in the
     stuck bar, so their centres are 7px either side of the middle */
  .is-menu-open .n12-head.is-stuck .n12-toggle span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .is-menu-open .n12-head.is-stuck .n12-toggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

  /* NO SCROLLING BEHIND THE MENU. The panel is fixed and full screen,
     so without this the page underneath scrolls while the menu is
     open and you close it somewhere else entirely. */
  html.is-menu-locked,
  html.is-menu-locked body{overflow:hidden}
  /* and the header never hides itself while the menu is open */
  .is-menu-open .n12-head.is-away{transform:none}

  /* THE HEADER STRIP MUST NOT BE TRANSLUCENT OVER THE MENU.

     .is-stuck gives the masthead rgba(12,10,10,.93) and a 12px
     backdrop-filter, and the header sits at z-index 70 against the
     menu's 60 -- so with the menu open, the top 64px of a full-screen
     panel is a 93%-opaque bar BLURRING WHAT IS BEHIND IT. On iOS a
     backdrop-filter samples the page, not the fixed panel in front of
     it, which is why the strip reads as see-through, and why it only
     happens after scrolling up: that is the one state where the header
     is stuck and visible at the same time as the menu.

     Open, the bar takes the panel's own colour flat and the blur comes
     off. There is then nothing behind it to show through. */
  .is-menu-open .n12-head.is-stuck,
  .is-menu-open .n12-head{
    background:var(--n12-menu-bg, #090707) !important;
    -webkit-backdrop-filter:none !important;
    backdrop-filter:none !important;
    border-bottom-color:transparent !important;
  }

  /* ...and it has to LOOK like a close. Three bars over a full-screen
     panel give no clue that the same control dismisses it. The outer two
     rotate into an X and the middle one goes; the bars are 3px on a 9px
     gap so their centres are 12px either side of the middle, which is the
     distance each has to travel. */
  .n12-toggle span{
    transition:transform .3s cubic-bezier(.33,1,.68,1),opacity .18s ease;
  }
  .is-menu-open .n12-toggle span:nth-child(1){transform:translateY(12px) rotate(45deg)}
  .is-menu-open .n12-toggle span:nth-child(2){opacity:0;transform:scaleX(.4)}
  .is-menu-open .n12-toggle span:nth-child(3){transform:translateY(-12px) rotate(-45deg)}
}

@media(prefers-reduced-motion:reduce){
  .n12-menu{transition:none}
  .n12-toggle span{transition:none}
}

/* ================ 12. the where-to-start ground, on a phone =============

   The landscape is 2000x669, a 3:1 frame. The band on a phone is roughly
   390x1480 -- 1:3.8. Under `cover` that showed about 9% of the picture's
   width, which is not a photograph any more, it is a texture. The portrait
   version is 887x1774, so cover fills the height and crops to the middle
   53% instead. */

@media(max-width:640px){
  .st-bg::before{
    background-image:image-set(url("/assets/images/home-start-desert-mobile.avif") type("image/avif"),url("/assets/images/home-start-desert-mobile.webp") type("image/webp"));
    background-position:center center;
  }
}

/* ============== 13. the last of the mobile margin cleanup ============== */

@media(max-width:900px){
  /* The quote had a clay bar down its left edge, 20px from the spine
     running down the same side. Two vertical accent lines that close
     together read as a mistake. The text is already in quotation marks
     and already clay; it does not need a third signal. That is now done
     where the quote is styled, above, rather than undone here. */

  /* Equal top and bottom on the row block, measured in ink: 18 of grid
     margin plus the column's own 38 is 56 from the subhead to the first
     label, and the same 38 plus 18 of foot padding is 56 from the last
     link to the buttons. (It was 46 and 72.) */
  .st-grid{margin-top:18px}
  .st-foot{padding-top:18px}
}

@media(max-width:640px){
  /* 76/76, the same as every band below it -- so the black panel's top and
     bottom margin matches the before/after section's exactly.

     That costs 40px of height and pushes the hero to 801px, which is past
     a phone's usable viewport by roughly the panel's bottom padding: the
     button's bottom edge lands about at the fold rather than comfortably
     inside it. The alternative was keeping 56 and having this be the one
     band on the page with its own rhythm. Matching won.

     NOTE: these two properties are also set in the hero block above. Both
     are @media(max-width:640px) at the same specificity, so the LAST one
     wins -- which is here. Change them here. */
  /* 248, up from 206. At 206 the wordmark floated over open sky; at 248 the
     dune ridge runs directly beneath it, and the whole vehicle is in frame
     rather than clipped at the roof. The three offerings still finish at
     736 of 852 on a 393px phone, so nothing falls below the fold. The two
     short-phone tiers below move with it. */
  .n12-photo{min-height:248px}
  /* 42 and 76, which is 76 and 76 in INK.
     The first offering row carries its own padding above its title, so 76
     of panel padding put 102px between the photograph and the first word
     against 76 under the last button. Equal padding was not equal margin.
     42 + the row's 34 = 76 at the top, and the bottom needs no correction
     because the button has no padding under it.

     This tracks the row padding: it was 50 when the rows were 26. If that
     changes again, change this too. */
  .lf-block .n12-panel{padding-top:42px;padding-bottom:76px}

  /* Left, like everything above it. Centring is what marks the close as
     the end of the reading on a wide screen, where the whole page is set
     against a left edge it can break from. On a phone nothing has a left
     edge to break from -- every band is nearly full width -- so centring
     stops being a signal and just rags both sides of a 350px measure. */
  .cl-wrap{align-items:flex-start;text-align:left}
  .cl-sub{margin-left:0;margin-right:0}
  /* align-items is the CROSS axis and this row is horizontal, so
     flex-start here would top-align the button against the link rather
     than left-align anything -- which is not what it was for. Left comes
     from justify-content, which the row already sets. */
  .cl-actions{justify-content:flex-start}
}

/* ============== 14. the hero on a SHORT phone, and sideways =============

   THIS BLOCK MUST STAY LAST. The hero's height is set in section 13 above
   at plain @media(max-width:640px). These queries are no more specific
   than that one -- adding a height condition does not raise specificity --
   so the only thing deciding the winner is source order. When they sat
   above section 13 the photograph and panel values here were simply
   discarded: an iPhone SE was still getting the 206px strip and 42/76
   panel meant for a tall screen, and only the row and title reductions
   below were taking effect.

   Why it is needed at all: the hero is tuned against height as well as
   width, to land the buttons inside the viewport. 815px works for an
   iPhone 16 (852), a Pro Max (956) and a Pixel 8 (915). It did not work
   for the short ones --

     iPhone SE     375x667   ink ended 768, 101px past the fold
     Galaxy S23    360x780   ink ended 800,  20px past

   -- and width alone cannot tell them apart, because the SE is WIDER than
   a Galaxy S23 and 113px shorter. Two tiers, since one compromise that
   fits 667px would leave a 956px screen looking starved. */

@media(max-width:640px) and (max-height:840px){
  .n12-photo{min-height:228px}
  .lf-block .n12-panel{padding-top:36px;padding-bottom:64px}
  .lf-block .n12-services a{padding-top:28px;padding-bottom:28px}
  /* Heads and offerings both come down, together. A shorter screen wants
     smaller type throughout; shrinking only the offerings would put them
     back under the section heads, which is the problem this whole pairing
     exists to prevent. */
  :root{--n12-mhead:clamp(27px,7.7vw,31px)}
  .lf-block .n12-claim{margin-top:26px}
  .n12-actions{padding-top:22px}
}

@media(max-width:640px) and (max-height:720px){
  .n12-photo{min-height:205px}
  .lf-block .n12-panel{padding-top:30px;padding-bottom:52px}
  .lf-block .n12-services a{padding-top:22px;padding-bottom:22px}
  :root{--n12-mhead:clamp(26px,7.2vw,29px)}
  .lf-block .n12-claim{margin-top:22px}
  .n12-actions{padding-top:20px}
}

/* Sideways is its own problem: a 393px-tall viewport cannot hold a
   photograph, three offerings and two buttons, and pretending otherwise
   would shrink all of them to nothing. The strip gets out of the way and
   the page scrolls, which is what anyone turning a phone expects. */
@media(max-width:1000px) and (max-height:520px) and (orientation:landscape){
  .n12-photo{min-height:min(200px,52vh)}
  .lf-block .n12-panel{padding-top:28px;padding-bottom:36px}
  .lf-block .n12-services a{padding-top:18px;padding-bottom:18px}
  /* Sideways the screen is wide and shallow, so a width-driven clamp
     reads the 852px as "lots of room" and sizes the type for a tablet:
     38px titles in a 393px-tall viewport. Held down to the width here. */
  :root{--n12-mhead:clamp(24px,3.2vw,30px)}
}

/* =========================================================================
   CTA PAIRS, ONE SHAPE, EVERY PAGE.

   Audited all nine pages plus the project modal at 390. Three already
   did the right thing -- pricing, blog and about stack the pair in a
   column with the primary at full width and the secondary centred under
   it, every centre landing on 195, the middle of the screen.

   The other four did not, and each was wrong differently:

     planning  .pl-plan-actions   still a ROW at 390: a 161px button and
                                  a 113px link side by side at 43 and 31
                                  tall, neither centred
     software  .swx-ctas          a row that WRAPPED, so it looked
                                  stacked while being laid out as a row:
                                  centres at 118 and 287 against a screen
                                  centre of 195. This is the one she saw
     ideas     .cs-cta-actions    wrapped row at justify:flex-start, so
                                  both sat hard left
     modal     .cs-modal-foot-actions  the same, inside the dialog

   SIDE BY SIDE IS NOT AVAILABLE AT THIS WIDTH, which is worth writing
   down because it was the first thing asked for in the modal: "book a
   15-minute call" measures 205px and "download the free checklist"
   181px. That is 386px of content plus a gap into 350px of usable
   width. They fit only by shrinking the type under what every other CTA
   on the site uses -- and matching the other CTAs was the other half of
   the request.

   So: the standard, everywhere. Column, 16px gap, primary fills the
   measure and centres its own label, secondary centres under it.
   ========================================================================= */
@media(max-width:700px){
  /* HOME IS THE REFERENCE, AND HOME IS A ROW.

     Measured at 390: the home page puts its pair side by side -- a
     161x43 filled button that hugs its own label at 14.5px, then a
     150px text link beside it at 13.5. 161 + 13 of gap + 150 is 324
     into 350px of usable width, so it fits, comfortably.

     Everything else had been standardised to a COLUMN with a 280px
     primary, which is the opposite of the reference. And they were not
     even consistent with each other: 280 on software, about and
     automation, 350 on pricing, 312 on contact, and three different
     type sizes across them -- 14.5, 15 and 16.

     So: the row, everywhere. The primary hugs its label instead of
     filling the measure, which is what makes the pair fit; the
     secondary sits beside it.

     flex-wrap:wrap rather than nowrap, because one pair on the site
     genuinely cannot fit: the automation modal's "book a 15-minute
     call" and "download the free checklist" measure 205 and 181, which
     is 386px of label into 350. That one wraps to two rows and still
     looks like the others. Everything else stays on one line.

     justify-content is NOT set. Home's band is left-aligned and the
     about and blog closers are centred; the alignment belongs to the
     band, and what is being standardised here is the buttons. */
  .pl-plan-actions,
  .swx-ctas,
  .cs-cta-actions,
  .cs-modal-foot-actions,
  .pr12-hero-actions,
  .pc-finder-actions,
  .bl12-close-actions,
  .ab12-close-actions{
    display:flex !important;
    flex-direction:row !important;
    align-items:center !important;
    gap:14px 13px !important;
    flex-wrap:wrap !important;
  }

  /* THE PRIMARY HUGS ITS LABEL. width:auto is the whole change -- the
     280px cap is what forced the column in the first place. 43px and
     14.5px are home's numbers. */
  .pl-plan-actions .pl-btn-primary,
  .swx-ctas .sw-btn--primary,
  .cs-cta-actions .btn,
  .cs-modal .cs-modal-foot-actions .btn,
  .cs-modal .cs-cta-actions .btn,
  .pr12-hero-actions .btn,
  .pc-finder-actions button,
  /* THE PRICING CLOSE IS ONE BUTTON ON A PHONE, and this is it. The
     panel's heading, its sentence and the outlined "find your starting
     point" are all hidden below 700 -- see pricing-n12.css -- so the
     call is no longer the quieter of a pair, it is the only thing
     there. It moved up here out of the secondary list below. */
  .pc-finder-actions .pc-finder-call,
  .ab12-close-actions .btn,
  .auto-hero-actions .auto-btn--primary,
  .bl12-close-actions .bl12-finder-btn{
    display:inline-flex !important;
    align-self:center !important;
    align-items:center !important;
    justify-content:center !important;
    width:auto !important;max-width:100% !important;
    min-height:44px !important;
    padding:12px 18px !important;
    /* THE FACE, NOT JUST THE SIZE. This block has been standardising the
       geometry and leaving each page's own font-family alone, so the
       automation hero's primary came out Questrial 16/700 against
       home's League Spartan 14.5/700 -- a different typeface for the
       same button. Home is the reference, so home's face is set here. */
    font-family:'League Spartan',sans-serif !important;
    font-weight:700 !important;
    font-size:14.5px !important;
    text-align:center !important;
  }

  /* AND THE PRICING FINDER IS FILLED HERE. On a desktop it is
     deliberately outlined -- the panel's whole sentence is about not
     knowing which service you need, so the tool is the quieter of the
     two. On a phone the reference is home's pair, and home's primary is
     a solid cream button; one page having an outlined primary is the
     kind of difference that reads as a bug. */
  .pc-finder-actions button,
  .pc-finder-actions .pc-finder-call{
    background:var(--pr-cream) !important;
    border-color:var(--pr-cream) !important;
    color:var(--pr-ground-dark) !important;
  }
  .pc-finder-actions button svg{stroke:var(--pr-ground-dark) !important}
  /* the call carried a bottom border as a text link; as a filled button
     it does not, and its link padding goes with it */
  .pc-finder-actions .pc-finder-call{
    border-bottom:0 !important;padding-bottom:12px !important;
  }
  .pc-finder-actions .pc-finder-call:hover{color:var(--pr-ground-dark) !important}

  /* and the secondary beside it, at the size home sets */
  .pl-plan-actions .pl-btn-text,
  .swx-ctas .sw-btn--text,
  .cs-cta-actions .n12-cta-3,
  .cs-modal .cs-modal-foot-actions .n12-cta-3,
  .cs-modal .cs-cta-actions .n12-cta-3,
  .pr12-hero-actions .n12-cta-3,
  .ab12-close-actions .n12-cta-3,
  .auto-hero-actions .auto-btn--text,
  .bl12-close-actions .n12-cta-3{
    display:inline-flex !important;
    align-self:center !important;
    align-items:center !important;
    width:auto !important;
    min-height:44px !important;
    /* home's secondary: Questrial 13.5 regular */
    font-family:'Questrial',sans-serif !important;
    font-weight:400 !important;
    font-size:13.5px !important;
  }

  /* AND THE 4px NUDGE STAYS. The software page's text CTA carries
     transform:translateX(4px) as an optical correction for sitting
     beside a bordered button -- which is exactly where it sits again
     now. It only had to come off while the pair was stacked. */

  /* ===================== ONE HERO TOP, AND IT IS 110 =====================
     Every page put its first line at exactly 128px, which left 58px of
     empty screen between the bottom of the logo and the eyebrow. On a
     phone that is a tenth of the viewport spent on nothing before the
     page says what it is. 110 leaves 40, which still clears the
     masthead comfortably.

     Eight files set this number, one of them (software) with
     !important, so this is written once here at (0,1,2) rather than
     edited in eight places and drifting apart again the next time one
     of them is touched. */
  html body .pl-hero-wrap,
  html body .sw-hero-simple,
  html body .auto-hero,
  html body .pr12-hero,
  html body .bl12-hero,
  html body .ab12-hero,
  html body .ct12-hero,
  html body .lg12-head{padding-top:110px !important}

  /* ================== NO ONE-WORD LAST LINES ==================
     A phone is narrow enough that a headline regularly breaks with a
     single word stranded on its own line, which is the thing that makes
     a page look unconsidered however good the rest of it is.

     `balance` tells the browser to even out the lines of a short block
     rather than filling greedily and dumping the remainder -- it is
     meant for headings, and it caps out around six lines, which every
     headline here is well inside. `pretty` is the version for running
     text: it only works the last few lines, so it costs nothing on a
     long paragraph and still refuses to leave one word alone.

     Both degrade to normal wrapping where they are not supported, so
     there is nothing to guard. */
  h1, h2, h3, h4,
  .n12-eyebrow, [class*="-eyebrow"],
  .bl12-card h3, .bl12-feature h2,
  .pc-card h2, .cs-title, .cs-workflow-step strong{
    text-wrap:balance;
  }
  p, li, .bl12-excerpt, .cs-featured-lede, figcaption{
    text-wrap:pretty;
  }
}
