/* =========================================================================
   planning-n12.css -- the planning page, on the home page's system.

   The two pages were never going to look related, because they were built
   on two different foundations. Measured, before this file:

                     planning              home
     grounds         #2C2523 / #332C2A     #171413 / #0F0D0C
     cream           #FBF6F0               #F6F1EA
     accent          wheat #E0D2C5         clay  #B28479
     eyebrow         14px / .12em          12px / .17em
     body copy       16-17px               14.5-15px
     breakpoints     640 / 760 / 900       640 / 900 / 980 / 1024

   The grounds were two to three shades lighter and browner, the accent
   was the wheat the home page deliberately moved OFF, and the type ran a
   size larger throughout. This file closes all of it.

   It loads after planning.css and overrides rather than replacing it,
   because planning.css also holds the whole plan-mock component -- about
   half its weight -- and that is worth keeping as it is.

   THE ONE TRICK WORTH KNOWING: planning.css colours things with --ink,
   --cream and --peach, which used to come from site.css. site.css is no
   longer loaded, so those three are redefined here pointing at the home
   palette -- which silently recolours every planning.css rule that uses
   them, without touching planning.css at all.
   ========================================================================= */

/* SAFARI ON A PHONE INFLATES TEXT ON ITS OWN, and this page cannot have
   it. The Text Autosizing pass boosts type in narrow blocks, and the
   plan mock -- laid out at zoom .26 below 640 -- is the widest possible
   invitation: the frame scaled down and the type inside it snapped back
   to full size, so numerals landed on the goals they number, avatars on
   the names beside them, and the deadline broke to its own line. Every
   track in the mock is sized in the window's zoomed coordinates, so
   full-size type in a .26 grid has nowhere to go but over its neighbour.

   It has to be declared HERE, on the root, not on the element that has
   the problem. .pl-plan-window{-webkit-text-size-adjust:100%} shipped
   first and changed nothing on the device: WebKit resolves the
   autosizing decision against the document, so a declaration on a
   descendant does not call it off. home-section.css sets exactly this
   rule on html for the same reason, and that page renders correctly on
   the same phone -- which is the only evidence available here, because
   the pass does not run in a desktop browser's phone emulation at all.

   100%, not none: it means "render text at the size I asked for" and
   leaves the reader's own page zoom alone. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}

:root{
  /* The home page's inset model, so both pages measure their left edge
     the same way. This is the DESKTOP half of it; the phone half is the
     rule right under this block. */
  --hx-inset:clamp(44px,8vw,120px);

  /* The bridge. Every --ink / --cream / --peach in planning.css now
     resolves to a home-page value. */
  --ink:#171413;
  --ink-2:#0F0D0C;
  --cream:#F6F1EA;
  --peach:#B28479;

  --pl-accent:#B28479;
  /* The second marker. Already in the plan mock, where it is the colour of
     an "on track" tag -- so the quarter is annotated in the colour the
     quarter's own tags already use. */
  --pl-ink-2:#A9B8C6;
  --pl-ground:#171413;
  --pl-ground-dark:#0F0D0C;
}

/* ============================== 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. There is no
   .lf-block here, so they are restated -- the numbers are the home
   page's rendered values, not new ones. */
/* .72 is the home page's value, where the nav sits over a still photograph
   whose top edge is reliably dark. Here it sits over a VIDEO, and measured
   against the brightest frame tone behind it -- rgb(111,86,66), a lit patch
   of road -- .72 came to 4.04:1, under the 4.5 a 15px link needs. .82 is
   4.91:1 against that same tone. The masthead scrim below does the other
   half of the work, and matters more: a pixel sample only ever proves one
   frame, and the frame is moving. */
.n12-nav a{color:rgba(246,241,234,.82)}

/* ================================ the wrap ==============================
   planning.css centres a 1160px column; the home page insets a full-width
   band. The band is what makes the left edge agree between the two, and
   what lets a section's background run edge to edge. */
.pl-wrap{width:100%;max-width:none;margin:0;padding:0 var(--hx-inset)}

/* AND ON A PHONE THE INSET IS THE GUTTER, which is the home page's whole
   rule: mobile-n12.css sets exactly this at 1024, and hero-v1 takes the
   gutter to 32 there and 20 below 640.

   It has to be restated here because this file loads after mobile-n12
   and the :root clamp above was winning, so the two pages measured their
   edges differently on the one screen where it costs something -- 44
   against 20 at 393, which is 12% of the screen spent on nothing, and
   two visibly different left edges if you moved between the pages. */
@media(max-width:1024px){
  :root{--hx-inset:var(--n12-gutter,32px)}
}

/* =============================== type ==================================
   Section heads land on the home page's exact clamp. The hero's h1 is
   larger than anything on the home page -- it is the one h1 on the site,
   and a page hero can carry it -- but it came down from 70px, which was
   bigger than the wordmark and out of scale with everything under it. */
/* Headings are League Spartan, full stop.

   .pl-beats h3 was rendering in Questrial at 700 -- its rule set the size,
   line-height and letter-spacing but never the family, so it fell back to
   the body font and synthesised a bold. That is a bug waiting to repeat
   every time a new component adds a heading, so the family is declared
   once here rather than component by component. */
h1,h2,h3{font-family:'League Spartan',sans-serif;font-weight:700}

.pl-eyebrow{
  display:block;
  font-family:'Questrial',sans-serif;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:rgba(246,241,234,.7);
}
.pl-hero h1{
  margin:14px 0 18px;
  font-size:clamp(40px,4.4vw,56px);
  line-height:1.02;letter-spacing:-.035em;
}
.pl-process-head h2,
.pl-section-head h2,
.pl-fail h2,
.pl-final h2{
  margin:0;
  font-size:clamp(26px,2.65vw,38px);
  line-height:1.04;letter-spacing:-.035em;
  /* Lowercase on every section head, as on the home page. It was set on
     .pl-final h2 and .pl-section-head h2 by planning.css and not on
     .pl-fail h2 or .pl-why-bar h2 -- invisible while the copy happens to
     be typed lowercase, and a difference the moment it is not. */
  text-transform:lowercase;
}
.pl-why-bar h2{text-transform:lowercase}
.pl-hero p{
  font-size:16px;line-height:1.6;color:rgba(246,241,234,.72);
}
/* 18px on the section subheads, 15 on the page's: the home page's .st-sub
   and .tr-sub are both 15/1.6 at .68. */
.pl-sub,
.pl-section-head p,
.pl-process-head p,
.pl-final p{
  margin:18px 0 0;max-width:62ch;
  font-size:15px;line-height:1.6;color:rgba(246,241,234,.68);
}

/* ============================== the hero ===============================
   496px was shorter than the content wanted and shorter than the home
   page's, which fills the viewport. The header is inside it now, absolute
   over the video, exactly as the home page's sits over its photograph. */
/* THE SPLIT.

   The old hero was 684px of which 301 -- nearly half -- was empty video
   below the buttons. That was not a height problem, it was a layout bug:
   .pl-hero is display:block, and .pl-hero-wrap asks for height:100% and
   align-items:flex-end. A percentage height against an auto-height parent
   resolves to auto, so the wrap never filled the hero and flex-end had
   nothing to align against. The copy sat wherever its 150px top padding
   put it, and the rest was dead.

   Making .pl-hero a flex column with the wrap on flex:1 is what actually
   fixes it. Everything below is then a framing decision. */
/* ====================== the hero and the plan =========================

   No picture up here. The hero opens on type and the plan window rises
   into the band above it, which is why these two sections still share a
   wrapper: the overlap crosses their boundary, so the ground has to be
   continuous and owned by neither of them.

   --pl-hero-h stays a variable because the phone tiers set it and
   .pl-hero reads it; there is no longer a stage height derived from it. */
.pl-top{
  --pl-hero-h:min(clamp(500px, 12.5vw + 360px, 648px), 94vh);
  /* NO isolation. It made .pl-top a stacking context, and the masthead
     -- position:fixed, with the full-screen mobile menu inside it --
     lives in .pl-hero, which is a child of .pl-top. A fixed element
     cannot escape a stacking context, so both were being painted
     INSIDE this block rather than over the page: scrolled down to the
     "why so short?" band, .pl-why-bar was painted over the masthead and
     swallowed taps on the menu button, and when the menu did open the
     page was drawn on top of it.

     Exactly the fault the about page had, where the same two
     declarations were on .ab12-top for the same reason -- see the note
     there. The background this rule carries needs no stacking context
     of its own; the children inside .pl-top that do overlap each other
     carry their own z-index and still order correctly against one
     another without it. */
  position:relative;
  /* The darker of the page's two grounds, #0F0D0C. With no picture the
     band was carrying the lighter one for no reason except that the
     video used to be mixed against it. The plan window swaps the other
     way in exchange -- see .pl-plan-window -- so the two do not end up
     the same colour. */
  background:var(--pl-ground-dark);
}
/* Positioned but WITHOUT a z-index, and that is deliberate. With
   z-index:1 each section made a stacking context, which sealed its
   children in: the board is a child of .pl-top, so nothing inside a
   sealed section -- the nav, the buttons, the annotations -- could ever
   be raised above it. Dropping the z-index lets those elements compete
   with the board directly in .pl-top's own context, which is the only
   way a canvas that covers both bands can still have live controls
   under it. */
.pl-top > section{position:relative}

.pl-hero{
  display:flex;flex-direction:column;
  /* Height tied to WIDTH, not viewport height, and this is load-bearing.
     object-fit:cover scales the footage to the box width, so the rendered
     frame is always width x 0.5625 -- but the box height was capped at
     520px. The wider the screen, the bigger the gap between the two, and
     the deeper the top crop: measured 23.6% of the frame at 1440, 29.0% at
     1920 and 35.8% at 2560, from one unchanged object-position.

     The figure's head starts 14.3% down the v3 frame (found by sampling
     the silhouette against the sky), so anything past ~1500px was
     decapitating her while 1440 looked fine. A vw height keeps box and
     frame in the same ratio, which makes the crop a constant 17%
     everywhere instead of something that grows with the monitor.

     The 74vh guard is for short wide windows, where a vw height would
     otherwise push the copy bar off the screen. */
  /* SHORTER, and above all flatter.

     42vw was a pure ratio: the box grew as fast as the screen did, so the
     crop held perfectly and the hero got taller forever. At 1920 that was
     806px holding 233px of copy, with 196px of empty sky above it and 274
     below -- a third of a 4K screen spent on nothing. The vw term is doing
     one job only, which is keeping the crop off the figure's head, and it
     does not need a full ratio to do it.

     12.5vw plus a constant is nearly flat by comparison: 520 at 1280, 540
     at 1440, 600 at 1920 against 806. The crop deepens as the box gets
     relatively shorter -- 6% of the frame at 1280, 9% at 1920, 12% at the
     648 ceiling -- all of it still clear of the head at 14.3%. Past 2200
     it would not be, so object-position comes up again there. */
  min-height:var(--pl-hero-h);
  height:auto;overflow:visible;
  /* planning.css sets a poster image here as the reduced-motion fallback.
     In the split that image would sit behind the solid left panel at a crop
     that does not match the video's, so it goes -- the <video> element's own
     poster attribute covers the same job and honours the same object-fit and
     object-position, which means the still and the moving frame are
     identical rather than merely similar. */
  background:transparent;background-image:none;
}
/* ========================= the whiteboard =============================

   A canvas over the hero and nothing else. It sits ABOVE the copy, so
   marks land on top of the headline the way they would on a board, and
   BELOW the masthead, so the nav stays clickable -- the copy itself
   carries no links, so covering it costs nothing.

   Inert until the script says otherwise, so a browser that never runs
   it gets an empty canvas rather than a marker cursor over a surface
   that does nothing. */
/* THE LAYER ORDER, all of it in .pl-top's stacking context:

     auto  the copy and the plan. Both are positioned and the plan comes
           later in the DOM, so it still paints over the hero and the
           window still breaks the fold. Neither needs a z-index for
           that, and carrying one was actively harmful: a positioned
           element WITH a z-index makes a stacking context, which sealed
           the nav, the buttons and the annotations inside it where
           nothing could raise them above a board painted at .pl-top
           level.
     3     the board, so ink lands ON the plan rather than under it
     5     the things that must stay live under it
     6     the eraser */
.pl-board{
  position:absolute;inset:0;z-index:3;
  pointer-events:none;
}
/* Drawing must never cost a click. Each of these sits above the board,
   which means you cannot draw over them either -- the right trade: a
   button you can press beats a button you can scribble on. */
.pl-actions.pl-plan-actions,
.pl-tour .pl-plan-outcomes article{position:relative;z-index:5}
/* The masthead gets the z-index and NOT position:relative. It is already
   absolutely positioned -- laid over the band, which is why
   .pl-hero-wrap starts at y=0 and its padding-top is the nav clearance.
   Putting it back in the flow drops the whole hero by its own 104px and
   lands the copy on the plan window. That has now happened twice.

   The value is 70, not 5. Five is all the board needs, but the mobile
   menu is a fixed full-screen panel at 60 and a SIBLING of the header,
   so anything lower paints the masthead under it: the burger's X was
   animating correctly the whole time, behind an opaque panel, leaving
   the phone menu with no visible way out. 70 is what mobile-n12.css
   sets for exactly that reason; this rule only has to not undercut it. */
.pl-hero .n12-head{z-index:70}
/* Only where there is a real pointer and room to use it. On a phone the
   hero is 404px of a scrolling page, and a drawing surface across it
   would swallow every swipe. */
@media (pointer:fine) and (min-width:1024px){
  .pl-board.is-on{
    pointer-events:auto;
    cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><g stroke-linejoin='round' stroke-width='1.3'><path d='M3 27l1.5-5 3.5 3.5L3 27z' fill='%23B28479' stroke='%23B28479'/><path d='M6.3 20.2L18.7 7.8l3.5 3.5L9.8 23.7z' fill='%23E4BCAC' stroke='%231a1614'/><path d='M19.5 7l2.5-2.5a1.6 1.6 0 012.3 0l1.2 1.2a1.6 1.6 0 010 2.3L23 10.5z' fill='%23F6F1EA' stroke='%231a1614'/></g></svg>") 3 27, crosshair;
  }
}
/* The masthead stays above the board so its links keep working. */
/* z-index only. The masthead is already absolutely positioned -- it is
   laid OVER the band, which is why .pl-hero-wrap starts at y=0 and its
   padding-top is the nav clearance. Adding position:relative here put it
   back in the flow and pushed the whole hero down by its own 104px: the
   copy landed on the plan window and the supporting line's contrast fell
   to 1.95:1 against it. */

/* The eraser only appears once there is something to erase. */
.pl-board-clear{
  /* Top right, under the masthead -- not the bottom of the hero, which
     is the plan window's: .pl-tour spans the full band width and rises
     125px into it, so a button down there is unclickable even where the
     window itself is not drawn. */
  position:absolute;right:var(--hx-inset);top:118px;z-index:6;
  display:inline-flex;align-items:center;justify-content:center;
  width:52px;height:52px;padding:0;
  background:rgba(23,20,19,.7);border:1px solid var(--n12-line);border-radius:999px;
  color:rgba(246,241,234,.7);cursor:pointer;
  transition:color .2s ease,border-color .2s ease,background-color .2s ease;
}
.pl-board-clear[hidden]{display:none}
.pl-board-clear svg{
  width:26px;height:26px;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;
}
.pl-board-clear:hover{
  color:var(--n12-cream);border-color:rgba(246,241,234,.32);background:rgba(23,20,19,.9);
}
.pl-board-clear:focus-visible{outline:2px solid var(--pl-accent);outline-offset:3px}

/* THE COPY SITS HIGH IN THE BAND, not centred in it, because the plan
   window rises into the bottom of it and needs that room clear. That is
   align-items, the vertical axis; justify-content is the horizontal one
   and it centres, so the block sits on the same axis as the plan
   directly under it. Both are centred on the viewport -- this wrap is a
   centred 1160 column and .pl-tour is centred on the window -- so the
   headline, the window and the two annotations all share one middle. */
.pl-hero-wrap{
  flex:1;height:auto;z-index:auto;
  align-items:flex-start;
  /* Centred on the same axis as the plan. align-items is the vertical
     job -- the copy sits high so the window has room to rise into the
     band -- and justify-content is the horizontal one. The wrap below
     1280 is the page's own full-bleed inset and above it is the plan's
     own track, and both are symmetric about the viewport, so centring
     inside either lands on the window's centre. */
  justify-content:center;
  /* 148, and it has to be: the masthead is laid OVER the picture, not
     stacked above it, so this wrap starts at y=0 and the padding is the
     only thing holding the eyebrow off the nav. While align-items was
     stuck on centre that did not show -- centring pushed the block clear
     regardless, which is exactly why 88 could be cut to 64 with nothing
     appearing to break.

     128 now, down from 148: 104 of nav plus 24 of air rather than 44.
     Her call off a rendered ladder at 148/128/112, and the software
     hero takes the same value in the same pass -- the two were matched
     at 148 and stay matched. The phone rule was already 128, so this is
     desktop coming down to meet it. */
  padding-top:128px;padding-bottom:38px;

  /* THE SAME COLUMN THE SOFTWARE PAGE'S HERO USES.

     Not the same padding -- the same SHAPE. This page's .pl-wrap is full
     bleed with a fixed inset, so its copy sat at roughly 120px whatever
     the screen; the software hero is a centred 1160 column, so its copy
     walks right as the window grows. A fixed 25px correction matched them
     at 1440 and nowhere else: 67px apart at 1280, 235px apart at 1920.

     The hero alone takes the centred column. Everything below keeps the
     page's own full-bleed inset, which means on a very wide screen the
     headline sits further in than the section headings under it. That is
     the trade for the two heroes matching. */
  width:min(1160px,calc(100% - 48px));
  margin-inline:auto;padding-left:0;padding-right:0;
}
.pl-hero-copy{max-width:none}
.pl-hero h1{
  margin:12px 0 0;
  /* 64 at the top end, down from 82. It is still the largest type on the
     site, which is right for the one h1 on a page hero, but at 82 it was
     bigger than the wordmark and louder than the picture behind it. */
  font-size:var(--n12-h1);
}
.pl-hero-copy{text-align:center}
/* THE SUPPORTING LINE IS IN THE ANNOTATION HAND.

   Caveat 700 at the colour the margin notes beside the plan use, which
   is the point: it reads as someone captioning the headline rather than
   as a second sentence from the company, and that is the device the
   whole plan section is built on. It also earns the drawn arrow under
   it -- ink under a line already written in ink.

   30px rather than the notes' 28, because this one is in the hero and
   has nothing beside it to be measured against. No measure on it: 46ch
   broke a 57-character sentence across two lines, which is what a
   measure is for when the copy is a paragraph and exactly wrong when it
   is one line. */
.pl-hero-copy p{
  /* 2, not 14. Caveat carries a lot of leading above its glyphs, so the
     declared margin is only part of what you see -- at 14 the optical
     gap was closer to 30 and the line read as a separate statement
     rather than as something written under the headline. */
  margin:2px auto 0;max-width:none;
  font-family:'Caveat',cursive;font-weight:700;
  font-size:30px;line-height:1.14;
  color:#E8CDC2;
}
/* ===================== the drawn ink in the hero =======================

   The same hand as the plan's rings and arrows, and the same mechanics:
   a wavering path, its length written into --len, and stroke-dashoffset
   transitioned from that length to zero so the stroke draws itself.

   overflow:visible on both, because the arrow reaches well outside the
   box of the word it hangs off. */
.pl-hero-ink{
  position:absolute;overflow:visible;pointer-events:none;
  fill:none;
}
.pl-hero-ink path{
  fill:none;stroke:var(--pl-accent);
  stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:var(--len,1200);
  stroke-dashoffset:var(--len,1200);
  transition:stroke-dashoffset .85s cubic-bezier(.22,1,.36,1) var(--delay,0s);
}
/* Measurement happens with transitions off. Writing --len while
   stroke-dashoffset is transitionable animates it from the fallback to
   the real length, and on the way it passes through offsets that wrap
   the dash pattern and draw a sliding segment -- which is exactly the
   flash the plan's ink had three separate attempts at fixing. */
.pl-hero-ink.is-setting path{transition:none}
.pl-hero-ink.is-drawn path{stroke-dashoffset:0}
/* The arrowhead fades rather than draws: a dash animation runs straight
   through the M jump between a line and its head, so a single path would
   draw the head in pieces from the wrong end. */
.pl-hero-ink path.pl-ink-head{
  stroke-dasharray:none;stroke-dashoffset:0;
  opacity:0;transition:opacity .3s ease var(--delay,0s);
}
.pl-hero-ink.is-drawn path.pl-ink-head{opacity:1}
@media(prefers-reduced-motion:reduce){
  .pl-hero-ink path,.pl-hero-ink path.pl-ink-head{transition:none}
}
/* The struck underline under the headline is gone. It was a second mark
   doing the same job the handwritten supporting line now does, and two
   hand-drawn things stacked on the headline was one too many. */

/* AND THE LINE WRITES ITSELF, the same way the two annotations beside
   the plan do: a clip-path opened from the left, not a fade. Same
   easing, and the inset is generous top and bottom for the same reason
   -- Caveat's ascenders and descenders run well past the line box and a
   tight clip shears them.

   Scoped to .rv, which an inline script puts on <html> before anything
   paints. If that script never runs there is no JS to open the clip
   either, so the line simply arrives written. */
.rv .pl-hero-copy p{clip-path:inset(-26% 100% -34% 0)}
.rv .pl-hero-copy p.is-written{
  clip-path:inset(-26% -6% -34% 0);
  transition:clip-path .95s cubic-bezier(.36,.82,.5,1) .3s;
}
@media(prefers-reduced-motion:reduce){
  .rv .pl-hero-copy p,
  .rv .pl-hero-copy p.is-written{clip-path:none;transition:none}
}

/* THE ARROW IS BELOW THE COPY, not beside it. Off to the right it hung
   from the end of the supporting line and pointed into the plan window's
   right half, pulling the eye off the axis everything else shares.

   54px tall and no more, and this is a hard constraint rather than a
   taste: there are 75px between the copy and the window, and .pl-tour
   carries z-index:2 against the hero's 1, so the window paints over
   anything the hero puts below that. The first version at 88px had its
   entire lower half, arrowhead included, hidden behind the window. */
.pl-hero-down{
  display:flex;justify-content:center;
  /* 4, not 12: Caveat's line box is taller than the 17px sans it
     replaced, so the copy grew downward and the arrow came within 4px
     of the window. The gap is a fixed 75px and the arrow has to live
     inside it. */
  margin-top:4px;
}
.pl-hero-down svg{position:static;width:38px;height:48px}
/* THE PHONE'S RING.

   The alley ink's counterpart below 1280, and on the same switch: where
   the desktop draws a ring and an arrow beside the plan, the phone draws
   the ring on it, when a note is tapped.

   It hangs in .pl-stage-wrap rather than in .pl-tour-stage because the
   stage clips -- the window is scaled from its top left and its unscaled
   width runs off the right -- and the ring's left stroke carries past the
   top corner, which is exactly the part that would be cut. */
.pl-note-ring{display:none}
.pl-note-hint{display:none}
/* To 1279, not 1024: the alley ink switches on at 1280, so anything short
   of that is a width with no mark of either kind. A tablet held sideways
   was the gap. */
@media(max-width:1279px){
  .pl-stage-wrap{position:relative}
  .pl-note-ring{
    display:block;position:absolute;left:0;top:0;z-index:3;
    pointer-events:none;overflow:visible;
  }
  .pl-note-ring path{
    fill:none;stroke:var(--pl-accent);stroke-width:1.7;
    stroke-linecap:round;stroke-linejoin:round;
    stroke-dasharray:var(--len,900) var(--len,900);
    opacity:0;transition:opacity .18s ease,stroke-dashoffset .72s cubic-bezier(.3,.7,.3,1);
  }
  .pl-note-ring.is-on path{opacity:1}
  /* The quarter's ring in the pale blue its note and the plan's own
     quarterly figures are already set in. */
  .pl-note-ring.is-alt path{stroke:var(--pl-ink-2)}
  /* Lengths are written under this, for the reason the ink layer spells
     out: a transitioned dashoffset animates through every value between
     the old and the new, and with a real dash array those values are a
     segment of the ring sliding along it. */
  .pl-note-ring.is-setting path{transition:none}
  @media(prefers-reduced-motion:reduce){
    .pl-note-ring path{transition:opacity .18s ease}
  }

  /* The one line of instruction on the page, and it earns it: a cursor
     finds the behaviour by passing over a note, a finger has nothing to
     hover with. Gone for good the first time a note is tapped. */
  .pl-note-hint{
    /* The box stays when the line fades, so tapping a note does not jerk
       the pair upward under the finger that tapped it. */
    display:block;order:2;margin:5px 0 0;text-align:center;
    /* 12.5, up from 11.5. It is a sentence telling you what to do --
       "tap a note to see where it comes from" -- not a tracked label,
       and the device sweep had it as the smallest piece of instruction
       on the site. The phone tier below already used 12.5; this brings
       the tablet range up to meet it. */
    font-size:12.5px;line-height:1.4;letter-spacing:.02em;
    /* .52, not the .4 it started at. Measured over its own ground it was
       3.51:1, and this is small type -- the one thing on the page that
       failed AA. .52 is 5.1:1. */
    color:rgba(246,241,234,.52);transition:opacity .3s ease;
  }
  .pl-tour.is-tapped .pl-note-hint{opacity:0}
}
/* It used to be hidden here, because the plan was a full screen further
   down and an arrow pointing at nothing is just a mark. It is directly
   beneath now, so the arrow has something to point at again -- and it is
   what fills the run of empty ground the shrinking mock left between the
   supporting line and the window.

   Narrower and longer than the desktop one: 30 wide so it stays a mark
   rather than a shape, 56 tall so it spans most of the way to the
   window. The desktop constraint that capped it at 54 -- the plan window
   painting over anything past a fixed 75px gap -- does not apply here,
   because the hero and the plan band are both transparent over one
   .pl-top ground and the boundary between them is not a visible edge. */
@media(max-width:900px){
  .pl-hero-down svg{width:30px;height:56px}
}

/* THE ASK, under the plan. Centred on the window, which is the axis the
   whole section already uses. The top margin is larger than the hero's
   was because this is closing a section rather than sitting inside a
   block of copy. */
/* .pl-actions.pl-plan-actions, not .pl-plan-actions: the base .pl-actions
   rule is declared further down this file with its own margin-top:34px,
   and at equal specificity the later one wins. Written as one class the
   margin here did nothing at all -- the measured gap came back as exactly
   34px, which is what gave it away. */
.pl-actions.pl-plan-actions{
  justify-content:center;
  margin-top:58px;
}

/* The black bar under the video used to carry the supporting line and both
   buttons. It is gone: it read as a second thing rather than the rest of
   the first one, and it put a hard horizontal edge across the only moving
   image on the page. All four elements are on the picture now. */

/* No picture in the hero at all now, so no framing, no scrim and no
   stage. Everything that used to live between here and .pl-actions --
   the zoom, the left-edge pan that walked the car off frame, the
   masthead wash, the left wash anchored to the copy column, the fade
   into the ground -- existed only to make type legible over a
   photograph and to hide the seam where the photograph stopped. With a
   flat ground there is no seam and nothing to fight. */
.pl-actions{
  display:flex;align-items:center;gap:28px;flex-wrap:wrap;margin-top:34px;
}
/* ============================= the bands ===============================
   118px top and bottom, which is the home page's where-to-start and
   in-practice rhythm, and the grounds alternate the way they do there:
   black hero, grey plan, black process, grey proof, grey close. */
.pl-included{
  padding:118px 0;
  /* TRANSPARENT, not the ground colour. The ground now belongs to
     .pl-top, and the stage is painted behind both bands -- an opaque
     background here draws a hard horizontal edge straight across the
     picture at the hero's bottom, which is the exact seam the stage
     exists to remove. planning.css sets this band solid twice, and the
     earlier override in this file lost to the one that used to live
     here. */
  background:transparent;
  /* planning.css also puts a 1px rule on the top of this band. It was
     there to divide the hero from the plan, and there is nothing left to
     divide. */
  border-top:0;
}
.pl-sessions{
  padding:118px 0;
  background:var(--pl-ground-dark);
}
/* Seven bands now, still alternating all the way down: bar dark, plan
   grey, how-it-works dark, why-four grey, choose-your-session dark,
   before-you-book grey, proof dark, close on its photograph. */
/* .pl-proof was the evidence band's ground. The band is gone. */

.pl-section-head,
.pl-process-head{max-width:none;margin-bottom:0}

/* ====================== what you leave with ============================ */

/* The note under the plan. Three short blocks: why a plan has to be looked
   at, what we do about it, and the link. */
/* No measure cap: it sits inside .pl-tour's alleys, so letting it run full
   width makes it exactly the plan's width, left edge and right. A 86ch cap
   stopped it about 60px short of the plan's right edge, which read as a
   column that had not quite been lined up. */
/* ========================== why plans fail ============================
   The argument the product rests on, on its own ground.

   The picture is the hero's own poster frame -- the same still the video
   falls back to -- so it costs nothing to load: the browser already has
   it. Cropped low and left, which puts her on the right of the band with
   the sun behind her and leaves the left two thirds for the type.

   Treated like the close rather than like the why-four-hours divider.
   That band runs at .55 opacity because its photograph is dust and
   mid-tones; this one has a sun in it, and the body copy here is 17px at
   70% cream, which needs the background under 0.09 luminance to clear
   4.5:1. .44 brightness under a .78 wash gets there with room. */
/* 118, the page's band rhythm and the home page's. Measured across both
   pages the planning bands were running 104, 118, 104, 118 and 132 while
   every home band except the before/after ran 118 -- four different
   depths on one page, none of them signifying anything. */
.pl-fail{
  position:relative;isolation:isolate;
  padding:118px 0;
  background:var(--pl-ground-dark);
  overflow:hidden;
}
/* THE LOOP LIVES HERE NOW. The hero keeps the frame as a still and this
   band gets the motion, which is the right way round: the hero's job is
   to hold a headline and hand you to the plan, and this one is a claim
   that benefits from something moving slowly behind it. Same file, same
   poster, same single decode -- it has just moved down the page. */
/* NOT FULL BLEED ANY MORE. The footage occupies the right 64% of the
   band and dissolves into the ground on its way left.

   Two things come out of the narrower box. It is much closer to the
   frame's own 1.78 ratio -- 1.56 at 1440 against 5.04 across the whole
   band -- so cover keeps nearly all of the frame height instead of 35%
   of it, and far more of her is in shot. And the left half of the band
   is clean ground again, which is where the heading and the copy start.

   The dissolve is a mask, not an overlay: an overlay would darken the
   footage toward the left and still leave a rectangle edge at 36%,
   where a mask removes the pixels entirely and there is nothing to see
   an edge of. */
.pl-fail-video{
  position:absolute;top:0;right:0;bottom:0;left:auto;
  width:64%;height:100%;
  /* The dissolve reaches further right than it did -- fully clear at the
     box's left edge, still only a fifth of the way in at 30%, and not
     solid until 74%. More of the band is clean ground and the picture
     arrives later, which is what keeps the type off it.

     It went further than this for one revision -- clear to 12%, solid
     only at 86% -- and that was too far: the picture started past the
     middle of the band and stopped being a picture. Back to these. */
  -webkit-mask-image:linear-gradient(90deg,
    transparent 0%, rgba(0,0,0,.18) 30%, rgba(0,0,0,.62) 54%, #000 74%);
  mask-image:linear-gradient(90deg,
    transparent 0%, rgba(0,0,0,.18) 30%, rgba(0,0,0,.62) 54%, #000 74%);
  object-fit:cover;
  /* 14%, so her head is in the band. This is a wide, shallow box -- 2.57:1
     at 1280 and 3.85 at 1920 -- so it keeps only 69% down to 46% of the
     frame height, and 62% put the window at 22.9-85.9% and cut her off at
     the shoulders. Her head starts at 14.3%; at 14% the window opens at
     7.6% even at 1920, which leaves sky above her at every width. X is
     inert here: cover scales this frame to the box WIDTH, so there is no
     horizontal overflow to pan through. */
  /* The box is close enough to the frame's own ratio that cover keeps
     about 92% of the height -- all of her, plus a lot of empty road
     under her boots. The zoom takes it in to roughly knees-up.

     A scale rather than a narrower box, so the composition of the band
     does not move: the mask, the width and the left edge of the picture
     all stay where they are. The origin rides at the very top because
     scaling about the centre would push her head out of frame -- at
     1.25 about 2%, her head lands at 14% of the box and the cut falls
     at her knees. */
  object-position:50% 30%;
  transform:scale(1.25);
  /* The origin is on the RIGHT edge, not the centre, so the whole 25% of
     the zoom's crop comes off the left instead of 12.5% off each side.
     The frame's right edge stays flush with the box and the car keeps
     its full length; what goes is desert on the left, which the mask is
     dissolving anyway. Visible frame: 20% to 100% of the width. */
  transform-origin:100% 2%;
  z-index:0;pointer-events:none;
  /* Lifted from .44/.40. It was pushed that far back because the picture
     ran under the type at full bleed; the type is on clean ground now,
     so the footage can be seen. */
  /* saturate(.6) brightness(.74) is the home close band's exact
     treatment, and with the wash now being the page's own ground rather
     than a tint, the filter is the only thing setting the tone.

     The -18 is the last of it. The footage is simply warmer than the
     home page's photograph, so matched treatments still left this band
     at hue 23 against its 13. Rotating the PICTURE works where rotating
     the old tinted wash did not: the wash is neutral now, so the filter
     has the whole of what you see to act on -- and it moves only the
     picture, never the part of the band that is meant to be page.

     Brightness is .92 now, with the closing band, for the same reason:
     .74 over this page's wash left the footage too near its ground to
     read as footage. Saturation and the rotation are untouched, so the
     tone this comment describes is unchanged -- only the level moves. */
  filter:saturate(.6) brightness(.92) hue-rotate(-18deg);
}
/* And the wash comes off the picture entirely. It only has to carry the
   right-hand end of the lines that reach into the footage, so it is a
   gradient that follows the mask rather than a flat sheet over the band
   -- nothing at the left, where there is no picture to darken. */
/* THE WASH IS THE BAND'S OWN GROUND, WHICH IS THE HOME PAGE'S RECIPE.

   Two wrong turns got here. First the wash was a neutral #0F0D0C, and
   the band measured hue 24 against the home page's 11-13 -- a neutral
   wash over warm footage darkens it without moving it, so the band was
   whatever the camera was. Then it was a red tint, which moved the hue
   but put a cast over the whole band including the part that is meant to
   be plain page.

   The home page's close band does neither: rgba(23,20,19,.7) is its own
   section colour at 70%, over a picture on saturate(.6) brightness(.74).
   The tone comes from the photograph and the filter; the wash only ever
   darkens toward the page.

   So this is the same: the band's own ground, running from fully
   transparent where the picture is meant to be itself to nearly solid
   where the type sits. At the clear end there is no wash at all, and at
   the heavy end the colour is exactly the page's, which is what makes
   the picture read as dissolving into the band rather than sitting
   behind a film. */
.pl-fail-shade{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(90deg,
    rgba(15,13,12,0) 0%,
    rgba(15,13,12,.34) 30%,
    rgba(15,13,12,.72) 58%,
    rgba(15,13,12,.84) 100%);
}
/* THE VERTICAL LINES ON THE VIDEO ARE BANDING, not an overlay -- nothing
   repeating paints over it; the only layer above is the shade gradient
   above, and that has no repeat.

   The sky in this footage is a long, almost flat gradient, and the video
   carries saturate(.6) brightness(.92) hue-rotate(-18deg). A hue rotation
   is a matrix multiply per pixel: it takes values that were one step
   apart and lands several of them on the same output level, so the soft
   ramp resolves into flat plates with visible edges between them. On a
   compressed source those edges follow the macroblock grid, which is why
   they read as lines rather than as a soft stepping.

   Dither fixes it where no amount of regrading will: a little noise at a
   fraction of a level breaks the plates up so the eye reconstructs the
   ramp. feTurbulence, tiled, at about 4% over the picture -- invisible
   as grain at this weight, and enough to carry the gradient. */
.pl-fail-shade::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  opacity:.055;
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/>\
</filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  background-size:160px 160px;
  background-repeat:repeat;
}
/* No centred column: .pl-wrap on its own, which is the same full-bleed
   inset every band below this one uses. Centred on 1000px it started at
   140px at 1280, 220 at 1440 and 460 at 1920, while how-it-works started
   at 102, 115 and 120 -- the two sections never shared an edge, and at
   1920 they were 340px apart. */
.pl-fail-bar{position:relative;z-index:1}
.pl-fail .pl-eyebrow{color:#E4BCAC}
/* The how-it-works scale exactly, and taken from the shared rules at the
   top of this file rather than restated, so the two bands stay in step if
   that scale ever moves. The heading needed adding to the .pl-section-head
   h2 group by hand: this band's h2 is not inside a .pl-section-head, so it
   was falling through to the browser default and rendering about 13px
   smaller than the how-it-works heading it was supposed to match. The
   paragraphs carry .pl-sub in the markup, so those were already right.
   Only the measure and the rhythm are set here. */
/* The heading runs the full width of the band. The paragraphs cannot any
   more, and this is the one place the brief had to give.

   When the picture was full bleed under a .78 wash, full-width copy
   measured 6.6-7.1:1 and the only cost was a long line. The picture is
   now bright and on the right, and the same copy measured 3.9-4.2 with
   the citation down at 3.35 -- text running across her shoulder. The
   options were to darken the footage again, which is the opposite of
   what was asked for, or to stop the lines before they reach her.

   min(86ch, 72%) is as wide as it goes, and the limit is not gradual.
   Swept five measures against the contrast: 54% reads 6.29-6.56:1, 60%
   5.60-6.42, 66% 5.34-6.32, 72% 5.46-6.35 -- all comfortable -- and
   then removing the cap entirely falls off a cliff to 3.38-4.26. That
   is the edge of the dissolve rather than a gradual decline: inside it
   the lines are on clean ground, past it they are on the lit frame. 72%
   sits just inside; 100% is well past. */
/* 0, like every other section head on the page. how-it-works, pricing
   and the close all run their eyebrow straight into the heading and let
   the heading's own line box do the spacing; this band was carrying 16px
   of its own and sitting looser than all of them. */
.pl-fail h2{margin:0;max-width:none}
.pl-fail .pl-sub{max-width:min(86ch,72%)}
.pl-fail .pl-sub + .pl-sub{margin-top:16px}
.pl-fail-link{margin-top:26px}
/* Colour, underline and hover now come from cta-n12.css, which owns the
   site's three CTA tiers. This link goes to /software -- a different
   page -- so it is tertiary and clay.

   It was #E4BCAC, which is PEACH, and a comment further down this file
   has been describing these two as "clay" while they were peach the
   whole time. Peach is not a site colour: clay #B28479 appears 48 times
   across all three pages, peach 42 of which 38 are the software page's
   own two files.

   The declarations are deleted here rather than overridden there,
   because this file loads AFTER cta-n12.css and would have won. */
.pl-fail-link a{white-space:nowrap}
/* A COMFORTABLE THUMB ON THESE TWO.

   Both band links are a 15px line of text in a paragraph of their own --
   a 15px tap target on a phone, where the guidance is around 44. The
   padding grows the hit area and the equal negative margin gives the
   layout back, so nothing above or below them moves: measured, the line
   sits where it did and the target is 35px instead of 15.

   inline-block because padding on an inline box does not affect what it
   catches vertically. */
/* And they carry the rule .pl-btn-text and the home page's .cl-link
   carry. All four are the same thing -- the quiet link beside or under
   an ask -- and these two were the only ones without it. */
/* The cream hairline is gone with the cream: cta-n12.css draws these in
   clay at .32, so the underline matches the colour instead of contradicting
   it. Only the tap-target padding below is still this file's business. */
/* inline-FLEX, not inline-block. The padding here is the tap-target
   trick and it still works either way -- but inline-block gives
   align-items nothing to act on, so the arrow landed on the text
   baseline and sat 3px above the letters' middle. Measured. */
/* SYMMETRICAL, 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 .pl-btn-text's middle 3px above the
   primary's in the same centred flex row. */
.pl-fail-link a,
.pl-why-link a,
.pl-actions .pl-btn-text{display:inline-flex;align-items:center;padding:7px 0;margin:-7px 0}
/* .pl-actions is a flex row and the text button sits beside a 44px
   primary; the negative margin keeps it on the primary's centre line. */
.pl-actions .pl-btn-text{align-self:center}

/* No margin to annotate into below 1025, so the ink does not exist there.
   An empty inline SVG still has a default 300x150 box, which was pushing
   a 320px phone into horizontal scroll. */
.pl-ink{display:none}

/* ======================= the plan, guided ==============================
   Above 1024 the four points become a rail and the plan sits beside them,
   sticky. The active point outlines the region of the plan it is
   describing, which turns the mock from a picture into the thing the
   section is actually about.

   Below 1025 nothing changes: the four columns and the mock stack exactly
   as before, because a rail needs a second column to point at. */
/* Between the tablet stack and the diagram there is now a band where the
   plan is beside nothing: the annotated layout needs roughly 1280px before
   the alleys are wide enough for an arrow to be a line rather than a stub,
   and the plan still has room to be legible. Below that, the points stack
   under it exactly as they do on a tablet. */
/* 1025 to 1279 used to stack the two notes above the window as plain
   ruled entries. That band is a tablet held sideways, and it was the one
   width on the page where a note pointed at nothing: the alley ink starts
   at 1280 and the tap ring stopped at 1024, so it got neither. It takes
   the tap treatment now, like everything below it -- see the blocks that
   run to 1279. */

/* THE PLAN BREAKS THE FOLD.

   The hero used to end on a hard edge and the plan band began underneath
   it -- two objects, one after the other, with nothing saying they were
   about the same thing. The window rises into the bottom of the video
   instead, so the artifact interrupts the picture rather than following
   it. The hero says what you leave with; the thing you leave with is
   sitting in the frame while it says it.

   display:flow-root on the section is what makes it work. Without it the
   tour's negative margin collapses through the section's own top edge and
   takes the ground up with it, which would paint over the video rather
   than letting the window rise out of it.

   Only above 1280, because that is where the notes sit beside the plan.
   Below it they stack above the window, so an overlap would lift the
   NOTES onto the video and leave the plan where it was. */
@media(min-width:1280px){
  /* THE HERO TAKES THE PLAN'S OWN TRACK.

     .pl-tour is a 1560 column centred on the viewport with
     clamp(250px,21.5vw,330px) of alley either side, and the window fills
     what is left. Giving the hero the identical width and padding means
     the copy is centred on the window's centre AND can never grow wider
     than the window -- the same box, so the two cannot drift however the
     type reflows.

     Only above 1280, because below it .pl-tour has no alleys and the
     window spans the page wrap, which the hero already matches. */
  .pl-hero-wrap{
    width:min(1560px, calc(100% - 60px));
    margin-inline:auto;
    padding-left:clamp(250px,21.5vw,330px);
    padding-right:clamp(250px,21.5vw,330px);
  }

  .pl-included{display:flow-root;padding-top:0}
  /* The 92px shadow was mixed for a window sitting half against a lit
     sky. On flat ground that reads as a heavy grey halo rather than an
     object in front, so it comes back to the window's own shadow. */
  /* THE PLAN IS THE DIAGRAM.

     The three points are annotations in the margin either side of the plan,
     each one ringed and arrowed to the region it describes, so the section
     is one object rather than a picture and a list of claims about it.

     The block is wider than the page's wrap on purpose. Keeping the notes
     inside it would have taken the plan from 800px to 762; pushing them out
     into the page margin takes it UP to 876, which is the point -- the plan
     is the best thing on the page and it was being shown at two thirds
     size to make room for text that could sit beside it. Centred on the
     viewport, not on the wrap, so it stays symmetrical at every width. */
  .pl-tour{
    /* 336, twenty down from 356: the painted gap between the hand-drawn
       arrow and the top of the plan window goes 55px -> 35px.

       The 356 is the window's top edge in absolute terms, so it is the
       number to move -- the -184 this computes to at 1440 is just 356
       minus the 540px hero, and it changes with the hero's height.

       Measured off INK rather than boxes, because the arrow is an SVG
       stroke and its box carries empty space under the stroke: the box
       gap and the seen gap are not the same number.

       Not pushed further. At 316 and below the window starts to reach
       the arrow itself rather than the air under it, which the
       measurement showed by breaking -- the scan began reading the
       window's own top edge as the arrow's last ink.

       Negative once the hero's height is subtracted, so the window rises
       into the video. This rule is the one
       that has to carry it -- it is the later of the two .pl-tour blocks
       and a plain margin-top:48px here quietly beat the overlap set
       above.

       Expressed against the hero's own height rather than as a clamp of
       its own, which is what finally makes the gap constant. The copy
       ends at about 280px whatever the screen -- it is pinned to the top
       by padding, and only the headline grows -- so the window's top is
       simply 336 minus however tall the hero happens to be, and the air
       between the two stays constant from 1280 to 2560 instead of
       opening from 132 to 202. */
    position:relative;
    /* 308, down from 318. Same expression, same constant-gap behaviour
       across viewports -- the window's top is simply this minus however
       tall the hero happens to be -- just tighter under the arrow. The
       hero's own padding-top is not in this sum, so closing the gap here
       cannot move the headline.

       An older note here says 306 measured 0px to the arrow's last ink.
       That was against a 48px arrow; it is 54 now and the measured gap
       at 318 is 24, so 308 leaves 14 -- closed up, with the arrowhead
       still clear of the window's edge. */
    margin-top:calc(308px - var(--pl-hero-h));
    width:min(1560px,calc(100vw - 60px));
    margin-left:calc(50% - min(1560px,calc(100vw - 60px)) / 2);
    /* The alley is wider than the note by design. The first version made
       them the same width, which left the arrow two pixels of travel and
       turned it into a tick mark -- the note may as well have been a
       caption. Roughly 80px of clear run either side is what it takes for
       a drawn line to read as one. */
    padding:0 clamp(250px,21.5vw,330px);
  }
  /* Static, not relative, so the notes inside it resolve against .pl-tour
     and can be placed against the plan's internals. It keeps no box of its
     own -- every child is absolutely positioned. */
  .pl-tour .pl-plan-outcomes{
    display:block;position:static;margin:0;border:0;
  }
  .pl-tour-stage{position:relative;z-index:1}

  /* THE INK. Drawn at runtime, so it sits over everything and takes no
     pointer events. overflow:visible because a hand-drawn ring overshoots
     its own box by a few pixels, which is the whole trick. */
  .pl-ink{
    display:block;
    position:absolute;inset:0;width:100%;height:100%;
    overflow:visible;pointer-events:none;z-index:2;
  }
  /* NOTHING IS DRAWN UNTIL YOU LOOK AT IT.

     Both rings sitting there permanently was two boxes round a plan that
     already has two boxes in it -- the panels' own grounds do the dividing,
     and the ink on top of them was just more lines. Now the plan is clean
     and the mark is made when a reader touches the part it belongs to,
     from either end: the note or the panel itself.

     The stroke is dashed by its own length and the dash offset is what
     moves, so it genuinely draws rather than fading up. It retracts the
     same way when the cursor leaves. */
  .pl-ink path{
    fill:none;stroke:var(--pl-accent);stroke-width:1.7;
    stroke-linecap:round;stroke-linejoin:round;
    /* The fallback is what stops the flash. The paths are in the DOM for a
       frame or two before script measures them and sets --len, and with no
       fallback the dash length is invalid, so every ring rendered complete
       for an instant on load before snapping away. 3000 is longer than any
       path here, so an unmeasured one is simply not drawn yet. */
    stroke-dasharray:var(--len,3000);stroke-dashoffset:var(--len,3000);
    transition:stroke-dashoffset .5s cubic-bezier(.32,.86,.5,1) var(--delay,0s);
  }
  /* The quarter is drawn in the sage the plan already uses for "on track",
     so the year and the quarter are tellable apart without reading either
     label. Two marker colours, both already on the page. */
  /* Script raises this while it measures the paths and writes --len. A
     dash length is a transitioned property, so without it the browser
     animates from the fallback to the real one and drags a lit segment
     round the ring on the way. */
  .pl-ink.is-setting path{transition:none}
  .pl-ink .pl-ink-alt{stroke:var(--pl-ink-2)}
  .pl-ink path.is-lit{stroke-dashoffset:0}
  /* The arrows draw themselves once, as the section arrives, and then
     stay. They are what says the note on the left belongs to the column on
     the right, and with nothing drawn at rest the two halves of the
     diagram had nothing joining them until you touched one. Only the ring
     waits to be asked for.

     They go after the headings have written, so the section builds in the
     order a person annotating would work: the label, then the line to the
     thing, and the circle only if you ask for it. */
  .rv .pl-tour.is-inked .pl-ink path.pl-ink-arrow{
    stroke-dashoffset:0;
    transition:stroke-dashoffset .75s cubic-bezier(.16,1,.3,1) var(--arrow-delay,.9s);
  }
  /* The head is its own path and does not draw -- it appears once the line
     has arrived. Drawn, it would start from one barb and cross to the
     other, which is not a thing a hand does. */
  .pl-ink path.pl-ink-head{
    stroke-dasharray:none;stroke-dashoffset:0;
    opacity:0;transition:opacity .22s ease var(--head-delay,1.55s);
  }
  .rv .pl-tour.is-inked .pl-ink path.pl-ink-head{opacity:1}

  @media(prefers-reduced-motion:reduce){
    /* No drawing, but the mark still has to appear -- it is the only thing
       connecting a note to its region. */
    .pl-ink path{transition:none}
  }

  /* THE NOTES. Each one is pulled by script to the height of its own ring,
     which is what keeps every arrow short enough to read as a pointer. */
  .pl-tour .pl-plan-outcomes article{
    position:absolute;width:clamp(196px,15.5vw,244px);z-index:3;
    display:block;padding:0;border:0;background:none;cursor:pointer;
  }
  .pl-tour .pl-plan-outcomes article.pl-note-l{left:0;text-align:right}
  .pl-tour .pl-plan-outcomes article.pl-note-r{right:0;text-align:left}
  /* The soft ellipse behind each note went with the picture. It was
     there because the right-hand one landed on a lit sky and measured
     1.07:1; on flat ground both notes sit at the section's own contrast
     and a dark pool in the margin would just be a smudge. */
  /* The plan's own third card is transparent!important in planning.css;
     as a note it needs nothing behind it either way. */
  .pl-tour .pl-plan-outcomes article:first-child,
  .pl-tour .pl-plan-outcomes article:last-child{padding:0}
  .pl-tour .pl-plan-outcomes article:hover{background:none}
  /* Matched to the home page, measured rather than eyeballed: its
     before/after numeral is League Spartan 700 at 19px with letter-spacing
     NORMAL -- not the .17em tracking a small caps label carries, which is
     what the rail had inherited from the four-column grid. Its column
     header is the same clamp as .st-move, 24px at 1440.

     The body goes 14 -> 15 with them. 24 over 14 is the home page's
     pairing missing a step, and the gap shows once the header grows. */
  /* THE LABEL IS PART OF THE DRAWING, THE SENTENCE IS NOT.
     Numeral and heading are set in the same hand as the rings, because
     they are what the arrow is carrying. The description stays in the
     page's own type: it is a sentence to read, not a mark on a diagram,
     and a paragraph of handwriting is a paragraph nobody reads. */
  .pl-tour .pl-plan-outcomes article > span{
    display:block;margin-bottom:2px;
    font-family:'Caveat',cursive;font-weight:600;
    font-size:21px;letter-spacing:.02em;line-height:1;
    color:var(--pl-accent);
  }
  .pl-tour .pl-plan-outcomes h3{
    /* inline-block so the box hugs the words. Left as a block it would be
       the full width of the note, and on the right-hand note -- which is
       set flush right -- the wipe below would spend most of its run over
       empty space before any letters appeared. */
    display:inline-block;
    margin:0 0 11px;
    font-family:'Caveat',cursive;font-weight:700;
    font-size:clamp(24px,1.95vw,31px);line-height:1;letter-spacing:0;
    text-transform:none;color:#E8CDC2;
  }

  /* WRITTEN OUT, NOT FADED IN.
     A left-to-right wipe across the heading, which in a hand this loose
     reads as the words being written. The inset is generous top and bottom
     because Caveat's ascenders and descenders run well past the line box
     and a tight clip shears them. */
  .rv .pl-tour .pl-plan-outcomes h3{
    clip-path:inset(-22% 100% -30% 0);
  }
  .rv .pl-tour.is-inked .pl-plan-outcomes h3{
    clip-path:inset(-22% -8% -30% 0);
    transition:clip-path .8s cubic-bezier(.36,.82,.5,1) var(--write,0s);
  }
  /* The numeral arrives just ahead of the words it labels. */
  .rv .pl-tour .pl-plan-outcomes article > span{
    opacity:0;transform:translateY(4px);
  }
  .rv .pl-tour.is-inked .pl-plan-outcomes article > span{
    opacity:1;transform:none;
    transition:opacity .4s ease var(--write,0s),
               transform .5s cubic-bezier(.16,1,.3,1) var(--write,0s);
  }
  .pl-tour .pl-plan-outcomes article:first-child{--write:.34s}
  .pl-tour .pl-plan-outcomes .pl-note-alt{--write:.62s}

  @media(prefers-reduced-motion:reduce){
    .rv .pl-tour .pl-plan-outcomes h3,
    .rv .pl-tour.is-inked .pl-plan-outcomes h3{clip-path:none;transition:none}
    .rv .pl-tour .pl-plan-outcomes article > span{opacity:1;transform:none}
  }
  /* Same 15/1.6 as everything else. These two are annotations, and a step
   down would have been defensible if the page had a second body size to
   step down to -- it does not, and 14/1.55 made them the only pair on
   the page at their own size. The colour carries the hierarchy instead. */
.pl-tour .pl-plan-outcomes p{font-size:15px;line-height:1.6;color:rgba(246,241,234,.62)}
  /* The second note is written in its own ink: numeral in --pl-ink-2 and
     heading a lighter tint of the same blue, which is the relationship
     #E8CDC2 has to the clay on the first note. The heading was #D3DEC4
     -- a pale GREEN -- so this note's two lines were in two different
     hues and the pair never read as one colour against the other. */
  .pl-tour .pl-plan-outcomes .pl-note-alt > span{color:var(--pl-ink-2)}
  .pl-tour .pl-plan-outcomes .pl-note-alt h3{color:#CFDCE8}
  /* Not sticky any more. The plan no longer has a tall column of rail to
     stay alongside; it is the middle of the diagram. */
  .pl-tour-stage .pl-plan-window{margin-top:0}
}
/* The highlight itself. An outline rather than a dimming overlay, because
   one of the regions (.pl-person) is nested inside another (.pl-quarter-
   panel) -- and a child of a faded parent cannot be made opaque again. */
/* The running border glow used to live here: a conic gradient rotated
   around the selected region and masked down to its border. It is gone.
   Once the regions are permanently ringed in ink, a second travelling
   highlight on the same edges is two indicators arguing about the same
   thing -- and the shiny one wins, which is the wrong way round. Hovering
   a note now simply brings its own ring forward.

   THE PLAN'S OWN BORDERS ARE GONE TOO.

   Every panel and every target tile carried a hairline, so a drawn ring
   around a panel was a wobbly line sitting 9px outside a crisp one. The
   panels keep their backgrounds, which is enough to separate them, and the
   only lines left inside the plan are the ink. */
/* ONE TYPEFACE INSIDE THE MOCK.
   The plan is software, and the software is set in Questrial. League
   Spartan on the labels made the mock read as a piece of this website
   rather than a screenshot of a product. Headings take weight rather than
   a second family.

   Questrial ships one weight, so 700 here is the browser's synthetic bold.
   At label size that is fine and it is what keeps the mock to one family;
   if it ever reads too heavy the fix is letter-spacing, not a second
   face. */
.pl-plan-window,
.pl-plan-window *{font-family:'Questrial',sans-serif}
.pl-plan-figs strong,
.pl-goals-panel li > span,
.pl-person strong,
.pl-avatar{font-weight:700}

/* ONE LABEL STYLE FOR THE WHOLE MOCK.
   The column title, the date beside it, "revenue", "gross profit",
   "metrics" and the two list headings were four different sizes with four
   different trackings, which made a small panel look like it had been
   assembled from bits. Every label in the plan is now the same size, the
   same tracking, the same case and the same colour -- position and the
   things underneath them do the ranking instead. */
.pl-panel-title span,
.pl-panel-title b,
.pl-meas > span,
.pl-plan-figs span{
  font-family:'Questrial',sans-serif;font-weight:700;
  font-size:11px;line-height:1.3;
  letter-spacing:.14em;text-transform:uppercase;
  color:rgba(246,241,234,.44);
}

/* THE PANELS GET THEIR GROUND BACK.
   Without it the year and the quarter ran together into one field of text
   -- the rings said where each one ended but nothing said they were two
   different things. The tiles inside stay flat; it is the two columns that
   need telling apart, not every figure in them. */
.pl-plan-window .pl-goals-panel,
.pl-plan-window .pl-quarter-panel{
  border-color:transparent;
  background:rgba(246,241,234,.028);
  border-radius:3px;
}
/* Equal all round: the same 28px between a panel and the window's edge on
   every side as between the two panels. The gutter was 40 against a 32px
   padding, which left the two columns further from each other than either
   was from the frame. */
/* Equal columns, not the 1.08/.92 the plan was built with. The year fitted
   its three figures on one line and the quarter dropped the deadline to a
   second -- the same block behaving two different ways in one window. */
.pl-plan-columns{grid-template-columns:1fr 1fr;gap:28px}
/* 1fr is minmax(auto,1fr), so each track still has its content's
   min-content width as a floor -- and the quarter panel's is wider than
   the year's, because an avatar and a name cannot break. Between 641 and
   767 that floor bound and the "equal" columns came out 214 and 260.
   Below 640 this was already set for the same reason. */
.pl-plan-columns > *{min-width:0}
.pl-plan-body{padding:28px}

/* A COLUMN EACH, LAID OUT LIKE THE REAL PLAN.
   Each side carries its own date on the same line as its title -- one date
   for the year, one for the quarter, where the priorities used to carry a
   date each. */
/* Stretch, not start. With grounds behind them, two panels of different
   heights read as one that is unfinished; matched, the shorter column's
   spare room is just space inside a panel. */
.pl-plan-columns{align-items:stretch}
.pl-panel-title{align-items:baseline}
.pl-panel-title b{
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:13px;letter-spacing:.04em;white-space:nowrap;
  font-variant-numeric:tabular-nums;color:var(--pl-accent);
}
/* The two figures. Side by side rather than stacked: they are a pair a
   reader takes in at once, and stacking them would push the list that
   matters further down the column.

   Named .pl-plan-figs and not .pl-figs, which the study band already owns
   for its 108px counts -- the first version of this reused that name and
   put a 108px "$12.4M" through the side of the plan window. */
/* Side by side, but sized to the numbers rather than to the column. Two
   equal halves pushed "gross profit" out to the far edge and left a run of
   dead space between the pair; flex with a fixed gap keeps them together
   as one line of figures and gives the column back two lines of height. */
.pl-plan-figs{
  display:flex;flex-wrap:wrap;gap:14px 28px;
  margin:16px 0 4px;
}
/* THE DEADLINE IS IN THE PANEL'S TOP RIGHT CORNER, opposite its name.

   It governs every line underneath it, so it belongs on the header, not
   in the run of figures where it read as a third measure standing beside
   two numbers -- and not on a line of its own under them, which is where
   the last attempt put it and which cost a whole row of panel height for
   one date.

   margin-left:auto against the title's own span, so it is pinned to the
   right wall however long the panel's name happens to be. */
.pl-panel-due{
  margin-left:auto;display:inline-flex;align-items:baseline;gap:8px;
  color:var(--pl-accent);
}
/* Its label keeps the mock's one micro-label style; the date itself is
   the .pl-panel-title b treatment, a step quieter than the figures
   below and in the accent, so the corner reads as a date and not as a
   fourth number. */
.pl-panel-due em{
  font-family:'Questrial',sans-serif;font-style:normal;font-weight:700;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(246,241,234,.44);
}
.pl-plan-figs span{display:block;margin-bottom:6px}
.pl-plan-figs strong{
  font-family:'Questrial',sans-serif;font-weight:700;
  font-size:18px;line-height:1;letter-spacing:-.01em;color:var(--n12-cream);
}

/* Measurables, and the two sub-headings above the lists. Same label as the
   panel titles at a step down, so the column reads as one thing with parts
   rather than three unrelated blocks. */
.pl-meas{margin-top:18px}
.pl-meas > span{display:block}
.pl-meas p{
  margin:7px 0 0;
  font-size:12.5px;line-height:1.35;color:rgba(246,241,234,.66);
}
/* The lists start straight under their own sub-heading, with no rule
   between the heading and the first item -- the rules belong BETWEEN the
   goals, and one directly under "goals for the year" made the heading look
   like a table header it is not. */
.pl-goals-panel ol{margin-top:2px}
.pl-goals-panel li:first-child{border-top:0}
/* Margin, not padding. .pl-person already carries its own vertical
   padding, so padding here only pushed the text down inside a box that
   still started flush against the heading -- the space has to be outside
   the row for the heading to breathe. */
.pl-quarter-panel .pl-meas + .pl-person{border-top:0;padding-top:0;margin-top:14px}

/* Built on the home page's "what it takes to start" columns, rather than
   near them: same 12px/.17em clay label, same clamp(20px,1.65vw,24px)
   heading, same 15px/1.55 body at .68, same hairline between columns and
   the same faint hover.

   The one structural difference is the outer edge. The home page's grid
   runs full-bleed and pads its first and last columns by the section inset
   so the dividers reach the screen edges. This grid lives inside .pl-wrap,
   which already carries the inset -- so the outer columns drop their
   outside padding instead, which lands the text on the same left edge as
   the heading above it and keeps the dividers between the columns where
   they belong. */
.pl-plan-outcomes{
  margin-top:52px;
  border:0;
}
/* planning.css draws a 1px gradient hairline across the top and bottom of
   this grid with ::before and ::after -- absolutely positioned, so zeroing
   the borders does nothing to them. They are what kept the four columns
   reading as a boxed table after the borders were gone. The start section
   has no such rules, so neither does this. */
.pl-plan-outcomes::before,
.pl-plan-outcomes::after{content:none}
.pl-plan-outcomes article{
  display:flex;flex-direction:column;
  padding:36px 34px;
  border:0;
  transition:background .2s ease;
}
.pl-plan-outcomes article + article{border-left:1px solid var(--n12-line)}
.pl-plan-outcomes article:first-child{padding-left:0}
.pl-plan-outcomes article:last-child{padding-right:0}
.pl-plan-outcomes article:hover{background:rgba(246,241,234,.028)}

/* The numeral reads as the column's label here, so it takes the label's
   treatment and its 14px drop to the heading. */
.pl-plan-outcomes article > span{
  display:block;margin-bottom:14px;
  font-family:'League Spartan',sans-serif;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:var(--pl-accent);
}
.pl-plan-outcomes h3{
  margin:0 0 14px;
  font-size:clamp(20px,1.65vw,24px);
  line-height:1.06;letter-spacing:-.03em;
}
.pl-plan-outcomes p{
  margin:0;font-size:15px;line-height:1.6;color:rgba(246,241,234,.68);
}

/* The mock. Its own chrome stays -- it is a picture of software and should
   look like one -- but the frame comes onto the page's palette and the
   radius matches the home page's screenshots. */
.pl-plan-window{
  margin-top:54px;
  border:1px solid rgba(246,241,234,.14);
  border-radius:12px;
  /* Opaque again. The .88 background and the 18px backdrop blur existed
     so the ridge line would carry faintly through the window and it
     would sit IN the photograph rather than on top of it. With a flat
     ground behind it there is nothing to see through to: all the
     transparency does is shift the colour slightly, and the blur is a
     real compositing cost for no visible effect.

     And it takes the LIGHTER ground now that the band under it has gone
     dark. The pair used to be a #0F0D0C window on a #171413 band; both
     on #0F0D0C would have left the window as a border and a shadow with
     nothing inside them. Swapped, it reads as a lit screen on a dark
     ground, which is what it is a picture of. */
  background:var(--pl-ground);
  /* NOT THE OLD 0 28px 70px rgba(0,0,0,.45). A black shadow over a
     near-black ground has very little contrast to spend, so a long blur
     does not read as depth -- it reads as a dark halo sitting off the
     window's bottom edge, which is the ring she kept seeing.

     Removing it entirely went flat, though. Depth here comes from light
     instead: a cream hairline along the top edge, as if the screen
     catches the room, plus a short tight shadow that seats it on the
     page. 12px of blur reaches nowhere, so there is nothing to ring.
     Same pair on .swa-app. */
  box-shadow:
    inset 0 1px 0 rgba(246,241,234,.10),
    0 1px 2px rgba(0,0,0,.55),
    0 4px 12px rgba(0,0,0,.35);
}
.pl-window-top{background:#1B1716;color:rgba(246,241,234,.6)}
.pl-window-top > b{color:var(--pl-accent)}

/* The status pills inside the mock were 10px. Small type is realistic for
   a picture of a dashboard, but 10px is below what anyone should be asked
   to read, and unlike the home page's proof shots this mock is live text
   rather than an image. 11 is as small as it goes. */
.pl-person em,
.pl-capacity{font-size:11px}

/* ============================= the beats ===============================
   What actually happens in the room -- the thing the page was missing
   entirely. Five sequential steps, so they run down rather than across,
   with the numeral and heading holding the left column and the detail on
   the right. That keeps the prose at a readable measure AND fills the
   band, which the old single-column timeline did not.

   Hairline between rows rather than around them: this is a sequence, not a
   set of cards, and a box around each would say otherwise. */
/* Four across, on one track.

   The rows-down version put four short paragraphs in a vertical queue in a
   band that had no other rhythm. Across, they read as a sequence you move
   through -- which is what they are -- and the track makes the movement
   literal. */
/* Two sentences now that who-is-in-the-room and where-it-happens live here,
   one per line via a <br>. No cap: each sentence has to fit its own line,
   and a measure narrow enough to be comfortable would wrap them both. */
.pl-sessions .pl-sub{max-width:none}

/* Steps alternate above and below the track.

   Two equal rows, the track sitting exactly on the boundary between them.
   Odd steps take row 1 and hang from its bottom edge, even steps take row
   2 and sit on its top edge -- so every node lands on the line whatever
   height its step happens to be. The 62px of padding on the inside edge is
   the room the tick needs. */
.pl-beats{
  list-style:none;margin:44px 0 0;padding:0;
  position:relative;
  display:grid;
  /* SEVEN COLUMNS FOR SIX STEPS.
     Six equal columns would give each step about 180px, or twenty-four
     characters a line. Instead the grid is one column finer than the step
     count and every step spans two of them: the nodes keep a tight rhythm
     along the track while the copy gets roughly twice the width it would
     otherwise have. Nothing collides, because a step's neighbour is always
     on the other side of the line.

     The seventh is 40px, not a seventh of the width. Equal sevenths put
     the six nodes across only six sevenths of the track, so the last step
     sat 330px short of the end of its own line while the first started
     hard against the left edge -- which is the lopsidedness. A narrow
     seventh still gives the last step somewhere to spill into while
     pushing every node along. */
  grid-template-columns:repeat(6,1fr) 40px;
  grid-template-rows:1fr 1fr;
  gap:0 30px;
}
/* The last node sits five sevenths of the way along, so both strokes fade
   out over the run past it rather than stopping on a hard edge in empty
   space. */
.pl-beats::before{
  content:"";position:absolute;left:0;right:0;top:50%;height:1px;
  background:var(--n12-line);
  -webkit-mask-image:linear-gradient(90deg,#000 84%,transparent 100%);
  mask-image:linear-gradient(90deg,#000 84%,transparent 100%);
}
.pl-beat-line{
  position:absolute;left:0;right:0;top:50%;height:1px;
  background:var(--pl-accent);
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.5s cubic-bezier(.16,1,.3,1) .1s;
  -webkit-mask-image:linear-gradient(90deg,#000 84%,transparent 100%);
  mask-image:linear-gradient(90deg,#000 84%,transparent 100%);
}
.pl-beats.is-drawn .pl-beat-line{transform:scaleX(1)}

/* The span gives each step two columns of room; the max-width stops it
   using all of it. Two full columns ran the copy 328px wide at 1440, which
   made each block reach well past its neighbour's node and the row read as
   six paragraphs rather than six stops on a line. */
.pl-beats li{
  display:block;padding:0;border:0;position:relative;
  max-width:clamp(226px,19.5vw,296px);
  /* A grid item's default min-width is its min-content, and a spanning
     item pushes that floor into the columns it covers. With six spanning
     items overlapping every column, the fr ratios never got a say and the
     tracks came out narrower than asked for. */
  min-width:0;
}

/* Six positions, alternating. Placed by index rather than :nth-of-type
   parity because the decorative <i> is the ol's first child and shifts
   every count by one. */
.pl-beats li:nth-of-type(1){grid-column:1 / span 2}
.pl-beats li:nth-of-type(2){grid-column:2 / span 2}
.pl-beats li:nth-of-type(3){grid-column:3 / span 2}
.pl-beats li:nth-of-type(4){grid-column:4 / span 2}
.pl-beats li:nth-of-type(5){grid-column:5 / span 2}
.pl-beats li:nth-of-type(6){grid-column:6 / span 2}
.pl-beats li:nth-of-type(odd){grid-row:1;align-self:end;padding-bottom:62px}
.pl-beats li:nth-of-type(even){grid-row:2;align-self:start;padding-top:62px}

/* THE BOOKENDS.
   Same shape as a step, told apart by a grey BEFORE / AFTER where the four
   hours carry a clay numeral. The numbers still only run to four, because
   the heading promises four hours and these two sit outside them. */
.pl-cap-when{
  display:block;margin-bottom:10px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:13px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(246,241,234,.49);
}
.pl-beat-cap h3{color:rgba(246,241,234,.88)}
.pl-beat-cap p{color:rgba(246,241,234,.52)}
/* A hollow ring rather than a filled clay one, so the track reads as
   running through the session and past it at either end. */
.pl-beat-cap .pl-beat-node{border-color:rgba(246,241,234,.3)}
.pl-beat-cap .pl-beat-node::after{
  background:linear-gradient(0deg,rgba(246,241,234,.3),rgba(246,241,234,0));
}
.pl-beats li:nth-of-type(even).pl-beat-cap .pl-beat-node::after{
  background:linear-gradient(180deg,rgba(246,241,234,.3),rgba(246,241,234,0));
}

/* THE NODE, lifted from the home page's proof tree and turned sideways.

   Same numbers as .tr-node there: an 11px circle, the section's own ground
   as the fill, a 2px clay ring, and a 6px halo of ground around it -- the
   halo is what punches the hole in the track, so the line reads as passing
   behind the node rather than stopping at it.

   The tick runs DOWN toward the step it belongs to, where the tree's runs
   sideways, and fades out the same way rather than ending on a hard edge. */
.pl-beat-node{
  position:absolute;left:0;
  width:11px;height:11px;border-radius:50%;
  background:var(--pl-ground-dark);
  border:2px solid var(--pl-accent);
  box-shadow:0 0 0 6px var(--pl-ground-dark);
}
/* FILLED, like the home page's tree nodes -- clay through rather than a
   clay ring on the ground colour. The numbered steps only: .pl-beat-cap
   is BEFORE and AFTER, which are not steps, and its hollow grey ring is
   what says so. Filling those too would make the track read as eight
   equal beats. The halo stays ground either way, because that is what
   punches the node out of the track behind it. */
.pl-beat .pl-beat-node{background:var(--pl-accent)}
/* Each node sits on the edge of its row that the track runs along. */
.pl-beats li:nth-of-type(odd) .pl-beat-node{top:auto;bottom:-5.5px}
.pl-beats li:nth-of-type(even) .pl-beat-node{top:-5.5px;bottom:auto}
.pl-beat-node::after{
  content:"";position:absolute;left:50%;
  width:1px;height:22px;
  transform:translateX(-.5px);
}
/* The tick always points back at the step it belongs to, so it runs UP out
   of the node for a step above the line and DOWN for one below it -- and
   fades away from the node either way. */
.pl-beats li:nth-of-type(odd) .pl-beat-node::after{
  bottom:100%;margin-bottom:5px;
  background:linear-gradient(0deg,var(--pl-accent),rgba(178,132,121,0));
}
.pl-beats li:nth-of-type(even) .pl-beat-node::after{
  top:100%;margin-top:5px;
  background:linear-gradient(180deg,var(--pl-accent),rgba(178,132,121,0));
}
/* Dimmed only when there is a script to undim it -- the same guard the
   tree uses, so the nodes are never stuck faint with JS off. */
.rv .pl-beat-node{
  opacity:.35;transform:scale(.7);
  transition:opacity .45s ease,transform .45s cubic-bezier(.16,1,.3,1);
}
.rv .pl-beats.is-drawn .pl-beat-node{opacity:1;transform:scale(1)}
/* Staggered to land behind the stroke as it passes each one. */
.rv .pl-beats.is-drawn li:nth-of-type(1) .pl-beat-node{transition-delay:.12s}
.rv .pl-beats.is-drawn li:nth-of-type(2) .pl-beat-node{transition-delay:.32s}
.rv .pl-beats.is-drawn li:nth-of-type(3) .pl-beat-node{transition-delay:.52s}
.rv .pl-beats.is-drawn li:nth-of-type(4) .pl-beat-node{transition-delay:.72s}
.rv .pl-beats.is-drawn li:nth-of-type(5) .pl-beat-node{transition-delay:.92s}
.rv .pl-beats.is-drawn li:nth-of-type(6) .pl-beat-node{transition-delay:1.12s}

.pl-beat-n{
  display:block;margin-bottom:10px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:13px;letter-spacing:.14em;color:var(--pl-accent);
}
/* The home page's .st-move, exactly: same clamp, same line-height, same
   tracking, lowercase, full cream. These six steps and the home page's
   three columns are the same thing -- a heading on a repeated card inside
   a band -- and they were running 21/1.12 at 88% against 24/1.06 at full
   cream, which is three separate differences doing no work. */
.pl-beats h3{
  margin:0 0 10px;
  font-size:clamp(20px,1.65vw,24px);line-height:1.06;letter-spacing:-.03em;
  text-transform:lowercase;color:var(--n12-cream);
}
/* 15/1.6, the page's one body size. It ran at 14.5 and was the only
   thing on the page at that size -- a half-pixel difference nobody can
   name and everybody can feel when two bands sit next to each other. */
.pl-beats p{
  margin:0;max-width:none;
  font-size:15px;line-height:1.6;color:rgba(246,241,234,.66);
}

@media(prefers-reduced-motion:reduce){
  .pl-beat-line{transition:none;transform:scaleX(1)}
}

/* The .pl-room and .pl-facts blocks used to bracket the track with who is
   in the room and where it happens. Both facts are one clause long, so they
   are in the section's lede now and the band is a heading and a track. */

/* ===================== why four hours, as a strip =======================
   It used to be a band of its own on a lighter ground with a bar chart of
   sixteen hours against four. Two problems with that: it answers a
   question the TIMELINE raises, so putting a whole section between the
   timeline and the price meant the reader carried the question past it;
   and an argument given its own band, its own texture and its own chart
   reads as the page defending itself rather than answering a fair point.

   As a strip under the track it is a footnote, which is what it is. Label
   left, argument right -- the same shape who-is-in-the-room used before
   that moved into the lede. */
/* A divider, not a chapter: half the depth of the bands either side and
   none of their apparatus -- no eyebrow, no h2, no illustration.

   The dust plume, which is already a 2160x728 panorama and so needs almost
   no cropping at band proportions. It is the only image between the hero
   and the close, which is most of why this reads as a break in the page
   rather than another section of it.

   The scrim is heavier at the top and bottom than through the middle, so
   the band meets the flat grounds above and below it without a seam. */
/* PROMOTED FROM A DIVIDER TO A SECTION.

   It was built as an aside -- centred, no eyebrow-and-heading structure,
   the smallest type on the page, half the depth of the bands either
   side. Every one of those signals says "skip me", and the copy inside
   is the only sentence on the page a competitor could not write: ten
   years on the client side of EOS, and why the two-day version fails.

   So it takes the page's own section shape. Left-aligned on the same
   inset, eyebrow into heading at 0 like how-it-works and pricing and
   the close, body at the shared .pl-sub size. It is still the shortest
   band on the page, so the rhythm of long-flat, short-picture holds. */
/* #0F0D0C, the darker of the site's two grounds. The band sits between
   two sections on #171413, so the step down is what separates it -- and
   the picture is coming back in opacity, which means the ground under it
   is doing more of the work than it used to. */
.pl-why{position:relative;padding:118px 0;background:#0F0D0C;overflow:hidden}
/* THE HOME PAGE'S TREATMENT, NOT A SCRIM OF ITS OWN.
   Its close section desaturates and dims the photograph itself and then
   lays a flat 70% of the page's own ink over it, which is why an image
   there reads as a texture under the type rather than a picture the type
   is sitting on. Same two numbers here. */
.pl-why::before,
.pl-why::after{content:"";position:absolute;inset:0;pointer-events:none}
.pl-why::before{
  /* A 3.00:1 panorama against a band that runs 2.86:1 at 1440, so cover
     keeps the whole height and trims a sliver of width -- the horizon
     line stays where it was composed and the cacti stay on the right,
     which is the half the copy does not use. 57 KB. */
  background:url('/assets/images/planning-desert-dusk.jpg') center 50%/cover no-repeat;
  /* Knocked back further than the home page's own numbers. Its close
     section is a full-height band where the picture is half the point;
     this is a 240px divider between two dense sections, and at the same
     strength the dust was competing with the sentence on top of it. */
  /* Barely touched. The dust photograph this replaced was bright and
     mid-toned and needed .52 saturation at .62 brightness to sit down;
     this one is already a dusk panorama that is mostly silhouette, and
     the same numbers crushed the last of the glow out of the horizon.
     The picture arrives dark, so the treatment can be light. */
  filter:saturate(.86) brightness(.94);
  /* .35, her pick off a rendered ladder at 1, .70, .50 and .35 on the
     darker ground this band moved to. The ground is #0F0D0C, so this
     composites the picture toward near-black rather than making it
     quieter against a neutral -- the frame is still graded at full
     strength, there is just 65% less of it reaching the eye.

     It is declared HERE and not beside the background above, because
     this rule already carried an `opacity:1` twenty lines further down
     the same block -- so the first version of this change sat above it
     and lost to it, and the band measured unchanged while the file read
     as though it had been set. Two declarations of one property in one
     block is the quietest way to make a value look applied when it is
     not. */
  opacity:.35;
}
/* And the wash comes down with it. At .46 over a picture that is now
   at .35 the band was being darkened twice for one job. */
.pl-why::after{background:rgba(23,20,19,.30)}
.pl-why .pl-wrap{position:relative;z-index:1}
/* Left on the page's own inset, like every band under it. */
.pl-why-bar{max-width:none;margin:0;text-align:left}
/* The home page's own eyebrow and body sizes for a band like this: 12px
   at .17em for the label, 15px/1.6 at 68% for the copy. It used to run
   bigger and brighter than anything equivalent on the site. */
.pl-why-bar > span{
  /* 0, like every other section head on the page: the heading's own line
     box does the spacing. It carried 16px while it was a centred
     divider. */
  display:block;margin-bottom:0;
  font-family:'Questrial',sans-serif;font-weight:700;
  font-size:12px;letter-spacing:.17em;text-transform:uppercase;
  color:rgba(246,241,234,.7);
}
/* The page's own section heading size, not a smaller one of its own.
   It ran at clamp(21px,1.9vw,25px) to keep the band an aside; it is not
   an aside any more. */
.pl-why-bar 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;
  /* 42ch, not 24. The sentence is 39 characters and it is one claim --
     "we have sat through the two-day version" broken after "through"
     reads as two half-thoughts, and the band has the width to spare
     either way. The cap stays rather than going to none so the heading
     still has a measure if the copy ever grows. It wraps below 900
     regardless, where 39 characters do not fit a phone. */
  text-transform:lowercase;color:var(--n12-cream);max-width:42ch;
}
/* And the shared body treatment, capped like the why-plans-fail band's
   so three sentences do not run 180 characters wide at 1920. */
.pl-why-bar p{
  /* min(86ch,72%), the same measure why-plans-fail uses. The two bands
     are the same shape -- a label, a claim and two paragraphs over a
     picture -- and they were running 944 and 710 at 1440. */
  margin:18px 0 0;max-width:min(86ch,72%);
  font-size:15px;line-height:1.6;color:rgba(246,241,234,.72);
}
/* A sentence a line was right when they were centred and short. Set
   left at this measure they are paragraphs, and want a paragraph's
   space between them. */
.pl-why-bar p + p{margin-top:14px}
.pl-why-link{margin-top:26px}
/* This link and why-plans-fail's are the same thing in the same place --
   a prose link closing a band over a picture -- and both are tertiary:
   this one goes to /about, that one to /software.

   THE COMMENT THAT USED TO SIT HERE SAID "both are clay" AND THEY WERE
   PEACH. #E4BCAC is peach; clay is #B28479. The note was written when
   the two were being brought into line with each other and it described
   the intention rather than the value, and it has been wrong ever since
   -- which is how "are they peach or clay?" became a question with two
   defensible answers. They are clay now, and the colour lives in
   cta-n12.css where the other two tiers are. */
.pl-why-bar a{white-space:nowrap}

/* ========================== the two kinds ==============================
   Two columns on the same treatment as the practical band below: hairline
   between, no box, label / heading / body. It replaced a pair of nine-row
   agendas, which were contradicting the promise that the agenda gets built
   per client -- and were ~1400px of page doing work one sentence does. */
.pl-choose{
  padding:118px 0;
  /* #171413, measured off the home page's before/after band rather than
     guessed: that section computes to rgb(23,20,19). It is a step up
     from the --pl-ground-dark the bands either side use, which suits the
     one section a reader scrolls looking for. (#2C2523, the stats bar,
     was the wrong grey -- lighter and warmer than anything the home
     page uses for a full band.) */
  background:var(--pl-ground);
}
/* Each of these is two paragraphs now -- what the session is, then what it
   leaves behind. A paragraph break rather than a longer one, so the pair
   still reads as one column of prose. */

/* The "before you book" band's styles used to live here. The band is gone:
   its four blocks were the before and the after of the session plus two
   pieces of logistics, and they now sit on the how-it-works timeline as
   .pl-beat-cap and .pl-facts. */

/* ============================== the price ==============================
   On the card, not in a band of its own.

   It was a separate pricing section, and that section had to re-describe
   both session types to make sense on its own -- the quarterly line was
   nearly word for word the quarterly card above it. Attaching the number
   to the thing it buys says each session once.

   A fixed offset and a rule, not margin-top:auto. Auto pins the block's
   BOTTOM to the column foot, and the annual block is three lines deeper
   than the quarterly one, so the two figures came out 87px apart. Following
   the text means they land within a line of each other and the offset
   reads as flow rather than as a broken grid. */
/* THE PRICING PAGE'S CARD, brought over rather than approximated.

   Its anatomy exactly: a bordered card, a top section holding the name and
   the price pair, a rule, then the features panel. grid-template-rows:
   auto 1fr is the part that matters -- it makes both cards' feature panels
   start on the same line however long the tops run.

   The palette does not come with it. That page is still on the old wheat
   and brown; this one is clay on the home page's grounds. */
/* THE SAME SPLIT THE PLAN USES.

   This was a bordered two-card table, which is the only boxed table on a
   page made otherwise of line, type and left-aligned structure -- which is
   why it read as imported from somewhere else. It is now two columns
   divided by a rule: annual left, quarterly right, exactly the shape the
   finished plan has at the top of the page. The page rhymes with itself
   and the price stops looking like a widget. */
/* ============================ the ledger ==============================

   Two rows on hairlines, the figure hard right. The same shape the plan
   window uses for REVENUE / $12.4M and for the deadline in its corner,
   which is the point: the price speaks the page's language instead of a
   pricing widget's.

   The figure is in --pl-ink-2, the pale blue the quarterly annotation is
   written in. Clay is this page's ANNOTATION colour -- the arrows, the
   rings, the handwritten line in the hero -- and spending it on the
   loudest number in the section would have put marginalia and money in
   the same voice. */
/* THE ROW FILLS THE RULE.

   The band was stuck between two bad choices. Packed left, the entries
   used about half the hairline and the rest of it ran on into nothing.
   Given the whole hairline, the description hit its 56ch cap and left a
   400px hole in the middle of every row. Centring only moved the
   emptiness to both ends at once.

   None of it was a margin problem: it was the hairline advertising a
   width the content had no use for. The answer taken here is to make the
   content use it -- the description runs the full track and the figure
   sits hard against the rule's right end, so the row has no middle to
   leave empty. It costs a long line, 124 characters at 1440, which is
   past a comfortable measure for a paragraph; these are two-clause
   descriptions rather than prose, and the alternative was a hole. */
.pl-ledger{
  display:block;
  border-top:1px solid var(--n12-line);
  margin-top:34px;
}
/* THE FIGURE SITS NEXT TO THE TEXT, not at the far wall.

   With 1fr auto the description column ate every spare pixel and pushed
   the figure to the right edge, so the gap between the two grew with the
   window: 305px at 1280, 439 at 1440, 909 at 1920. They stopped reading
   as one row.

   A fixed 60ch column and justify-content:start packs them together
   instead, so the figure lands at the same place at every width and the
   gap is 72px flat. The row itself is still full width, so the hairlines
   still run the whole band -- it is the content that is packed, not the
   rule. */
.pl-ledger-row{
  /* A FIXED figure column, not auto. On auto each row sized its own,
     and the two rows do not have the same widest child -- the annual
     one carries "or $336 a month for 12 months" at about 200px, the
     quarterly one only "$2,500" at 145. So the columns came out
     different widths and the two prices right-aligned to two different
     edges, one under the other but not with it. 230px is shared, so
     both land on the same right rule.

     And 150px of alley rather than 72: the figure needs to read as the
     other side of the row, not as the end of the sentence.

     CENTRED ON BOTH AXES.

     Vertically, because baseline pinned the "$3,360" to the first line
     of the description, which is right when the two sides are the same
     height and wrong here: the annual row's figure carries four lines to
     the body's three, the quarterly row's two to the body's four, so
     each side hung off a shared top edge with all its slack at the
     bottom. Centring gives each block the same middle.

     Horizontally, because the pair is narrower than the band and packing
     it left left the slack in one lump on the right -- 400px of it at
     1440, 900 at 2560, growing with every inch of screen while the
     entries stayed pinned to the far edge. Centred, the row widens
     symmetrically and the two sides sit either side of the band's own
     axis, which is the axis the heading above them already uses. The
     hairlines still run the full width: it is the content that is
     centred, not the rule. */
  display:grid;grid-template-columns:minmax(0,1fr) 230px;
  justify-content:stretch;align-items:center;gap:0 80px;
  /* No side padding and no negative margin: the row's edges ARE the
     rule's edges, and the rule's left edge is the heading's. */
  padding:30px 0;margin:0;
  border-bottom:1px solid var(--n12-line);
  transition:background-color .2s ease;
}
/* The rows light the way the plan's annotations do. */
.pl-ledger-row:hover{background:rgba(246,241,234,.028)}
/* The page's sub-heading, now on the home page's .st-move: same clamp,
   line-height, tracking and case as the session beats above and the
   home page's three columns. It was 21/1.12 with its own tracking -- a
   third size for the same job. */
.pl-ledger-body h3{
  margin:0 0 9px;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(20px,1.65vw,24px);line-height:1.06;letter-spacing:-.03em;
  text-transform:lowercase;color:var(--n12-cream);
}
/* No measure of its own -- the row's 60ch column is the measure now, and
   two caps fighting each other is how the description ended up stopping
   400px short of the figure. */
.pl-ledger-body p{
  /* The track is the measure, up to a point. Uncapped it ran 147
     characters at 1920 and kept going; 118ch is the same ceiling the
     why-so-short band already uses, so the page has one widest measure
     rather than two. It does not bind at 1440, where the track is
     narrower than the cap. */
  margin:0;max-width:118ch;
  font-size:15px;line-height:1.6;color:rgba(246,241,234,.68);
}
/* the currency line, under the ledger's last rule */
.pl-ledger-note{
  margin:18px 0 0;
  font-family:'Questrial',sans-serif;
  font-size:13.5px;line-height:1.6;color:rgba(246,241,234,.52);
}
.pl-ledger-fig{text-align:right;white-space:nowrap}
.pl-ledger-fig strong{
  display:block;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:50px;line-height:1;letter-spacing:-.035em;
  color:var(--pl-ink-2);
}
.pl-ledger-fig > span{
  display:block;margin-top:8px;
  font-family:'Questrial',sans-serif;font-weight:700;
  /* 12/.17em, the page's label size -- the same as every eyebrow and the
     same as the home page's. At 11/.14 these two were the smallest type
     on the page outside the footer, and they are not a footnote: they
     are what the number means. */
  font-size:12px;letter-spacing:.17em;text-transform:uppercase;
  /* .56, not the mock's .44. That is the plan window's micro-label
     value and it works there because those labels sit on a panel a
     shade lighter than the section; out here on --pl-ground-dark the
     same colour measures 4.02:1, under the floor for 11px text. */
  color:rgba(246,241,234,.56);
}
/* The tag sits ON the one-time figure, because that is whose saving it
   is: twelve months at $336 is $4,032, and $3,360 paid once is two of
   them back. */
.pl-ledger-tag{
  display:inline-block;margin-top:11px;padding:4px 11px;
  border:1px solid rgba(169,184,198,.46);border-radius:999px;
  font-style:normal;font-size:11.5px;letter-spacing:.04em;
  color:var(--pl-ink-2);
}
/* And the monthly alternative is the quiet line under it, not a second
   figure competing with the first. */
.pl-ledger-fig .pl-ledger-alt{
  margin-top:10px;
  font-family:'Questrial',sans-serif;font-weight:400;
  font-size:13px;letter-spacing:0;text-transform:none;
  color:rgba(246,241,234,.56);
}

/* ============================== the proof ==============================
   The two figures get the clay accent and the section's own rule, rather
/* The evidence band's styles used to fill the next eighty lines: a
   two-column lede, the 138 and 19,951 counts at 108px, a conclusion and a
   citation. The band is gone -- its one useful sentence is now the first
   line of the note under the plan, where the reader is looking at the plan
   while reading why it has to be looked at. */

/* ============================== the close ==============================
   The same shape as the home page's: one ask, deeper than the bands above
   it, its photograph pushed well back so the cream button stays the
   brightest thing on the screen. */
.pl-final{
  /* 118 like the rest. It ran 132 to read "deeper than the bands above";
     with every other band now measurably on one rhythm, 14px of extra
     depth is not a signal, it is a band that failed to line up. */
  padding:118px 0;
  position:relative;isolation:isolate;
  background:var(--pl-ground);
}
/* THE MIRROR OF THE WHY-PLANS-FAIL BAND. Picture on the left, dissolving
   to the right; there, picture on the right dissolving to the left.

   Full bleed, this frame was being cropped hard: the band is 514 tall
   against 1440 wide, a ratio of 2.80 against the frame's 1.78, so cover
   kept only 63% of the height and placed the window 19% down -- past the
   top of her head at 14.2%, which is why it was cut. Every crop position
   that cleared her head at 1440 failed at 1920 or 2560.

   In a box 64% of the band it stops being a crop at all. 922 wide by 514
   is a ratio of 1.79 against the frame's 1.78, so cover keeps 99% of the
   height and she is whole, head to boots, at every width. That is the
   zoom-out: a narrower box, not a smaller picture. */
.pl-final::before{
  content:"";position:absolute;top:0;bottom:0;left:0;right:auto;
  /* FULL WIDTH, AND NO MASK. See the long note on the mask below.
     The picture now runs the whole band and the overlay above it does
     all of the fading, which is how the video in why-plans-fail has
     always worked. */
  width:100%;z-index:0;
  /* HER HEAD NEEDS ROOM ABOVE IT, AND cover COULD NOT GIVE IT.

     At cover this 1672x941 frame draws 922x519 in a 922x486 panel --
     33px of vertical play in total, so background-position could move
     her by at most 16px and looked like it was doing nothing.

     auto 125% draws it 608 tall, which is 122px of play, and that is
     still a downscale from 941 so nothing softens. At 12% she sits with
     sky above her instead of against the top edge. */
  /* SIZED BY WIDTH, NOT BY HEIGHT. This is the cut-off edge and the left
     margin, and both were one fault.

     `auto 125%` sets the height from the BOX and lets the width fall out
     of the aspect ratio, so the picture was drawn 1080px wide at every
     viewport. The box is 64% of the band, so it passes 1080 at about
     1688px wide -- and past that the box keeps growing while the picture
     does not. At 1728 the box is 1106 and at 1920 it is 1229, which
     leaves 13px and then 74px of bare ground down BOTH sides, plus a hard
     vertical edge where the picture stops halfway through the mask's
     fade. That is exactly what her screenshot shows.

     It never appeared in testing because every check ran at 1440, where
     the box is 922 and the picture still covers it.

     `125% auto` sets the width from the box instead, so the picture is
     always 25% wider than the box it sits in and can never leave a gap at
     any viewport. The height then falls out at 1.777x that, which is what
     buys the vertical play her head needs -- 162px at 1440 against the
     32px plain cover would give. */
  /* THE SAME DRAWN SIZE AND THE SAME PLACE, on a box that is now the
     whole band instead of 78% of it.

     Scale: the picture has been 80% of the band's width throughout
     (0.64 x 1.25, then 0.78 x 1.03). On a full-width box that is simply
     80%.

     Position: at 78% wide, `center` put the image's left edge 1% of the
     band left of the band's own edge. background-position resolves as
     (container - image) x percentage, so on a full-width box the same
     offset is (100% - 80%) x -5% = -1%. Hence -5%. */
  background:url('/assets/images/planning-close-road.jpg') -5% 12%/80% auto no-repeat;
  background-image:image-set(url("/assets/images/planning-close-road.avif") type("image/avif"),url("/assets/images/planning-close-road.jpg") type("image/jpeg"));
  /* The home close band's treatment, same as why-plans-fail's -- except
     for the brightness, which this band cannot afford.

     THE "LEFT MARGIN" WAS THIS VALUE, NOT A LAYOUT BUG. ::before is at
     left:0 and the first painted column measured 0px of 1440, so nothing
     was ever inset. What was wrong is that at .74, under this band's wash,
     the picture's own half averaged 25.8 against a bare ground of 20.6 --
     five luminance points out of 255. The frame was very nearly invisible,
     so the eye read the empty left as a gap.

     Same answer for "it should fade smoothly into the right": with the copy
     hidden the profile was already monotonic from 25% out to the ground and
     the largest step across the fade was 2.1. It was smooth. It was fading
     from almost nothing into nothing, which does not read as a fade.

     .92 with the wash below puts the picture 13.2 points over ground
     instead of 5.2. The heading costs 14.82 -> 13.55, which it has. */
  /* .80, down from .92. The lift to .92 was to stop the frame reading as
     a gap, and it did -- but it also made this the brightest picture on
     the page, against a closing band that should settle rather than
     announce. .80 keeps it clearly a photograph (about 9 luminance
     points over the bare ground rather than the 13 .92 gave, still well
     above the 5 that was invisible) without leading the band. */
  filter:saturate(.6) brightness(.80) hue-rotate(-18deg);
  /* SIX STOPS, NOT FOUR. Measured across the frame the old ramp fell
     .72 -> .22 between 44% and 72% -- half the mask's weight disposed of
     in a quarter of its width, which is the drop that reads as sudden.
     The same total falloff spread over stops that never lose more than
     about .2 at a time, and pushed further right so the fade starts
     later and has more room to finish in. */
  /* NO MASK. THIS IS WHY FOUR ATTEMPTS AT THE RAMP NEVER LANDED.

     She asked whether this was built the same way as the fade on the
     video further up the page, "just reversed sides". It was not, and
     that is the whole answer.

     The video fades with .pl-fail-shade: a gradient overlay painting the
     band's own colour ON TOP of the footage. One picture blending toward
     one flat colour, so the curve you write is the curve you get.

     This band faded with mask-image, which does something else entirely:
     it makes the picture TRANSPARENT and reveals whatever is behind it.
     And there was already a second gradient -- ::after -- washing the
     same area. So the visible result was two ramps compounding, and no
     arrangement of stops in the mask could produce the curve I was
     aiming at, because the mask was never the only thing acting.

     Rebuilt the video's way: the picture runs full width and untouched,
     and ::after does all the fading. Mirrored, because the picture is on
     the left here and on the right there. */
  /* ONE RAMP, AND IT IS THE MASK.

     The previous pass removed the mask and gave the job to the ::after
     overlay, reasoning that the video's shade works that way. That broke
     it: the picture is drawn 80% of the band wide, so with nothing
     fading it there is a hard vertical edge where the image simply
     stops, and the overlay was still climbing at that point. That edge
     is what she photographed.

     The lesson from the video still holds -- ONE ramp, not two -- but
     the right single ramp here is the mask, because the mask is what
     controls the picture's own edge. So: mask fades the picture to
     nothing by 72%, comfortably before it ends at 79%, and ::after is
     reduced to a light wash that no longer competes. */
  -webkit-mask-image:linear-gradient(90deg,
    #000 0%, rgba(0,0,0,.97) 8%, rgba(0,0,0,.92) 17%,
    rgba(0,0,0,.84) 26%, rgba(0,0,0,.73) 35%, rgba(0,0,0,.60) 44%,
    rgba(0,0,0,.46) 52%, rgba(0,0,0,.32) 60%, rgba(0,0,0,.19) 66%,
    rgba(0,0,0,.08) 70%, transparent 74%);
  mask-image:linear-gradient(90deg,
    #000 0%, rgba(0,0,0,.97) 8%, rgba(0,0,0,.92) 17%,
    rgba(0,0,0,.84) 26%, rgba(0,0,0,.73) 35%, rgba(0,0,0,.60) 44%,
    rgba(0,0,0,.46) 52%, rgba(0,0,0,.32) 60%, rgba(0,0,0,.19) 66%,
    rgba(0,0,0,.08) 70%, transparent 74%);
}
/* And the wash mirrors too: weight over the picture, nothing over the
   open right where the type sits on the section's own ground. */
/* The same wash as why-plans-fail, mirrored: this band's own ground,
   solid where the type is and gone where the picture is. #171413 here
   rather than #0F0D0C, because that is this section's colour -- and it
   is the identical value the home page's close band washes with. */
/* Lifted with the brightness above. The old .84/.72 over the picture's own
   half was most of what made the frame invisible -- the grade darkened it
   and then the wash took another 84% of what was left. The copy does not
   need that much: even at these weights the heading measures 13.55. */
/* A LIGHT WASH ONLY. The mask above owns the fade now; if this climbs
   toward opaque as well, the two ramps compound and the visible curve is
   neither of them -- which is what four passes at the mask stops were
   fighting. It just settles the picture's left half a little so the
   photograph does not out-shout the type. */
.pl-final::after{
  content:"";position:absolute;inset:0;z-index:0;
  background:linear-gradient(90deg,
    rgba(23,20,19,.34) 0%,
    rgba(23,20,19,.26) 40%,
    rgba(23,20,19,.12) 64%,
    rgba(23,20,19,0)   82%);
}
/* THE COPY SITS ON THE RIGHT, over the open half of the frame.

   align-items:flex-end pushes the two blocks to the right wall; the
   text inside them stays left-aligned, because right-aligned ragged-left
   body copy is harder to read than a left-aligned block that happens to
   sit on the right. So the block moves, not the setting. */
.pl-final-box{
  position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:flex-end;
  gap:0;max-width:none;
  background:none;border:0;padding:0 var(--hx-inset);
}
/* Wide enough for the heading to hold two lines and no wider, so it
   cannot reach back across the frame to where she is standing.

   The nowrap has to go with it. planning.css sets white-space:nowrap on
   this heading and this paragraph -- harmless while the block ran the
   full 1210, because the two lines measure 690 and 803 and both fitted.
   At 620 they do not: the text kept painting straight out of its own
   box and off the right of the section, while every measurement of the
   box said 620 and looked correct. */
.pl-final-box > div{width:min(620px,52%)}
/* Flush to the band's inset, which is the right edge every other section
   on the page ends on. It carried a 110px offset for a while to sit in
   the middle of the frame's open half; on the page that read as one
   block hanging short of a line all its neighbours reach. */
.pl-final h2,.pl-final p{white-space:normal}
/* A space above 900, a line break below it. display:block on an empty
   inline is the break; contents takes it back out of the box tree so the
   desktop line is unaffected. */
/* THE BREAK IS EVERYWHERE NOW, not just on a phone.

   It used to be display:contents above 900, so the desktop line wrapped
   wherever 620px ran out -- which was after "out of your", leaving
   "head." alone on the second line. The phrase is "out of your head";
   it should arrive in one piece at any width. */
.pl-break{display:block;height:0}
/* THE DESKTOP-ONLY ONE. The closing heading breaks in two different
   places depending on the width: above 900 after "months", so "out of
   your head." is its own line; at or below 900 after "12", so "months
   out of your head." arrives together and nothing is left hanging.

   Two spans rather than one, because a single unconditional .pl-break
   changes both -- which is what moving it did the first time. */
.pl-break-d{display:block;height:0}
@media(max-width:900px){
  .pl-break-d{display:contents}
}

/* The phone-only one, for a heading that is two sentences and fits on a
   single line above 900. */
.pl-break-m{display:contents}
@media(max-width:900px){
  .pl-break-m{display:block;height:0}
}
.pl-final-box > div:last-child{margin-top:30px}
.pl-final-box p{margin:0 0 30px;max-width:none}

/* ============================== responsive ==============================
   The page used 640 / 760 / 900. The home page uses 640 / 900 / 980 /
   1024, and mobile-n12.css is already loaded here, so this page now
   answers to the same breakpoints as the rest of the site. */

@media(max-width:1024px){
  /* The stacked, ruled treatment of the two notes used to be here. It is
     gone: below 1280 they are cards, set further down this file, and
     these rules only existed to be overridden by them. */

  /* THE TIMELINE GOES VERTICAL EARLIER THAN IT USED TO.
     Six positions across a 1024px tablet is about 150px a column, which
     breaks these sentences into three-word lines -- and the whole point of
     the bookends is that they read as sentences, not labels. Below the
     desktop breakpoint the track turns vertical and every entry sits to the
     right of it, bookends included. */
  .pl-beats{
    display:block;margin-top:34px;padding:0 0 0 44px;
  }
  /* Every one of these has to be restated at .pl-beat:nth-of-type()'s
     weight. That selector is (0,2,0) -- a class plus a pseudo-class -- and
     `.pl-beats li` is only (0,1,1), so the desktop placement was quietly
     winning here and leaving nodes stranded in the gaps. */
  .pl-beats li.pl-beat,
  .pl-beats li.pl-beat-cap{
    grid-row:auto;align-self:auto;position:relative;
    padding:0 0 30px;
    /* The desktop cap keeps the copy inside its column; stacked, the
       column is the page. */
    max-width:62ch;
  }
  .pl-beats li:last-child{padding-bottom:0}
  /* Stacked, the bookends are just the first and last entries in the list,
     so label, title and sentence go back to one column. */
  .pl-beats li.pl-beat-cap{display:block;max-width:62ch}
  /* Their node keeps the ground fill and the halo -- that is what punches
     the hole in the vertical track -- and drops only the clay ring to a
     quiet grey, so it still reads as context rather than a step. */
  .pl-beats li.pl-beat-cap .pl-beat-node{
    display:block;border-color:rgba(246,241,234,.3);
  }
  .pl-beats li.pl-beat .pl-beat-node,
  .pl-beats li.pl-beat-cap .pl-beat-node{left:-38.5px;top:2px;bottom:auto}
  .pl-beats li.pl-beat .pl-beat-node::after,
  .pl-beats li.pl-beat-cap .pl-beat-node::after{
    top:50%;bottom:auto;left:100%;margin:0 0 0 5px;
    width:22px;height:1px;
    background:linear-gradient(90deg,var(--pl-accent),rgba(178,132,121,0));
    transform:translateY(-.5px);
  }
  /* Absolute again, and the fade turns with it. An explicit height rather
     than top+bottom: the base rule sets height, and leaving it to resolve
     from the two offsets collapsed the track to nothing. */
  .pl-beats::before,
  .pl-beat-line{
    position:absolute;left:11px;right:auto;top:8px;bottom:auto;
    width:1px;height:calc(100% - 16px);
    -webkit-mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
    mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
  }
  .pl-beat-line{transform:scaleY(0);transform-origin:top}
  .pl-beats.is-drawn .pl-beat-line{transform:scaleY(1)}
  .pl-beat-n{position:static;margin-bottom:8px;padding:0;background:none}
  .pl-beats h3{margin-bottom:8px}
  .pl-beats p{max-width:62ch}
}

@media(max-width:900px){
  .pl-included,.pl-sessions,.pl-choose{padding:76px 0}

  /* THE LEDGER STACKS. A figure hard right of a description needs a
     column of clear space to sit in, and at 393 there is none -- the
     price would end up under the last word of the sentence. Name,
     description, then the figure beneath, left-aligned with everything
     else, and the figure comes down from 50px to 40. */
  /* No indent down here -- at 393 the wrap is already only 305 wide and
     66px of it would be a third of the line. */
  .pl-ledger-row{
    grid-template-columns:1fr;gap:18px 0;
    padding:24px 0;margin:0;
  }
  .pl-ledger-row:hover{background:none}
  .pl-ledger-fig{text-align:left;white-space:normal}
  .pl-ledger-fig strong{font-size:40px}
  .pl-ledger-fig .pl-ledger-alt{white-space:normal}

/* One column, so the rule between the two halves turns horizontal --
     the same move the plan panels and the prices make at this width. */
  /* ONE SUB-HEADING SIZE ON A PHONE, and it is the home page's. The
     clamp bottoms out at 20 on a phone by itself now, so the size does
     not need restating -- only the leading, which the clamp carries from
     .st-move and which this block used to overwrite with its own 1.12. */

  /* AND THE SECTION HEADS TAKE THE HOME PAGE'S PHONE SIZE.

     mobile-n12.css defines --n12-mhead for exactly this, and applies it
     to .hx-head, .st-head, .tr-head and .cl-head. The planning page's
     heads were never added to that list, so they stayed at the clamp's
     26px floor while the home page's went to 32 at 393 -- six pixels,
     on the largest type below the hero, between two pages that are
     meant to read as one site.

     Declared here rather than added to that rule because a media query
     adds no specificity: .pl-fail h2 there would still lose to
     .pl-fail h2 in this file, which loads later. */
  .pl-process-head h2,
  .pl-section-head h2,
  .pl-fail h2,
  .pl-why-bar h2,
  .pl-final h2{font-size:var(--n12-mhead,clamp(29px,8.2vw,34px))}

  /* 76, the home page's phone rhythm, which every band on that page uses
     and which .pl-sessions and .pl-choose already use here. */
  .pl-fail{padding:76px 0}
  /* These two carried a 28px left margin against the page's 44, to buy
     back picture. The page is on the home gutter now -- 20 at 393 -- so
     the override would make them WIDER-margined than everything around
     them, which is the opposite of the point. It goes; the gutter gives
     them more than the special case ever did. */
  /* 80%, not the full width. She stands on the right of the frame and a
     full-bleed column of type ran straight across her -- the band read as
     text on a dark ground rather than text beside a figure. Twenty per
     cent back is enough to clear her head and shoulders, and the copy
     keeps a 45-character measure at 393, which is still a readable line.
     The picture is doing work here; it should be visible. */
  .pl-fail h2,.pl-fail .pl-sub{max-width:80%}
  /* THE SIDE-BY-SIDE COMPOSITION DOES NOT SURVIVE A PHONE. At 393 there
     is no room for a column of type beside a figure, so the copy runs the
     full width and lands straight on her: the desktop treatment measured
     3.94:1 on the body here. The picture goes back to being a quiet
     full-bleed ground, which is the treatment that measured 6.6-7.1
     before the band was rebuilt. */
  .pl-fail-video{
    left:0;right:auto;width:100%;
    -webkit-mask-image:none;mask-image:none;
    /* 48%, over from 56: the copy is left-aligned and 80% wide, so every
       point the frame moves right is one where she is beside the text
       rather than under it. */
    object-position:48% 26%;
    transform:none;
    /* .62 and .55, up from .44 and .4. The old values were set when the
       copy ran the full width and the picture had to disappear under it;
       with the type at 80% and the figure out to the right there is
       nothing to hide her from, and she was reading as a silhouette in
       the dark rather than a person. The band's quietest text still
       measures 5.98 against its brightest pixel, down from 6.88. */
    /* .92 with the desktop rule. At this width the type sits ON the
       footage, so this is the one place the lift has to be checked rather
       than assumed -- measured below in the same pass as the closing band. */
    filter:saturate(.6) brightness(.92) hue-rotate(-18deg);
  }
  /* Full bleed here, so the wash is flat rather than a gradient -- but it
     is the same #0F0D0C the band is, at the weight the type needs. */
  .pl-fail-shade{background:rgba(15,13,12,.78)}

/* THE CLOSE UNSPLITS. Its right-hand column is min(620px,52%), and at
     393 the wrap is 305 wide so 52% is 159 -- narrower than the booking
     button, which is what pushed an element past the viewport. There is
     no room for a figure beside a column of type at this width anyway,
     so the copy goes back to full width on the left.

     And the crop moves with it: at 70% the frame shows the road and the
     sun rather than her, which leaves the stacked text clean ground
     instead of putting it over the car. */
  .pl-final{padding:76px 0}
  /* THE COPY KEEPS THE RIGHT SIDE HERE TOO, at 82% rather than the full
     width. She and the car are on the left of this frame, and a
     full-bleed column left her as an edge of a shoulder in the corner.
     Right-aligned and 18% narrower, the left of the band is hers.

     AND THE TEXT IS SET RIGHT HERE, not just the block. The desktop
     keeps a left-aligned block that happens to sit on the right, because
     ragged-left body copy is harder to read across a 620px measure. At
     305 it is four short lines against a picture, the ragged edge is
     barely ragged, and a left-set block hard against the right wall just
     reads as text that failed to move. */
  /* Its 28px right margin goes with the other two: the wrap's own gutter
     is 20 at 393, so all three now hold the same edge as every band on
     the page rather than three exceptions that agreed with each other. */
  .pl-final-box{align-items:flex-end}
  /* The BLOCK goes full width and the copy inside it stays narrow, which
     is a change from holding the whole thing at 82%. The heading has to
     land in two lines -- "let's get the next 12 months" then "out of
     your head." -- and that first clause needs 354px at the section
     size, which 82% of a 393px screen (289) could never give it. It was
     coming out in three.

     What the 82% was protecting is still protected: the paragraph and
     the buttons keep the narrow measure, so the left of the frame is
     hers everywhere except behind two lines of heading. */
  .pl-final-box > div{width:100%;text-align:right}
  /* 72% of the full width, which is the 254px the paragraph already had
     at 88% of 82%. Narrower than the heading above it on purpose: at the
     same width the two read as one block. */
  .pl-final-box p{width:72%;margin-left:auto}
  /* AND THE HEADING TAKES THE WIDTH IT IS GIVEN.

     Even full-bleed, 354px does not fit in the 353 a 393px screen has --
     it misses by a pixel, and on a 360 it misses by thirty. So the size
     is derived from the width rather than picked: .0909 is the section
     size divided by the width that clause needs at it (32.2/354), so the
     clause fills the line and stops. It only ever comes DOWN from
     --n12-mhead, so wider phones keep the home page's size exactly. */
  .pl-final h2{font-size:min(var(--n12-mhead,34px),calc((100vw - 48px) * .0909))}
  /* Buttons are flex items, so the text-align above does not reach them. */
  .pl-final-box .pl-actions{justify-content:flex-end;align-items:flex-end}
  /* Full bleed and unmasked again, like the why-plans-fail band does at
     this width: there is no room for a figure beside a column of type,
     so the picture goes back to being a quiet ground under it. */
  .pl-final::before{
    /* 50%. It was 64, which put her at the very left edge with her head
       cut off, and 44 brought her fully in but then left her standing in
       the middle of the band with the road behind her doing nothing. 50
       is six points back: she keeps her head, the car crops at the edge
       the way a photograph does, and the open ground between her and the
       type belongs to the road rather than to neither of them. */
    /* back to cover here: the desktop rule now zooms to 125% to buy
       vertical play in a 64%-wide panel, and at full bleed on a phone
       that same zoom just crops her out sideways. */
    width:100%;background-position:50% 46%;background-size:cover;
    -webkit-mask-image:none;mask-image:none;
    /* .92 like the desktop rule, so the band does not lighten on one and
       stay dark on the other. The wash below keeps its own weight: here the
       type sits ON the picture at full bleed rather than beside it, so the
       phone cannot spend contrast the way the desktop band could. */
    filter:saturate(.6) brightness(.92) hue-rotate(-18deg);
  }
  .pl-final::after{background:rgba(23,20,19,.78)}

  /* Label over argument, like every other pair on this page at phone
     width. */
  .pl-why{padding:76px 0}
  /* 80%, the same measure why-plans-fail's supporting line takes below
     900 -- these two bands are the same shape and the same argument at
     the same size, and the 72% they share above that width left this one
     254 against the other's 282 on a phone. Above 900 both are
     min(86ch,72%) and already agree; this only closes the gap the phone
     rule opened. The link goes with it: it is the last line of the same
     column, and a shorter measure on it would put its underline short of
     where the paragraph ends. */
  .pl-why-bar p{font-size:15px}
  .pl-why-bar p,.pl-why-link{max-width:80%}
  /* THE TWO CACTUSES GO TO THE RIGHT EDGE.

     The picture is a 3:1 panorama and the band on a phone is roughly
     1:2.7, so cover scales it about 1.45x and shows a 393px slice of a
     3180px image -- at the default 50% that slice is empty dune and the
     only two objects in the frame are 2500px off to the right.

     85%: the pair sits at 80-90% of the source, so the far end of the
     image is past them, and every point below 100 walks them rightwards
     across the screen. 88 put them whole in frame but with the smaller
     one standing in the middle of the paragraphs; 85 is 84px further
     right, which clears the type at the cost of the taller one's arm
     running off the edge -- which reads as a photograph cropped at the
     edge rather than a mistake. Below about 83 both start losing shape. */
  .pl-why::before{background-position:85% 50%}
  /* And the wash goes .46 -> .56 with it. The old slice was dune; this
     one is the horizon, which is the brightest part of the photograph,
     and the label and body measured 4.40 and 4.55 against it -- under
     the floor at four of six widths. .56 puts the whole band at 5.1 or
     better with the cactuses still reading as silhouettes, and it is
     headroom rather than a pass: the last time this page shipped a 4.46
     it went under as soon as a line of copy was rewritten. */
  .pl-why::after{background:rgba(23,20,19,.56)}

  .pl-plan-window{margin-top:40px}
  .pl-plan-outcomes{margin-top:40px}

  /* THE BAND STACKS.

     Two columns need roughly 900px to stay readable; below that the aside
     would be a 40-character alley. One column, headline then supporting
     line then buttons -- which is fine here in a way it was not in the old
     panel, because the picture is no longer behind it fighting for the
     same pixels.

     The image band shortens rather than growing: on a phone the picture is
     establishing the page, not carrying it, and every pixel it takes is one
     the headline does not get above the fold. */
  /* The same height as the home page's photo strip, in px rather than vh,
     so the two pages open identically on a phone -- and the same two
     short-phone tiers below.

     The picture is gone, so the crop, the zoom and the phone-only flat
     wash that used to live here have gone with it. What is left is the
     height, which still matters: it is what keeps the headline and both
     buttons above the fold on a phone. */
  .pl-top{--pl-hero-h:404px}
  .pl-hero{min-height:var(--pl-hero-h)}
  /* Below the software page's own breakpoint the centred column and the
     full-bleed inset resolve to the same thing anyway, so the hero goes
     back to the page's wrap and stops being a special case. */
  .pl-hero-wrap{
    /* Same arithmetic as the desktop rule: the masthead is 104px here too
       and it is laid over the picture, so anything under ~128 puts the
       eyebrow through the nav. 100 only ever worked because align-items
       was silently centring the block and pushing it clear. */
    padding-top:128px;padding-bottom:24px;
    width:100%;margin-inline:0;
    padding-left:var(--hx-inset);padding-right:var(--hx-inset);
  }
  /* Caveat runs small for its point size, so the phone step is gentler
     than the 17->15.5 it was: 26 against 30 rather than the proportional
     cut, which would have left it smaller than the body copy beneath. */
  .pl-hero-copy p{font-size:26px;margin-top:12px}
  
}

/* The two short-phone tiers. They used to match the home page's photo
   heights exactly, which worked while this hero held a headline and
   nothing else. It now holds four elements, so the floor has to clear
   them: at 205px the copy was starting six pixels under the masthead.

   The padding comes down with the height rather than the floor doing all
   the work, or the block ends up pinned to the bottom of a short box. */
/* The padding-top these two used to cut is no longer free. Under
   flex-start it is the nav clearance and nothing else, so 96 and 84 just
   put the eyebrow back under the masthead without buying any height --
   the box is on a min-height regardless. What does the fitting on a short
   phone is the type coming down, which stays. */
@media(max-width:900px) and (max-height:840px){
  .pl-top{--pl-hero-h:404px}
  .pl-hero-wrap{padding-bottom:22px}
}
@media(max-width:900px) and (max-height:720px){
  .pl-top{--pl-hero-h:402px}
  .pl-hero-wrap{padding-bottom:20px}
  .pl-hero-copy p{font-size:24px;margin-top:10px}
  
}

@media(max-width:640px){
  /* THE CORNER IS NOT A CORNER AT PHONE WIDTH. "1 YEAR PLAN" and
     "DEADLINE DEC 31 2026" do not fit on one line in a 340px panel, and
     the date carries white-space:nowrap, so it pushed out of the panel
     rather than breaking -- 35 elements past the client width at 393,
     against none before. It drops to its own line here. */
  .pl-panel-title{flex-wrap:wrap;row-gap:7px}
  .pl-panel-due{margin-left:0;flex:0 0 100%}

  /* AND THE PLAN STACKS, which it was always supposed to. planning.css
     sets grid-template-columns:1fr for this band below 900; the rule in
     this file sets 1fr 1fr with no breakpoint and, loading later, won
     everywhere -- so the mock has been two 154px columns on a phone.

     It stayed invisible because the window clips it: the page never
     scrolled sideways, it just quietly cut the right-hand column off.
     The nowrap date in the panel header is what finally made it
     measurable, pushing 31 elements past the viewport at 393.

     min-width:0 with it, because a grid item's auto minimum is its
     min-content width and the date would otherwise put that floor back
     into the track. */
  .pl-plan-columns{grid-template-columns:1fr;gap:22px}
  .pl-plan-columns > *{min-width:0}

  /* One up. Vertical rules make no sense in a single column, so they
     become horizontal ones between the cards. */
  .pl-plan-outcomes{grid-template-columns:1fr}
  .pl-plan-outcomes article,
  .pl-plan-outcomes article:nth-child(odd),
  .pl-plan-outcomes article:nth-child(even){
    padding:26px 0 30px;border-left:0;border-right:0;
    border-top:1px solid var(--n12-line);
  }
  .pl-plan-outcomes article:first-child{border-top:0;padding-top:0}

/* The buttons stack and sit left, the way they do on the home page. */
  .pl-actions{flex-direction:row;flex-wrap:wrap;gap:14px 13px;align-items:center}

  .pl-final-box p{margin-bottom:26px}
  .pl-final-box > div:last-child{margin-top:24px}
}

/* ================ 13. the plan itself, on a small screen ================

   THE MOCK ARRIVES THIRD, WHICH IS ONE PLACE TOO LATE.

   On a phone the band reads: "this is the plan", then both annotations,
   then the window -- 480px of scrolling between the promise and the
   thing. The notes are captions; they belong under what they caption.
   Above 1280 this does not arise, because the two of them are absolutely
   positioned in the alleys either side of the window and the reading
   order is spatial rather than vertical.

   Flex only to get `order`. The band is a plain block stack otherwise and
   stays one -- nothing here wants flex layout, it wants three children in
   a different sequence.

   To 1279, matching the ring: the notes and the mark that connects them
   to the plan have to switch over at the same width, or a tablet gets
   cards with no ring or a ring with nothing to tap. */
@media(max-width:1279px){
  /* THE PLAN COMES UP UNDER THE ARROW -- and the amount it comes up by
     is the same expression the desktop uses, not a flat -26.

     The hero carries `min-height:var(--pl-hero-h)`, which resolves to
     500px at 1024 and 507 at 1180 while the copy ends at 294. Above
     1280 the tour cancels that with `calc(308px - var(--pl-hero-h))`;
     below it, the min-height stayed and the cancellation did not, so
     the arrow was left hanging over 184-204px of empty hero. A flat
     -26 could not fix both ends of the range either -- measured, it
     left 184 at 1024 and -12 at 900, where the arrow overlapped the
     plan window.

     One expression, every width: the window's top is 308px from the
     document top whatever the hero does. */
  .pl-tour{display:flex;flex-direction:column;margin-top:calc(308px - var(--pl-hero-h))}
  /* 290 on a phone, because the hero's nav clearance is 110 there
     rather than 128 -- the arrow finishes 18px higher, so the window
     has to follow it up or the gap re-opens to 38. */
  @media(max-width:700px){
    .pl-tour{margin-top:calc(290px - var(--pl-hero-h))}
  }
  .pl-stage-wrap{order:1}
  /* The notes are cards now rather than two marks reaching up at the
     window, so they take a gap: they sit under the plan, they are not
     touching it. */
  /* The two margins either side of the hint are not equal, and should
     not be: the cards lean, so their rotated boxes rise about 4px above
     where they are laid out, and the tack hangs 4px above that again.
     The numbers below put the LINE centred between the plan's bottom
     edge and the topmost pixel the notes actually paint. */
  .pl-tour .pl-plan-outcomes{order:3;margin-top:14px;margin-bottom:0}
  .pl-tour .pl-actions{order:4}
  /* 58 was set for the desktop, where the notes are two tall margin
     columns either side of the plan and the buttons need clearing from
     both. Under a pair of small cards it read as a hole. */
  .pl-tour .pl-actions.pl-plan-actions{margin-top:30px}
  /* It is the first thing in the band now, so its own top margin goes and
     the band's padding does that work. */
  .pl-plan-window{margin-top:0}
  /* 4, down from 18, 34 and 52 before that. The hero's arrow ends 24px
     above the band's own edge, so what a reader sees between its head
     and the window is this plus that; the band's padding is the only
     half of it that is free to go. */
  .pl-included{padding-top:4px}
  .pl-hero-wrap{padding-bottom:10px}

  /* AND THE TWO NOTES STAY ANNOTATIONS.

     Above 1280 they sit in the alleys either side of the window, set in
     Caveat with a clay numeral, and the ink layer draws a ring and an
     arrow from each into the region of the plan it describes. Below that
     the alleys are gone and they stack under the window -- where they
     arrived as two more League Spartan headings, with nothing saying
     they were annotations on the thing above rather than the next
     section of the page.

     So they keep the handwriting, and each gets a short arrow drawn back
     up into the window. Same generator as the hero's, mirrored on y:
     the note is under what it annotates here, where the hero's arrow is
     above it.

     This block, not the 900 one, because that is where the notes start
     stacking -- at 901-1024 they were getting the marker with no box to
     draw in. */
  /* AND THEY SIT EITHER SIDE, UNDER THE PANEL EACH ONE IS ABOUT.

     Stacked full-width they were two captions in a column under a
     two-column picture, and nothing connected either one to its half of
     it. Side by side, the year's note is under the year panel and the
     quarter's is under the quarter panel -- the same left-right pairing
     the alleys make above 1280, folded below the window instead of
     wrapped around it.

     They get smaller with it, because the column does: 167px at 393. The
     body goes to 14/1.5 and the handwriting to 22 -- this is the one
     place on the page a step down from the body size is earned, because
     they have stopped being prose in the flow and become captions on a
     picture. */
  /* AND THEY ARE TWO NOTES, NOT TWO CAPTIONS.

     Small cards on a slight lean with a tack in the corner, each one a
     button: tapping draws the ring around the half of the plan it names.
     That is the whole reason for the treatment -- a card looks like
     something to pick up, and a caption does not, and on a touch screen
     nothing else advertises that the pair do anything. */
  .pl-plan-outcomes{grid-template-columns:1fr 1fr;gap:0 12px}
  .pl-plan-outcomes article,
  .pl-plan-outcomes article:nth-child(odd),
  .pl-plan-outcomes article:nth-child(even){
    position:relative;padding:12px 13px 13px;border:1px solid rgba(246,241,234,.1);
    border-radius:3px;background:#211C1A;cursor:pointer;
    box-shadow:0 10px 22px rgba(0,0,0,.4);
    /* --r is the note's resting angle, so the drift keyframes can be
       written once and still respect each one's own lean. */
    --r:-1.6deg;
    transform:rotate(var(--r));
    /* opacity is in this list on purpose. A transition shorthand REPLACES
       the one reveal-n12.css sets, so without it the card had no opacity
       transition at all and snapped to visible while everything around it
       faded. Same .6s, same easing, same --rv-d, so it keeps its place in
       the stagger. The reveal's translateY is a casualty either way --
       the drift animation owns transform on these two. */
    transition:transform .35s cubic-bezier(.34,1.56,.64,1),
               border-color .3s ease,box-shadow .3s ease,
               opacity .6s cubic-bezier(.16,1,.3,1) var(--rv-d,0ms);
    animation:pl-note-drift 7.5s ease-in-out infinite;
  }
  .pl-plan-outcomes article:last-child{--r:1.5deg;animation-duration:8.6s;animation-delay:-3.2s}
  /* The tack. Clay on the year, blue on the quarter, on the outside
     corner of each so the pair opens outward. */
  .pl-plan-outcomes article::before{
    content:"";position:absolute;top:-4px;left:13px;width:8px;height:8px;
    border-radius:50%;background:var(--pl-accent);
    box-shadow:0 2px 5px rgba(0,0,0,.5);
  }
  .pl-plan-outcomes article:last-child::before{
    left:auto;right:13px;background:var(--pl-ink-2);
  }
  /* Picked up: the drift comes OFF -- an animation beats a transition on
     the same property, so with it running the settle never showed -- and
     the note straightens most of the way and lifts. */
  .pl-plan-outcomes article.is-on{
    animation:none;
    transform:rotate(calc(var(--r) * .25)) translateY(-5px) scale(1.02);
    border-color:rgba(178,132,121,.55);box-shadow:0 16px 30px rgba(0,0,0,.5);
  }
  .pl-plan-outcomes .pl-note-alt.is-on{border-color:rgba(169,184,198,.55)}
  .pl-plan-outcomes article:hover{background:#211C1A}
  @keyframes pl-note-drift{
    0%,100%{transform:rotate(var(--r)) translateY(0)}
    50%{transform:rotate(calc(var(--r) * .55)) translateY(-3px)}
  }
  @media(prefers-reduced-motion:reduce){
    .pl-plan-outcomes article,
    .pl-plan-outcomes article:nth-child(odd),
    .pl-plan-outcomes article:nth-child(even){animation:none}
    .pl-plan-outcomes article.is-on{transform:rotate(var(--r))}
  }
  /* Mirrored: the first note set left in its column, the second right,
     so the pair brackets the window the way the alleys do above 1280.
     It costs the right-hand note a ragged left edge over three lines at
     168px, which is the trade for the two marks sitting at opposite
     ends of the band instead of both hugging the same side.

     AND THEY ARE NOT ON THE SAME LINE. Two notes with their arrows,
     numerals and headings on four shared baselines read as a table with
     the rules taken out. Dropping the second one and leaning the two
     headings opposite ways is the difference between a layout that
     happens to hold annotations and something written on the page --
     which is what the rest of this band's ink is for.

     Small numbers on purpose: 14px of drop and a degree and a half of
     lean. Enough that the pair is not square, not so much that it reads
     as broken. The lean lives on the CARD now rather than on the
     heading -- the whole note is the thing resting on the page. */
  .pl-plan-outcomes{align-items:start}
  .pl-plan-outcomes article:last-child{margin-top:14px}

  /* A step down from the 22 they were: the card takes 26px of the
     column's 170 in padding, and the handwriting has to fit the words on
     the lines it had. */
  .pl-plan-outcomes h3{
    /* inline-block so the wipe below hugs the words. As a block it would
       run the width of the card and spend the tail of its travel over
       empty space, which reads as a delay rather than as writing. */
    display:inline-block;
    font-family:'Caveat',cursive;font-weight:700;
    font-size:19px;line-height:1.02;letter-spacing:0;
    text-transform:none;color:#E8CDC2;
    margin:0 0 5px;
  }

  /* WRITTEN OUT DOWN HERE TOO, NOT JUST IN THE ALLEYS.

     The same left-to-right wipe the desktop's notes get, on the same
     .is-inked switch -- which the tour script sets at any width, so all
     this needed was the rules. The inset is generous top and bottom
     because Caveat's ascenders and descenders run past the line box and
     a tight clip shears them. */
  .rv .pl-tour .pl-plan-outcomes h3{
    clip-path:inset(-22% 100% -30% 0);
  }
  .rv .pl-tour.is-inked .pl-plan-outcomes h3{
    clip-path:inset(-22% -8% -30% 0);
    transition:clip-path .8s cubic-bezier(.36,.82,.5,1) var(--write,0s);
  }
  /* The numeral arrives just ahead of the words it labels. */
  .rv .pl-tour .pl-plan-outcomes article > span{
    opacity:0;transform:translateY(4px);
  }
  .rv .pl-tour.is-inked .pl-plan-outcomes article > span{
    opacity:1;transform:none;
    transition:opacity .4s ease var(--write,0s),
               transform .5s cubic-bezier(.16,1,.3,1) var(--write,0s);
  }
  /* One writes, then the other. Both at once is a layout appearing; one
     after the other is somebody writing two notes. */
  .pl-tour .pl-plan-outcomes article:first-child{--write:.34s}
  .pl-tour .pl-plan-outcomes .pl-note-alt{--write:.62s}
  @media(prefers-reduced-motion:reduce){
    .rv .pl-tour .pl-plan-outcomes h3,
    .rv .pl-tour.is-inked .pl-plan-outcomes h3{clip-path:none;transition:none}
    .rv .pl-tour .pl-plan-outcomes article > span{opacity:1;transform:none}
  }
  /* The numerals go back to the page's sans here. In the alleys they are
     handwriting because the whole note is a margin scrawl; on a card
     they are a label on a thing, and two sizes of Caveat stacked in a
     144px box was the note arguing with itself. */
  .pl-plan-outcomes article > span{
    font-family:'League Spartan',sans-serif;font-weight:600;
    font-size:10px;letter-spacing:.2em;line-height:1;
    margin-bottom:4px;
    color:var(--pl-accent);
  }
  /* The same two inks the desktop uses: the year in clay, the quarter in
     the pale blue -- which is also the colour the plan's own quarterly
     figures are set in. The phone had both notes in clay, so a pairing
     that runs through the whole band stopped at the annotations. */
  .pl-plan-outcomes .pl-note-alt > span{color:var(--pl-ink-2)}
  .pl-plan-outcomes .pl-note-alt h3{color:#CFDCE8}
  .pl-plan-outcomes p{font-size:12px;line-height:1.45;color:rgba(246,241,234,.6)}
}

/* AND THE CARD IS NOT ALWAYS 170px WIDE.

   The sizes above are drawn for a phone, where the column is 170 and the
   plan is painted at .46. From 641 to 1024 the plan is at full size and
   each card is 350 to 480 across -- 19px of handwriting and a 12px body
   in a box that wide is a note written for a different page. The
   treatment is the same; only the type and the padding come back up. */
@media(min-width:641px) and (max-width:1279px){
  .pl-plan-outcomes{gap:0 18px}
  .pl-plan-outcomes article,
  .pl-plan-outcomes article:nth-child(odd),
  .pl-plan-outcomes article:nth-child(even){padding:18px 20px 19px}
  .pl-plan-outcomes article::before,
  .pl-plan-outcomes article:last-child::before{width:9px;height:9px;top:-5px}
  .pl-plan-outcomes article::before{left:20px}
  .pl-plan-outcomes article:last-child::before{left:auto;right:20px}
  .pl-plan-outcomes h3{font-size:25px;line-height:1.02;margin:0 0 7px}
  .pl-plan-outcomes article > span{font-size:11px;margin-bottom:6px}
  .pl-plan-outcomes p{font-size:14px;line-height:1.5}
  /* Same centring, recomputed: the line is a point taller here and the
     tack hangs 5px rather than 4. */
  .pl-note-hint{font-size:12.5px;margin-top:7px}
  .pl-tour .pl-plan-outcomes{margin-top:17px}
}

/* AND THE BAND ABOVE IT GIVES BACK THE ROOM IT IS NOT USING.

   404px was the home page photo strip's height, carried over so the two
   pages would open the same way, and then sized to clear a headline and
   two buttons. There is no picture here any more and the buttons moved
   under the plan: what is left is an eyebrow, four words and a line of
   Caveat -- 107px of type, top-aligned under a 128px nav clearance,
   followed by 169px of nothing before the window starts.

   312 clears the masthead, the copy and a comfortable foot, and it is
   what puts the plan under the sentence that promises it. It also
   supersedes the two short-phone tiers above, which were fitting a
   taller band into a shorter viewport -- a problem this height does not
   have on any phone. */
@media(max-width:900px){
  .pl-top{--pl-hero-h:312px}
}

/* AND IT COMES DOWN IN SIZE.

   At full size the window ran 1169px tall at 393 -- one and a third
   screens of it -- and every goal wrapped to two lines inside a 305px
   column. It stopped reading as a picture of software and started
   reading as a page of it.

   zoom, not transform:scale. Scale paints smaller but still occupies the
   unscaled box, so it would leave ~400px of hole under the window that
   no amount of negative margin fixes responsively. zoom is laid out at
   the reduced size, so the band closes up on its own.

   Thumbnail scale, and meant to be. The text inside is decorative --
   what the plan contains is said in full, at full size, in the two notes
   underneath -- so it can go far smaller than the page's own copy ever
   could. What it has to keep is structure: two panels, five numbered
   goals, four named people, each on its own line.

   AND AT THIS SCALE THE YEAR AND THE QUARTER GO BACK SIDE BY SIDE.

   They were stacked below 640 because at full size a 305px window
   cannot carry two columns -- it was two 154px tracks with the
   right-hand one clipped off. Zoomed, the window is 850px in its own
   coordinates and the two panels get 390 each, which is more than the
   desktop layout gives either of them.

   It matters beyond the height. Stacked, the mock is a long document
   you scroll; side by side it is the shape of the real thing -- the year
   on the left, the quarter beside it -- which is the one job a picture
   of software has at this size, since nothing in it is being read.

   1169px tall stacked at full size becomes 164. */
@media(max-width:640px){
  /* .26. The floor is not legibility -- nothing in here is read -- it is
     that the panels go hollow. Zooming out widens the columns in the
     window's own coordinates (654px each at a 320px phone by .22), so
     the goals occupy less and less of each row and the year panel ends
     in a field of empty ground. At .26 both panels still read as full;
     by .18 the mock is a postage stamp with holes in it.

     Above this, .36 was where the last wrapping goal came onto one line
     and .41 left it on two -- so anything between .26 and .36 keeps all
     five goals single-line, which is the quality that makes this read as
     a screenshot rather than a squeeze. */
  /* TRANSFORM, NOT ZOOM -- and this is the third attempt at the same
     bug, so it is worth saying why this one cannot come back.

     Under zoom the mock laid out at 1/.26 of its painted size: narrow
     blocks of small type, which is precisely what Safari's Text
     Autosizing pass looks for. It boosted the type back to full size
     inside tracks sized for .26, and the numerals landed on the goals
     they number. text-size-adjust:100% on the window did not stop it,
     and neither did the same declaration on html -- both shipped, both
     changed nothing on the device, and neither can be reproduced in a
     desktop browser because the pass only runs on the phone.

     A transform does not give it anything to act on. The mock lays out
     at its FULL width -- the same layout the desktop has, where this has
     never happened -- and only the painted result is scaled. Whatever
     the phone decides about text size, it decides it about a desktop
     layout. It is also immune the other way: if the cause was ever an
     iOS quirk in zoom itself rather than autosizing, there is no zoom
     here to be quirky.

     The cost is that a transform does not change layout, so the window
     still occupies its unscaled height and leaves a hole under it. No
     CSS expression knows that height -- it is content-dependent -- so
     the inline script measures the painted box and sets the stage to it.
     Height is the only thing the script owns; if it never runs, the band
     is too tall and nothing else is wrong. */
  .pl-plan-window{
    /* .46, and the scale is not a taste setting -- it is the reciprocal
       of how wide the mock's content needs to be. .26 was set when the
       window laid out at 1358px, which is what it needed while the
       deadline sat opposite each panel title and the status tags sat
       under their goals. With the deadline stacked and the tags back
       beside their names, 767 is enough, and everything inside renders
       nearly twice the size in the same frame.

       .52 is the next step and most of the goal lines wrap at it; .46 is
       the last value where they hold one line. */
    --s:.46;
    width:calc(100% / var(--s));
    transform-origin:top left;
  }
  /* The transform needs its own selector. reveal-n12 sets transform:none
     on `.rv [data-rv].is-rv` -- (0,3,0), which beats a bare class -- and
     the window is one of the reveal's items, so a plain
     .pl-plan-window{transform:...} was silently discarded and the mock
     rendered at full size. Matched at (0,3,0) and later in the cascade.
     The plain selector stays for the no-JS case, where nothing has put
     .rv on the document. */
  .pl-plan-window,
  .rv .pl-tour-stage .pl-plan-window{transform:scale(var(--s))}
  /* Belt and braces on the layout box the transform leaves behind. */
  .pl-tour-stage{overflow:hidden}
  .pl-plan-columns{grid-template-columns:1fr 1fr}

  /* THE MOCK KEEPS ITS DESKTOP INSIDES.

     This is the thing every earlier attempt got wrong, in the same way,
     four times. The window's LAYOUT is 883px wide here -- it always was,
     under zoom too -- so every phone rule aimed at its internals was
     reshaping a desktop-width panel for a screen it is not on. They were
     written when the window laid out at the viewport's width, which it
     has not done since it started being scaled.

     What they cost, in the order they showed up on the page: the two
     status tags dropped under their goals instead of sitting beside
     them, because planning.css moves .pl-person to two columns below
     760 and the tag to its own row -- four extra rows of height inside a
     panel with 380px of unused width. The chrome was cut to 36px and the
     labels to 9.5, both of which only made sense at .26. The window
     carried margin-left:-7px from the same block: outside the transform,
     so it shifted the painted box seven pixels left of the stage, and
     overflow:hidden on the stage took the traffic-light corner off.

     So the mock goes back to being what it is -- a picture of the
     desktop product -- and only the scale is phone-specific. */
  .pl-plan-window{margin-left:0;margin-right:0;border-radius:12px}
  .pl-window-top{height:48px;padding:0 18px;font-size:12px;grid-template-columns:1fr auto 1fr;gap:0}
  
  .pl-plan-body{padding:28px}
  .pl-plan-columns{grid-template-columns:1fr 1fr;gap:28px}
  .pl-goals-panel,.pl-quarter-panel{padding:20px}

/* The status tag beside the name it belongs to, not under it. */
  .pl-person{grid-template-columns:34px 1fr auto}
  .pl-person em{grid-column:auto}
  /* And the labels back to the mock's one label style. */
  .pl-panel-title span,
  .pl-panel-title b,
  .pl-meas > span,
  .pl-plan-figs span,
  .pl-panel-due em{font-size:11px;letter-spacing:.14em}
  .pl-panel-title b{font-size:13px;letter-spacing:.04em}
  .pl-plan-figs strong{font-size:18px}

/* THE ONE THING THAT STAYS PHONE-SPECIFIC INSIDE THE WINDOW.

     margin-left:auto puts the deadline against each panel's right wall,
     which on a desktop is a corner. It also sets the panel's width,
     because a title and a date on one line need room nothing else in
     there needs -- five goal lines, four names, two figures are all
     short. Stacked under the title it costs one row of height and takes
     475px off the layout the whole mock demands, which is what pays for
     the scale above. */
  .pl-panel-title{flex-wrap:wrap;row-gap:3px}
  .pl-panel-due{flex:0 0 100%;margin-left:0}
}

/* NO REVEAL OVERRIDE HERE, DELIBERATELY. See the matching note on
   .swa-app in software-app.css. Restating the transition from outside
   the reveal system stops it firing at all: the reveal class lands
   before first paint on anything already in view, and this window sits
   at y336 in a 950px viewport, so it is always in view at load. It read
   as the plan being "already loaded" when the page opened. The system's
   own timing works and is left alone. */
