/* =========================================================================
   software-n12.css — the software page on the home page's terms.

   Loads last, after software.css, and does the same job planning-n12.css
   does for the planning page: it does not redesign anything, it maps what
   is there onto one palette, one type scale, one gutter and one rhythm.

   What it had to change, measured against the home page at 1440 and 393:

     ground      #2C2523 / #2C292A / #211E1F   ->  #000 / #0F0D0C / #171413
     cream       #FBF6F0                       ->  #F6F1EA
     h1          58px flat                     ->  clamp(40px,4.4vw,56px)
     h2          38/41                         ->  clamp(26px,2.65vw,38px)/1.04
     eyebrow     14px, .22em, #E0D2C5          ->  12px, .17em, clay
     body        16/1.6 at .72                 ->  15/1.6 at .68
     buttons     14px, its own pair            ->  the shared .n12 pair
     column      min(1160px, 100% - 48px)      ->  full width on --hx-inset
     rhythm      129/86, 0/0, 76/76, 82/126    ->  118/118 and 76/76

   The browns were the biggest single thing. site.css set --ink #332C2A and
   --cream #FBF6F0 -- a warm brown ground and a warmer cream than the rest
   of the site -- so every band on this page was a couple of degrees off
   every band on the other two, in a way that is invisible on one page and
   obvious the moment you move between them.
   ========================================================================= */

/* --------------------------- what site.css used to do --------------------
   hero-v1.css brings the reset, but not these two, and the page was
   getting them from site.css. */
h1,h2,h3{margin:0}
img{max-width:100%;display:block}

/* --------------------------------- the shell ----------------------------
   hero-v1.css gives the masthead at 42px and a 13.5px nav; on the home page
   shift-anim raises those to 52 and 15 inside .lf-block, and the planning
   page restates them for the same reason. There is no .lf-block here
   either, so the wordmark was rendering at 42 on a desktop and 34 on a
   phone against the other two pages' 52 -- the one element that is
   supposed to be identical everywhere. The numbers are the home page's
   rendered values, not new ones. */
/* The nav sits over a photograph here, as it does on the home page, so it
   takes the home page's .72 rather than the planning page's .82 -- that
   one was raised for a moving image whose brightest frame it had to clear. */
.n12-nav a{color:rgba(246,241,234,.72)}

/* --------------------------------- ground -------------------------------
   Black under everything, the dark ground for the bands that carry the
   plain sections, and the lighter one for anything that should read as a
   panel on it. The same three values the planning page uses. */
:root{
  --sw-ground:#171413;
  --sw-ground-dark:#0F0D0C;
  --sw-accent:#B28479;
}
html,body{background:#000}
body{color:var(--n12-cream)}

/* ------------------------------- the column -----------------------------
   .wrap came from home-section.css as a centred 1160 box. Every other page
   runs full width on --hx-inset, which is what puts the left edge of the
   copy on the same line as the masthead's wordmark. */
.wrap{
  width:100%;max-width:none;margin:0;
  padding:0 var(--hx-inset);
  position:relative;z-index:1;
}
:root{--hx-inset:clamp(44px,8vw,120px)}
@media(max-width:1024px){
  :root{--hx-inset:var(--n12-gutter,32px)}
}

/* -------------------------------- the type ------------------------------ */
/* The eyebrow is the planning page's, in clay: these two are the product
   pages and they should label their sections the same way. The home page
   keeps its own cream one. */
.eyebrow,
.sw-custom-kicker{
  display:block;margin:0 0 12px;
  font-family:'Questrial',sans-serif;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:#E4BCAC;
}

.sw-hero-simple h1{
  margin:14px 0 18px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(40px,4.4vw,56px);
  line-height:1.02;letter-spacing:-.035em;text-transform:lowercase;
}
/* The hero's supporting line. A shade brighter and a step larger than the
   body copy in the rows -- it is the only sentence up there and it is
   carrying the whole product in one breath -- but still the page's type,
   not a second voice. */
.sw-hero-sub{
  margin:0 0 6px;max-width:34em;
  font-size:16px;line-height:1.55;color:rgba(246,241,234,.76);
}
@media(max-width:640px){
  .sw-hero-sub{font-size:15px;max-width:none}
}
/* The closing heading was still on site.css's cream, #FBF6F0 -- a warmer
   white than the rest of the site, and the one place that old palette
   was still showing. */
.sw-product-row h2,
.sw-custom h2{
  margin:0;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(26px,2.65vw,38px);
  line-height:1.04;letter-spacing:-.035em;text-transform:lowercase;
  color:var(--n12-cream);
}
/* 15/1.6 at .68, the one body size the other two pages run. This page was
   at 16/1.6 at .72 -- half a step bigger and a shade brighter, which is
   the kind of difference nobody can name and everybody feels. */
.sw-product-copy p,
.sw-custom p,
.sw-four-item p{
  font-size:15px;line-height:1.6;color:rgba(246,241,234,.68);
}
.sw-product-copy p{max-width:62ch}

/* ------------------------------ the buttons -----------------------------
   The page had its own pair. They are the shared pair now -- cta-n12.css
   styles .n12-cta and its siblings, and mobile-n12.css already lists the
   planning page's two, so adding these keeps all three pages on one
   button at every width. */
.sw-btn--primary{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:15px 26px;border:0;border-radius:0;
  font-family:'Questrial',sans-serif;font-size:16px;font-weight:700;line-height:1;
  background:var(--n12-cream);color:#000;
  transition:background .18s ease,transform .18s ease;
}
.sw-btn--primary:hover{background:#fff;transform:translateY(-1px)}
/* 400, not the 700 .sw-btn sets. The home page's .n12-help and the
   planning page's .pl-btn-text are both regular weight -- a text link
   set bold beside a filled button reads as a second button. */
.sw-btn--text{
  /* inline-FLEX: the padding is the tap-target trick and works either
     way, but inline-block leaves align-items nothing to act on and the
     arrow lands on the text baseline, 3px above the letters' middle. */
  /* SYMMETRICAL padding, 7 and 7 rather than 10 and 4. The pair is what
     makes the tap target; which side carries more of it decides where
     the box's CENTRE lands, and 10/4 put this control's middle 3px above
     the primary's in the same centred flex row. */
  display:inline-flex;align-items:center;padding:7px 0;margin:-7px 0;
  font-family:'Questrial',sans-serif;font-size:16px;font-weight:400;line-height:normal;
  color:rgba(246,241,234,.78);
  border-bottom:1px solid rgba(246,241,234,.3);
}

/* THE PHONE CTA, RESTATED.

   mobile-n12.css owns the phone treatment for every button on the site
   and .sw-btn--primary is in its list now -- but that file loads BEFORE
   this one, and a media query adds no specificity, so the rule above was
   winning on a phone and this page's buttons came out 16px Questrial
   against the home page's 14.5px League Spartan. The values here are
   that file's, not new ones. */
@media(max-width:640px){
  .sw-btn--primary{
    width:auto;min-width:0;padding:14px 15px;
    font-family:'League Spartan',sans-serif;font-size:14.5px;
    letter-spacing:-.01em;justify-content:center;
  }
  .sw-btn--text{align-self:center;font-size:13.5px}
}
.sw-btn--text:hover{color:var(--n12-cream);border-color:var(--n12-cream)}

/* ------------------------------- the bands ------------------------------
   118 top and bottom on a desktop, 76 on a phone: the home page's rhythm,
   which the planning page already runs. The hero keeps its own height --
   it is a picture, not a band of type. */
/* The sections carried their own 24px (16 on a phone) side padding AND a
   centred .wrap inside it. With the wrap on --hx-inset that is two
   gutters stacked, which is why the hero's headline sat 24px right of
   every heading under it. The inset is the wrap's job now; the sections
   only own their vertical rhythm. */
.sw-hero-simple,
.sw-simple,
.sw-product,
.sw-custom{padding-left:0;padding-right:0}
.sw-product{padding-top:118px;padding-bottom:118px;background:var(--sw-ground-dark)}
.sw-product .wrap{max-width:none}
.sw-simple{background:var(--sw-ground-dark)}
.sw-simple .wrap{padding:0 var(--hx-inset)}
.sw-custom{padding-top:118px;padding-bottom:118px;background-color:var(--sw-ground)}
/* ================================ the hero ==============================

   THE HEADLINE IS NOT WRITTEN ACROSS A PHOTOGRAPH ANY MORE.

   That is what made this hero feel cheap next to the other two. Type over
   a sunset needs a heavy scrim and a heavy scrim over a sunset is a brown
   filter -- so every word sat on mud. The home page never does it: the
   picture is on one side of a hard edge and the type is on solid ground
   on the other. The planning page never does it either, because planning
   has no picture at all -- the product IS the picture.

   This takes planning's answer and gives it this page's content: a frame
   that is already dark where the type goes, the four things the software
   holds, and the window for whichever one you pick, rising out of the
   fold the way the plan does on /planning.
   ---------------------------------------------------------------------- */
.sw-hero-simple{
  background-color:var(--sw-ground-dark);
  background-image:none;
  text-align:center;
  height:auto;min-height:0;
  /* Measured off the planning page: its eyebrow sits at 148 on a
     desktop and 128 on a phone, with the wordmark's baseline at 78.
     With the masthead out of the flow again, the padding positions the
     copy -- so these two numbers ARE the match.

     128 now at both widths; software-app.css carries the same change and
     the note explaining it. */
  padding:128px 24px 0;
}
@media(min-width:901px){
  /* software.css pins the hero to a 500px box to match the other service
     pages. This one is as tall as its contents, because the stack has to
     be cut by the fold rather than by a fixed height. */
  .sw-hero-simple{height:auto;min-height:0;padding-top:128px}
}
/* TWO LAYERS, THE WAY THE HOME PAGE'S CLOSING BAND DOES IT.
   close-section.css puts the photograph on .cl-bg::before under
   `saturate(.6) brightness(.74)` and lays a flat rgba(23,20,19,.7) over
   it on ::after, so the picture reads as texture rather than as a view.
   Same structure, lighter numbers -- that photograph starts bright and
   this one starts dark. */
.sw-hero-simple::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  /* cover, not an upscale. At `auto 155%` this 1983px-wide file rendered
     near 3683 and looked soft; cover asks 1.2x at this height. */
  background:url("/assets/images/desert-blue-hour.webp") center center/cover no-repeat;
  background-image:image-set(url("/assets/images/desert-blue-hour.avif") type("image/avif"),url("/assets/images/desert-blue-hour.webp") type("image/webp"));
  filter:saturate(.68) brightness(.92);
}
.sw-hero-simple::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(180deg,
      rgba(15,13,12,.50) 0%,
      rgba(15,13,12,.30) 26%,
      rgba(15,13,12,.30) 42%,
      rgba(15,13,12,.42) 54%,
      rgba(15,13,12,.36) 68%,
      rgba(15,13,12,.24) 84%,
      rgba(15,13,12,.34) 100%),
    rgba(23,20,19,.62);
}
/* NAMED, NOT `> *`. A blanket rule put position:relative on every direct
   child, which included .n12-menu -- and mobile-n12.css only takes that
   panel out of the flow by making it position:fixed. Overriding it
   dropped a 676px closed menu into the layout below 1024, and the hero
   went from 965px tall to 1610. */
.sw-hero-simple > .sw-hero-wrap,
.sw-hero-simple > .sw-hero-rail,
.sw-hero-simple > .sw-hero-stack{position:relative;z-index:2}
/* AND THE MASTHEAD KEEPS ITS OWN POSITION.
   Home and planning both leave .n12-head absolute, which puts the
   wordmark at y=26 on both. Making it relative here to lift it above
   the wash dropped it into the flow, where it then ate the section's
   118px of padding and sat at y=144 -- 118px lower than every other
   page, which is exactly the jump you see moving between them. It only
   ever needed the z-index. */
.sw-hero-simple > .n12-head{z-index:3}
.sw-hero-wrap,
.sw-custom-wrap{max-width:none}
.sw-hero-copy{max-width:none;text-align:center}
.sw-hero-simple .eyebrow{display:block;margin-bottom:14px}
/* No max-width: the break is in the markup and a ch limit would only
   fight it. Left to wrap, the line chose "one place to keep the
   important / shit organized.", which splits the noun -- and a width
   narrow enough to force the right break gives three lines. */
.sw-hero-simple h1{
  font-size:var(--n12-h1);
  max-width:none;margin:0 auto 26px;
}
.sw-hero-br{display:inline}
.sw-hero-actions{justify-content:center;margin-bottom:34px}
@media(max-width:760px){
  .sw-hero-br{display:none}
}

/* ------------------------------------------------- the switcher, as a rail
   NOT A BUTTON BAR. A dark plate with four buttons on it looks like a
   piece of chrome dropped onto a photograph, and the page already owns a
   better shape for four steps: the spine. This is the spine on its side.
   Real buttons underneath, so a keyboard still works; what changed is
   what they look like, not what they are. */
.sw-hero-rail{
  display:grid;grid-template-columns:repeat(4,1fr);
  position:relative;width:min(100%,760px);margin:0 auto;
}
/* The rail, from the first node's centre to the last one's. Each cell is
   a quarter of the strip, so a node's centre sits at 12.5%. */
.sw-hero-rail::before{
  content:"";position:absolute;left:12.5%;right:12.5%;top:22px;height:1px;
  background:rgba(246,241,234,.2);
}
.sw-hero-rail button{
  display:grid;justify-items:center;align-content:start;
  background:none;border:0;padding:0 10px;cursor:pointer;
  color:rgba(246,241,234,.62);
  transition:color .25s ease;
}
.sw-hero-rail i{
  font-style:normal;font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:11px;letter-spacing:.14em;color:var(--sw-accent);
  margin-bottom:9px;transition:color .25s ease;
}
/* Actually opaque. At .92 the line showed straight through every node,
   so they read as rings laid over a wire instead of as points on it. */
.sw-hero-rail s{
  width:13px;height:13px;border-radius:999px;text-decoration:none;
  border:1px solid rgba(246,241,234,.34);
  background:#171413;
  position:relative;
  transition:background .3s ease,border-color .3s ease,transform .3s ease;
}
.sw-hero-rail b{
  margin-top:13px;max-width:15ch;
  font-family:'Questrial',sans-serif;font-weight:700;
  font-size:12px;letter-spacing:.14em;line-height:1.35;text-transform:uppercase;
}
.sw-hero-rail button:hover{color:rgba(246,241,234,.86)}
.sw-hero-rail button:hover s{border-color:#E4BCAC}
.sw-hero-rail button[aria-selected="true"]{color:#F6F1EA}
.sw-hero-rail button[aria-selected="true"] i{color:#E4BCAC}
.sw-hero-rail button[aria-selected="true"] s{
  background:var(--sw-accent);border-color:#E4BCAC;transform:scale(1.1);
}
/* The breath, off the spine's own: a ring that expands and goes, rather
   than the node itself moving -- a node that moves drags the rail. */
.sw-hero-rail button[aria-selected="true"] s::after{
  content:"";position:absolute;inset:-4px;border-radius:999px;
  border:1px solid #E4BCAC;opacity:0;
  animation:sw-breathe 3s ease-out infinite;
}
@keyframes sw-breathe{
  0%{opacity:.45;transform:scale(.75)}
  60%,100%{opacity:0;transform:scale(1.5)}
}
.sw-hero-rail button:focus-visible{outline:2px solid #E4BCAC;outline-offset:3px}
@media(prefers-reduced-motion:reduce){
  .sw-hero-rail s{transition:none}
  .sw-hero-rail button[aria-selected="true"] s::after{animation:none}
}
@media(max-width:760px){
  /* Four columns on a phone gives each label about 80px, and "who's
     responsible for what" is five lines in 80px. So the rail stands up,
     which is what the spine does at this width anyway. */
  .sw-hero-rail{
    display:grid;grid-template-columns:auto 1fr;gap:0 14px;
    justify-items:start;text-align:left;width:100%;max-width:340px;
  }
  .sw-hero-rail::before{left:6px;right:auto;top:8px;bottom:8px;width:1px;height:auto}
  .sw-hero-rail button{
    display:grid;grid-template-columns:13px auto;align-items:center;
    gap:0 12px;padding:9px 0;grid-column:1/-1;justify-items:start;
  }
  .sw-hero-rail i{display:none}
  .sw-hero-rail b{margin-top:0;max-width:none;font-size:11.5px;letter-spacing:.12em}
}

/* ------------------------------------------------------------- the stack */
.sw-hero-stack{
  position:relative;max-width:1000px;margin:34px auto 0;height:340px;
}
.sw-hero-stack .sw-mock{
  /* left, not inherited -- the section centres its own type and the
     windows were picking it up, so every to-do and metric row was
     centred inside its window, which no application has ever done. */
  text-align:left;
  /* ONE SIZE FOR ALL FOUR. They are naturally different heights -- the
     meeting is four agenda lines, the dashboard is a list plus two goal
     cards -- so the fan had four different bottom edges and read as a
     pile. Fixed and clipped: same rectangle, cut at the same place. */
  height:430px;overflow:hidden;
  position:absolute;left:50%;top:0;width:min(88vw,760px);
  transform-origin:50% 100%;cursor:pointer;
  box-shadow:0 40px 80px rgba(0,0,0,.62);
  transition:transform .6s cubic-bezier(.16,1,.3,1),filter .6s ease;
}
/* Dimmed, but not to the point of being a dark rectangle -- and
   outlined, because against a near-black ground the edge of a dark
   window is otherwise unfindable. */
.sw-hero-stack .is-l,
.sw-hero-stack .is-r,
.sw-hero-stack .is-b{
  filter:brightness(.72) saturate(.9);
  outline:1px solid rgba(246,241,234,.12);outline-offset:-1px;
}
.sw-hero-stack .is-l,
.sw-hero-stack .is-r{z-index:2}
.sw-hero-stack .is-l{transform:translateX(-50%) translateX(-152px) translateY(26px) rotate(-3.4deg) scale(.9)}
.sw-hero-stack .is-r{transform:translateX(-50%) translateX(152px) translateY(26px) rotate(3.4deg) scale(.9)}
/* The fourth goes straight back and UP, so its top edge shows above the
   front window's. Pushed down it would sit perfectly hidden behind it,
   and a card you cannot see is not in the stack. */
.sw-hero-stack .is-b{
  z-index:1;
  transform:translateX(-50%) translateY(-30px) scale(.84);
  filter:brightness(.55) saturate(.85);
}
.sw-hero-stack .is-l:hover,
.sw-hero-stack .is-r:hover,
.sw-hero-stack .is-b:hover{filter:brightness(.92) saturate(1)}
.sw-hero-stack .is-f{z-index:3;transform:translateX(-50%);cursor:default}
@media(prefers-reduced-motion:reduce){
  .sw-hero-stack .sw-mock{transition:none}
}
@media(max-width:760px){
  .sw-hero-simple{padding-top:128px}
  .sw-hero-stack{height:300px;margin-top:26px}
  .sw-hero-stack .sw-mock{width:92vw}
  .sw-hero-stack .is-l{transform:translateX(-50%) translateX(-34px) translateY(20px) rotate(-4deg) scale(.93)}
  .sw-hero-stack .is-r{transform:translateX(-50%) translateX(34px) translateY(20px) rotate(4deg) scale(.93)}
}

/* ================================ the spine =============================

   The page's four words, as its structure instead of a strip above it.
   One rail down the left, a node for each step, and the step's own
   question under its name. The rail is what turns four rows into a
   sequence: without it they are four independent claims in a stack, which
   is what they were.

   The rows do not alternate any more. Alternation is decoration, and a
   spine needs a constant axis -- with the copy swapping sides every row
   the step label would have detached from the thing it labels every
   other time. Copy left, mock right, all four.
   ---------------------------------------------------------------------- */
.sw-product .wrap{position:relative;--sw-rail:0px}

/* The rail itself, drawn from the top as the section arrives. It runs
   between the first node and the last rather than the whole height: a
   line that starts above the first step and ends below the last one is a
   border, not a spine. */
/* THE MOCK LEADS, THE RAIL DIVIDES, THE COPY FOLLOWS.

   Three arrangements were tried. A left rail with everything to the
   right of it read as a sequence but ran four identical rows. A centred
   rail with the rows alternating broke that up and cost two things: the
   columns have to go equal for a centred axis, which took the mocks from
   695px to 519, and the short copy blocks left large voids opposite the
   tall windows.

   This one keeps what each had. The mock sits on the page's left edge --
   so the band still starts where every other band on the site starts --
   the rail divides the row, and the copy follows on the right. Every row
   the same way round, which is what a numbered sequence needs, and the
   mock keeps the wider column because it no longer has to match the copy
   for a centred axis to work.

   The rail's x cannot be written as a percentage: it is the middle of a
   gutter between two fr columns, which moves with the width. The script
   measures it and sets --sw-spine-x. Absent that, it falls back to 50%
   and everything still reads.
   ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* THE OLD NOTE, kept because the bug in it is worth remembering:

   It hung in the margin for a while, so that the headings in this band
   would line up with the hero's and the closing band's. Measured across
   the three pages, that was the wrong thing to align: the leftmost INK
   is what a reader sees as the margin, and the rail is the leftmost ink
   here. It was landing at 38, 51 and 56 against the other two pages'
   102, 115 and 120.

   It was also a bug. The override that pulled the rail back in lived in
   a max-width:900 block while the inset drops to 32 at 1024 -- so
   between 901 and 1024 the rail was at 32 minus 64, which is 32 pixels
   off the left of the screen. The spine was simply not there.

   On the inset everywhere, then, with the copy stepping past it. The
   band's headings sit 64px (30 on a phone) right of the hero's, which is
   what an indented sequence costs and is worth paying: the margin is the
   thing that has to agree between pages, and now it does. */
/* AND IT FILLS AS YOU READ, RATHER THAN DRAWING ONCE.

   This was a one-shot: it ran when the band arrived and then sat there.
   The home page's proof spine does the better thing -- a neutral track
   with a clay bar inside whose height is how far down the section you
   are -- so the line reports a POSITION rather than an event, and it
   retreats when you scroll back up. Same mechanism here. */
.sw-spine{
  position:absolute;left:var(--sw-spine-x,50%);top:var(--sw-spine-top,0);
  width:1px;height:var(--sw-spine-h,0);
  background:rgba(246,241,234,.12);
}
.sw-spine i{
  display:block;width:100%;height:100%;
  background:var(--sw-accent);
  transform:scaleY(var(--sw-p,0));transform-origin:top center;
}
@media(prefers-reduced-motion:reduce){
  /* No travelling line: the clay is simply there. */
  .sw-spine i{transform:none}
}

/* The copy steps past the rail. 64 on a desktop, 30 on a phone -- see
   the phone block below, where 64 out of 353 would be a fifth of the
   screen spent on a gutter. */
/* EQUAL COLUMNS, so the rail is on the page's centre line and not just
   somewhere between the two. 1.15fr against .85fr gave the mock 25 more
   pixels and put the rail 77px right of the middle -- which is the kind
   of nearly-centred that reads as a mistake rather than as a choice. */
.sw-product-row{position:relative;padding-left:0;align-items:center;grid-template-columns:minmax(0,1fr) 72px minmax(0,1fr)}
.sw-product-row > .sw-mock{grid-column:1;grid-row:1}
.sw-product-row > .sw-product-copy{grid-column:3;grid-row:1}
/* :first-of-type, not :first-child. software.css clears the top border on
   the first row and the bottom padding on the last with :first-child and
   :last-child, and the spine's own element is now the wrap's first child
   -- so row one grew a rule across the top of the section. The rows are
   the only divs in here, so of-type picks them out. */
.sw-product-row:first-of-type{border-top:0;padding-top:0}
.sw-product-row:last-of-type{padding-bottom:0}
/* The node. A ring on the rail, filled once its row is the one you are
   reading -- the same lit/unlit pair the planning page's annotations use. */
.sw-product-row::before{
  content:"";position:absolute;left:calc(var(--sw-node-x,50%) - 5.5px);top:var(--sw-node-top,6px);
  width:11px;height:11px;border-radius:50%;
  border:1px solid rgba(178,132,121,.55);background:var(--sw-ground-dark);
  transition:background .45s ease,border-color .45s ease,box-shadow .45s ease;
}
.sw-product-row.is-here::before{
  background:var(--sw-accent);border-color:var(--sw-accent);
  box-shadow:0 0 0 5px rgba(178,132,121,.12);
}
/* A slight breath on the filled ones, the same as the home page's tree.
   A ring OUTSIDE the node rather than the node itself, so nothing that
   is lined up with the step label moves. Staggered: four dots pulsing in
   unison is a loading spinner. */
.sw-product-row::after{
  content:"";position:absolute;
  left:calc(var(--sw-node-x,50%) - 7.5px);top:calc(var(--sw-node-top,6px) - 2px);
  width:15px;height:15px;border-radius:50%;
  border:1px solid var(--sw-accent);
  opacity:0;pointer-events:none;
}
.sw-product-row.is-here::after{animation:sw-breathe 3.2s ease-out infinite}
.sw-product-row:nth-of-type(2)::after{animation-delay:.8s}
.sw-product-row:nth-of-type(3)::after{animation-delay:1.6s}
.sw-product-row:nth-of-type(4)::after{animation-delay:2.4s}
@keyframes sw-breathe{
  0%{opacity:.4;transform:scale(.8)}
  55%,100%{opacity:0;transform:scale(1.5)}
}
@media(prefers-reduced-motion:reduce){
  .sw-product-row.is-here::after{animation:none}
}

/* The number and the word on one line, and nothing else. The step used to
   carry its question underneath in Caveat; the hand belongs to the
   planning page, where it means "someone annotated this", and a second
   page using it spends it. The headings say the same thing directly. */
.sw-step{display:block;margin:0 0 12px}
/* THE LABEL BELONGS TO THE HEADING; THE PARAGRAPH IS A SEPARATE BREATH.
   Those three sat at 12 above the heading and 14 below it -- near enough
   the same gap that the eyebrow, the heading and the sentence read as one
   undifferentiated block. The label stays tight to what it labels and the
   paragraph gets its own air. */
.sw-product-copy h2{margin-bottom:22px}
@media(max-width:900px){.sw-product-copy h2{margin-bottom:18px}}
/* Both clay, the deeper one on the numeral -- the same pairing the
   planning page's two notes use, where the numeral is --pl-accent and
   the words are its lighter tint. The numeral was cream at 40%, which
   made it read as furniture rather than as part of the label. */
.sw-step b{
  display:inline-block;margin-right:10px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:12px;letter-spacing:.14em;color:var(--sw-accent);
}
/* Questrial, like every other eyebrow on the site. This one was League
   Spartan, which at 12px and .17em tracking is a different letterform
   doing the same job -- the home page's .st-eyebrow and the planning
   page's .pl-eyebrow are both the body face. */
.sw-step > span{
  font-family:'Questrial',sans-serif;font-weight:700;
  font-size:12px;letter-spacing:.17em;text-transform:uppercase;
  color:#E4BCAC;
}

/* Four rows, one axis: the reverse class is off the markup, and this
   catches any that come back. */
.sw-product-row.reverse{grid-template-columns:.8fr 1.2fr}
.sw-product-row.reverse .sw-product-copy{order:0}

/* STEP ONE HAS A THIRD THING IN IT.

   The planning offer is a sibling of the mock now rather than a tail on
   the copy, so that on a phone it lands AFTER the plan -- the offer to
   help build one makes more sense once you have seen what one looks
   like. Named areas rather than source order, because the desktop wants
   it back under the copy and the phone wants it last. */
.sw-product-row--plan{
  grid-template-areas:"mock gut copy" "mock gut cta";
  grid-template-rows:auto auto;
  align-items:center;
}
.sw-product-row--plan > .sw-product-copy{grid-area:copy}
.sw-product-row--plan > .sw-mock{grid-area:mock;align-self:center}
.sw-product-row--plan .sw-inline-planning{grid-area:cta;align-self:start}
/* THE RULE HAS TO END WHERE THE TEXT ENDS.
   software.css padded it 14px above the question and 2px below the link,
   so the rule ran a clear 12px past the bottom of the words -- the text
   sat high in its own bracket. Equal padding, and since both lines are
   line boxes with symmetric half-leading, equal padding is what centres
   them against it. */
.sw-inline-planning{padding-top:9px;padding-bottom:9px}
@media(max-width:900px){
  /* Stacked, and the copy leads again. Leading with a picture is right
     on a desktop where the heading is beside it; on a phone it would put
     a window above the sentence that says what the window is. */
  .sw-product-row--plan{grid-template-areas:"copy" "mock" "cta";grid-template-rows:auto}
  .sw-product-row--plan .sw-inline-planning{margin-top:0}
  .sw-product-row > .sw-mock,
  .sw-product-row > .sw-product-copy{grid-column:1}
  .sw-product-row > .sw-product-copy{grid-row:1}
  .sw-product-row > .sw-mock{grid-row:2}
}

/* ========================= one type scale for the mocks =================

   Measured across the four windows before this: a row of body text was
   13px in the plan, 13 in the meeting, 10 in the dashboard and 9 in the
   org chart; the micro-labels ran 8, 9, 10 and 11. Four pictures of the
   SAME product, drawn at four sizes, which reads as four different
   applications rather than four screens of one.

     title   12   the window's own name, already consistent
     body    13   a row of content
     meta    11   the quiet column beside it: owner, date, status
     label   10   the uppercase micro-label over a block
     figure  23   a number that is the point of its panel

   The org chart keeps its own smaller pair: six boxes across one window
   is a genuine constraint, not an inconsistency -- but they come up to
   12/11/10 from 11/9/9, which is as far as the width allows.
   ---------------------------------------------------------------------- */
.sw-mock{--mk-body:13px;--mk-meta:11px;--mk-label:10px}

/* the dashboard */
.sw-todo-tabs button{font-size:var(--mk-meta)}
.sw-dash .sw-todo-item b{font-size:var(--mk-body)}
.sw-dash .sw-todo-item em,
.sw-dash .sw-todo-item strong{font-size:var(--mk-meta)}
.sw-dash-empty{font-size:var(--mk-meta)}
.sw-goal-card > span{font-size:var(--mk-label);letter-spacing:.14em}
.sw-goal-card > b{font-size:var(--mk-body)}
.sw-goal-card > em{font-size:var(--mk-meta)}
.sw-report-line{font-size:var(--mk-meta)}
.sw-report-line > b{font-size:var(--mk-body)}
/* the meeting */
.sw-agenda-line{font-size:var(--mk-body)}
.sw-agenda-line em,
.sw-agenda-line > span{font-size:var(--mk-meta)}
.sw-play{font-size:var(--mk-meta)}
.sw-meeting-todo{font-size:var(--mk-body)}
.sw-meeting-todo em,
.sw-meeting-todo strong{font-size:var(--mk-meta)}
/* the plan */
.sw-mock-trow{font-size:var(--mk-body)}
.sw-mock-trow.head{font-size:var(--mk-label);letter-spacing:.14em}
.sw-plan-col > span,
.sw-mock-sub{font-size:var(--mk-label)}
.sw-plan-col em{font-size:var(--mk-meta)}
/* the org chart, on its own pair */
.sw-org-node b{font-size:12px}
.sw-org-node .sw-org-person{font-size:var(--mk-meta)}
.sw-org-node span{font-size:var(--mk-label)}

/* EACH SEAT LISTS WHAT IT OWNS.

   Next 12's chart holds duties per seat, and a box with one vague line
   under a name -- "delivery + team" -- was showing a job title, which is
   the thing an org chart is usually criticised for. Two duties each: the
   point of the feature is that a seat is a set of responsibilities
   somebody holds, not a rung.

   Two and not four because six boxes share one window. The dash is a
   border rather than a list marker so the wrap indents under the text
   instead of under the bullet. */
.sw-org-duty{
  position:relative;padding-left:9px;
  color:rgba(224,210,197,.52);
}
.sw-org-duty + .sw-org-duty{margin-top:2px}
.sw-org-duty::before{
  content:"";position:absolute;left:0;top:.62em;
  width:4px;height:1px;background:rgba(224,210,197,.38);
}
.sw-org-node .sw-org-person{margin-bottom:5px}
/* The duties are a list and want a left edge; the top box centres its
   department and name, which left the dashes floating a long way from
   the words. It goes left-aligned like every other box -- the box itself
   is still centred under nothing, which is what makes it the top. */
.sw-org-node--top{text-align:left}

/* The owner's second seat, named. The clay on the repeated name marks it
   but does not explain it, and "also leadership" is the whole point of
   the detail -- it is not a duty, so it does not take a dash. */
.sw-org-also{
  display:block;margin:-2px 0 5px;
  font-size:var(--mk-label);font-style:italic;
  color:rgba(178,132,121,.75);
}

/* The seat the owner is also holding, and the seat nobody is in yet.
   Both are quiet: they are facts about the chart, not warnings. */
.sw-org-node--dual .sw-org-person{color:var(--sw-accent)}
.sw-org-node--open{
  border-style:dashed;border-color:rgba(224,210,197,.22);
  background:rgba(246,241,234,.02);box-shadow:none;
}
.sw-org-node--open b{color:rgba(246,241,234,.55)}
.sw-org-node--open .sw-org-person{color:rgba(246,241,234,.42);font-style:italic}

/* ===================== the chart is a hierarchy ========================

   It was not drawing one. A bar floated across the three managers with
   no drop into any of them, so nothing connected a box to the box above
   it -- and the bottom two hung off a bracket centred under SALES, which
   made dispatch and customer experience look like they reported to the
   seat the owner is doubling up on.

   Every line is drawn from a box to a box now:

       leadership
            |
     +------+------+
     |      |      |
    ops   sales  finance
     |
     +------+
     |      |
   dispatch  cx

   All of it is pseudo-elements hung off the rows and the nodes, so the
   geometry follows the boxes instead of being pinned at fixed pixel
   offsets the way .sw-org-stem and .sw-org-branch were -- those two are
   off, and the markup can lose them whenever it is next touched.
   ---------------------------------------------------------------------- */
.sw-org-stem,
.sw-org-branch{display:none}

.sw-org-row{position:relative}
.sw-org-node{position:relative}

/* leadership down to the managers' bar */
.sw-org-node--top::after{
  content:"";position:absolute;left:50%;top:100%;
  width:1px;height:17px;background:rgba(224,210,197,.36);
}
/* the bar, spanning the OUTER managers' centres -- 31% wide in a
   space-between row puts them at 15.5% and 84.5% */
.sw-org-row:not(.sw-org-row--bottom)::before{
  content:"";position:absolute;left:15.5%;right:15.5%;top:-17px;
  height:1px;background:rgba(224,210,197,.36);
}
/* and a drop from the bar into each manager */
.sw-org-row:not(.sw-org-row--bottom) > .sw-org-node::before{
  content:"";position:absolute;left:50%;top:-17px;
  width:1px;height:17px;background:rgba(224,210,197,.36);
}
/* operations down toward its own two reports */
.sw-org-row:not(.sw-org-row--bottom) > .sw-org-node:first-child::after{
  content:"";position:absolute;left:50%;top:100%;
  width:1px;height:14px;background:rgba(224,210,197,.3);
}

/* THE BOTTOM PAIR SITS ON THE SAME GRID AS THE ROW ABOVE.

   The managers are three 31% boxes with 3.5% between them. The bottom
   two were 31% boxes with 22.5% between them -- the same size but a
   different rhythm, which read as a second layout rather than the next
   row of the first.

   65.5% wide with two 47.33% nodes gives 31% boxes with the same 3.5%
   gap, which lands dispatch under operations and customer experience
   under sales. Everything below is derived from that: the node centres
   are at 23.66% and 76.34% of this row. */
.sw-org-row--bottom{width:65.5%;margin:31px auto 0 0}
.sw-org-row--bottom .sw-org-node{width:47.33%}
.sw-org-row--bottom::before{
  left:23.66%;right:23.66%;top:-17px;height:17px;
  border:0;border-top:1px solid rgba(224,210,197,.3);
}
.sw-org-row--bottom > .sw-org-node::before{
  content:"";position:absolute;left:50%;top:-17px;
  width:1px;height:17px;background:rgba(224,210,197,.3);
}

@media(max-width:640px){
  /* Everything steps down together rather than each mock finding its own
     floor, which is how they drifted apart in the first place. */
  .sw-mock{--mk-body:12px;--mk-meta:10px;--mk-label:9px}
  .sw-org-node b{font-size:10px}
  .sw-org-node .sw-org-person{font-size:9px}
  .sw-org-node span{font-size:8px}
}

/* ------------------------------- the mocks ------------------------------
   The window chrome matches the plan mock on the planning page: the same
   ground, the same hairline, the same three dots. They are pictures of the
   same product and were drawn in two different greys. */
.sw-mock{
  background:var(--sw-ground);
  border:1px solid rgba(178,132,121,.20);
  border-radius:12px;
  box-shadow:0 28px 70px rgba(0,0,0,.45);
}
.sw-mock-topbar{background:#1B1716;border-bottom:1px solid rgba(246,241,234,.14)}
.sw-mock-title{color:rgba(246,241,234,.6)}
.sw-mock-dot.r{background:#6B6668}
.sw-mock-dot.y{background:#95877F}
.sw-mock-dot.g{background:#C18A70}

/* ============================== the plan strip ==========================
   The year and the quarter, side by side above the weekly numbers, in the
   same window. The pair divides the way the plan panels on the planning
   page divide and the two prices on it divide: a rule between, not a gap.
   ---------------------------------------------------------------------- */
.sw-plan-strip{
  display:grid;grid-template-columns:1fr 1fr;
  border-bottom:1px solid rgba(246,241,234,.1);
}
.sw-plan-col{padding:15px 18px 16px}
.sw-plan-col + .sw-plan-col{border-left:1px solid rgba(246,241,234,.1)}
.sw-plan-col > span{
  display:block;margin-bottom:8px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(246,241,234,.44);
}
.sw-plan-col b{
  display:block;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:23px;line-height:1;letter-spacing:-.02em;color:var(--n12-cream);
}
.sw-plan-col em{
  display:block;margin-top:5px;
  font-style:normal;font-size:11px;color:rgba(246,241,234,.5);
}
/* The table's own label, so the numbers under it read as a third thing
   rather than as more of the quarter's column. */
.sw-mock-sub{
  padding:13px 18px 0;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(246,241,234,.44);
}
.sw-mock-plan .sw-mock-table{padding-top:2px}
@media(max-width:400px){
  .sw-plan-col{padding:13px 12px 14px}
  .sw-plan-col b{font-size:20px}
  .sw-plan-col em{font-size:10px}
}

/* ============================== the meeting =============================
   The agenda mock runs. Everything below is the difference between the
   still picture and the running one -- the still picture is what a
   reader who never presses it sees, and it is unchanged.
   ---------------------------------------------------------------------- */
.sw-meeting .sw-mock-topbar{position:relative}
.sw-play{
  margin-left:auto;padding:5px 12px;
  border:1px solid rgba(178,132,121,.45);border-radius:999px;background:transparent;
  /* No font-size here: the mock type scale above owns it, and this rule
     is later in the file so a size here would win. */
  font-family:'Questrial',sans-serif;letter-spacing:.06em;
  color:#E4BCAC;cursor:pointer;white-space:nowrap;
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
.sw-play:hover{background:rgba(178,132,121,.14);border-color:var(--sw-accent)}
.sw-play:focus-visible{outline:2px solid #E4BCAC;outline-offset:2px}

/* The item being discussed. The numeral fills, the row lifts off the
   ground a little and its time goes to full cream -- this is the line
   the room is on. */
.sw-agenda-line{transition:background .3s ease,opacity .3s ease}
.sw-agenda-line > span,
.sw-agenda-line em{transition:color .3s ease,background .3s ease,border-color .3s ease}
.sw-meeting.is-running .sw-agenda-line{opacity:.42}
.sw-meeting .sw-agenda-line.is-live{
  opacity:1;background:rgba(178,132,121,.07);
}
.sw-meeting .sw-agenda-line.is-live > span{
  background:var(--sw-accent);border-color:var(--sw-accent);color:#171413;
}
.sw-meeting .sw-agenda-line.is-live em{color:var(--n12-cream)}
/* Discussed. The numeral becomes a tick and the row settles back. */
.sw-meeting .sw-agenda-line.is-done{opacity:.55}
.sw-meeting .sw-agenda-line.is-done > span{
  color:transparent;border-color:rgba(167,196,164,.5);
}
.sw-meeting .sw-agenda-line.is-done > span::after{
  content:"";position:absolute;width:9px;height:5px;
  border-left:1.5px solid #A7C4A4;border-bottom:1.5px solid #A7C4A4;
  transform:rotate(-45deg) translate(1px,-1px);
}
.sw-agenda-line > span{position:relative}
.sw-meeting .sw-agenda-line.is-done em{color:rgba(167,196,164,.75)}

/* What the meeting produced. A meeting that ends with nothing is the
   thing the heading is complaining about, so this is the payoff: the
   agenda finishes and a to-do exists that did not before. */
.sw-meeting-out{
  padding:14px 16px 16px;border-top:1px solid rgba(246,241,234,.1);
  opacity:0;transform:translateY(8px);
  transition:opacity .5s ease,transform .5s cubic-bezier(.16,1,.3,1);
}
.sw-meeting-out.is-in{opacity:1;transform:none}
.sw-meeting-out > span{
  display:block;margin-bottom:9px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:10px;letter-spacing:.17em;text-transform:uppercase;
  color:rgba(246,241,234,.42);
}
.sw-meeting-todo{
  display:grid;grid-template-columns:16px 1fr auto auto;gap:10px;
  align-items:center;color:#E8E0DB;
}
.sw-meeting-todo i{
  width:14px;height:14px;border-radius:3px;
  border:1px solid rgba(178,132,121,.5);
}
.sw-meeting-todo em{font-style:normal;color:rgba(246,241,234,.5)}
.sw-meeting-todo strong{font-weight:400;color:var(--sw-accent)}

@media(prefers-reduced-motion:reduce){
  .sw-agenda-line,
  .sw-agenda-line > span,
  .sw-agenda-line em,
  .sw-meeting-out{transition:none}
  .sw-meeting-out{transform:none}
}

/* =========================== saying it is alive =========================
   A window that does something looks exactly like a window that does not,
   and a small outlined button in a chrome bar reads as part of the
   picture. Two cues: a line in the reading column, where the eye already
   is, pointing at the mock; and a slow ring on the control itself. Both
   stop for good at the first touch -- an invitation that keeps arriving
   after it has been accepted is a nag.
   ---------------------------------------------------------------------- */
/* It is a button now, not a label. It was telling you to go and press
   something else, which is one instruction more than it needs -- pressing
   THIS runs the mock beside it. So it looks pressable: clay, underlined,
   and it brightens on hover. */
.sw-try{margin:14px 0 0;transition:opacity .4s ease}
.sw-try button{
  font:inherit;font-size:13px;letter-spacing:.02em;
  background:none;border:0;padding:4px 0;cursor:pointer;
  color:var(--sw-accent);
  border-bottom:1px solid rgba(178,132,121,.45);
  transition:color .2s ease,border-color .2s ease;
}
.sw-try button:hover{color:#E4BCAC;border-color:#E4BCAC}
.sw-try button:focus-visible{outline:2px solid #E4BCAC;outline-offset:3px}
/* The arrow points AT the mock, which is on the left now. Before the
   words, because an arrow pointing left from the end of a phrase reads
   backwards. The non-breaking space keeps it off the word -- a trailing
   normal one collapses. */
.sw-try button::before{
  content:"\2190\00a0";
  display:inline-block;transform:translateX(0);
  transition:transform .9s ease-in-out;
}
.sw-try.is-nudge button::before{transform:translateX(-5px)}
.sw-product-row.is-tried .sw-try{opacity:0;pointer-events:none}
@media(max-width:900px){
  /* Stacked, so the mock is underneath and the arrow turns with it --
     and goes back after the words, where a down arrow belongs. */
  .sw-try button::before{content:""}
  .sw-try button::after{
    content:"\00a0\2193";display:inline-block;
    transition:transform .9s ease-in-out;
  }
  .sw-try.is-nudge button::before{transform:none}
  .sw-try.is-nudge button::after{transform:translateY(4px)}
}
@media(prefers-reduced-motion:reduce){
  .sw-try,.sw-try button::before,.sw-try button::after{transition:none}
  .sw-try.is-nudge button::before,
  .sw-try.is-nudge button::after{transform:none}
}

/* The ring on the control. Not a pulse on the button itself -- that moves
   the label, and a label that moves is harder to read, not easier to
   notice. */
.sw-play{position:relative}
.sw-play::after{
  content:"";position:absolute;inset:-3px;border-radius:999px;
  border:1px solid #E4BCAC;opacity:0;pointer-events:none;
  animation:sw-ping 3s ease-out infinite;
}
.sw-mock.is-tried .sw-play::after{animation:none;opacity:0}
@keyframes sw-ping{
  0%{opacity:.45;transform:scale(.97)}
  60%,100%{opacity:0;transform:scale(1.22)}
}
@media(prefers-reduced-motion:reduce){
  .sw-play::after{animation:none;opacity:0}
}

/* ============================= the dashboard ============================
   The tabs filter and the rows tick. It is a picture of state, not of
   time, so nothing moves on its own -- it only answers.
   ---------------------------------------------------------------------- */
.sw-todo-tabs button{
  /* font-size AFTER font:inherit, which resets it to the mock's 16px --
     and this rule is later in the file than the type scale above, so the
     scale's value has to be restated here rather than relied on. */
  font:inherit;font-size:var(--mk-meta);
  background:none;border:0;padding:0 0 11px;cursor:pointer;
  position:relative;color:rgba(246,241,234,.54);
  transition:color .2s ease;
}
.sw-todo-tabs button:hover{color:rgba(246,241,234,.85)}
.sw-todo-tabs button.active{color:#E4BCAC}
.sw-todo-tabs button.active::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:#E4BCAC;
}
.sw-todo-tabs button:focus-visible,
.sw-todo-item:focus-visible{outline:2px solid #E4BCAC;outline-offset:2px}

.sw-dash .sw-todo-item{
  width:100%;font:inherit;background:none;border:0;border-bottom:1px solid rgba(246,241,234,.055);
  text-align:left;cursor:pointer;color:inherit;
  transition:opacity .25s ease;
}
.sw-dash .sw-todo-item:hover{opacity:.78}
.sw-dash .sw-todo-item[hidden]{display:none}
.sw-dash .sw-todo-item.is-done b{color:rgba(246,241,234,.5);text-decoration:line-through}
.sw-dash .sw-todo-item i{transition:background .25s ease,border-color .25s ease}
.sw-dash-empty{
  margin:0;padding:22px 18px;text-align:center;
  color:rgba(246,241,234,.4);
}
.sw-report-line > i em{transition:width .45s cubic-bezier(.16,1,.3,1)}
@media(prefers-reduced-motion:reduce){
  .sw-report-line > i em,.sw-dash .sw-todo-item,.sw-dash .sw-todo-item i{transition:none}
}

/* ------------------------------ the phone ------------------------------- */
@media(max-width:900px){
  .sw-product,
  .sw-custom{padding-top:76px;padding-bottom:76px}
  .sw-hero-simple,
  .sw-simple,
  .sw-product,
  .sw-custom{padding-left:0;padding-right:0}
  /* !important only to answer an !important. software.css sets
     `padding:94px 16px 52px!important` on the hero below 640, which put
     the headline 16px inside every heading under it -- 36 against 20 at
     393. Nothing else on the page needs the hammer. */
  /* padding-top joins them for the same reason: that same shorthand
     sets 94px, which put the wordmark 34px higher than home's and
     planning's on a phone. 128 is the planning page's own measurement. */
  .sw-hero-simple{padding-left:0!important;padding-right:0!important;padding-top:128px!important}
  /* The spine stays on a phone -- it is the page's structure, not a
     desktop flourish -- but it pulls in: 64px of indent out of 353 is a
     fifth of the screen spent on a gutter. */
  /* A phone stacks, so there is no gutter to put the rail in: it goes
     back to the page's left edge with the copy stepping 30px past it.
     64 would be a fifth of a 353px column. */
  /* The rail is positioned against the wrap's PADDING box, which starts
     at the screen edge -- so the page inset has to be added back, or the
     rail lands at x=0 instead of on the margin. The node is positioned
     against its row, which already starts one inset in, so it takes 0. */
  .sw-product .wrap{--sw-spine-x:var(--hx-inset);--sw-node-x:0px}
  .sw-product-row{padding-left:30px;grid-template-columns:1fr}
  .sw-product-row::before{left:-5.5px}
  .sw-product-row::after{left:-7.5px}
  .sw-product-row::before{width:9px;height:9px;left:calc(var(--sw-rail) * -1 - 4px)}
  .sw-product-row::after{
    width:13px;height:13px;
    left:calc(var(--sw-rail) * -1 - 6px);top:calc(var(--sw-node-top,6px) - 2px);
  }
  /* The section heads take the home page's phone size, from the same token
     mobile-n12.css defines for .st-head and its siblings. Declared here
     because a media query adds no specificity and the selectors in that
     file would lose to these ones, which load later. */
  .sw-product-row h2,
  .sw-custom h2{font-size:var(--n12-mhead,clamp(29px,8.2vw,34px))}
}

/* ------------------------------ the reveal ------------------------------
   The mock is the one thing on a row that should not slide: it is a
   picture of a screen, and a screenshot that moves reads as a carousel.
   Fade only, like the home page's photograph. */
.rv .sw-mock[data-rv]{transform:none;transition:opacity .9s ease var(--rv-d,0ms)}
.rv .sw-mock[data-rv].is-rv{transform:none}
