/* =========================================================================
   proof-tree.css — the three cases hung off a vertical spine.

   Vertical was never the problem. The problem was that each row used half
   the width and left the other half empty, and that the three sat there as
   separate blocks with nothing tying them together.

   Alternating around a centre line fixes both: every row now fills both
   halves -- picture on one side, copy on the other -- and the spine running
   between them makes the three read as one sequence rather than three
   unrelated slabs.

   The spine draws as you scroll. It is scroll-linked rather than ambient:
   nothing moves unless the reader does.
   ========================================================================= */

/* .lf-block.tr, not .tr. The section carries lf-block and lf-gd3 itself, so
   a single-class selector loses to .lf-block.lf-gd3 on the very same
   element and the ground stayed grey. Two classes match that weight, and
   this file loads later. */
.lf-block.tr{
  /* Pin the accent to clay here. Without this it inherits --lf-accent from
     .lf-block, which resolves to WHEAT -- only .lf--clay switches it. Every
     "var(--lf-accent, #B28479)" below was therefore falling back to nothing,
     because the variable was defined, just defined as the other colour. */
  --lf-accent:#B28479;
  /* Back to the hero's black rather than continuing the grey. Four sections
     on two grounds -- black, grey, grey, black -- so the page closes on the
     tone it opened with, and the where-to-start photograph sits between two
     darker bands instead of running into one. The nodes and their haloes
     read --lf-ground too, so they follow. */
  --lf-ground:#0F0D0C;
  background:var(--lf-ground,#171413);
  color:var(--n12-cream);
  padding:118px 0;
  /* No top rule. The page already has the tab rule, the column dividers and
     the spine; the section above it ends on the same ground anyway, so the
     line was separating two things that were already continuous. */
}
/* The quote sits opposite the heading rather than under it. It is the one
   outside voice in the section, so standing it apart from the company's own
   words is worth the asymmetry -- and it fills the right half of a band
   that was empty. */
.tr-wrap{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,42%);
  gap:clamp(32px,5vw,90px);align-items:center;
  padding:0 var(--hx-inset);
}
@media(max-width:900px){.tr-wrap{grid-template-columns:1fr;gap:30px}}

/* Flush to the heading, like every section label on the planning page. */
.tr-eyebrow{
  display:block;margin-bottom:0;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:rgba(246,241,234,.7);
}
.tr-head{
  margin:0;font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(26px,2.65vw,38px);line-height:1.02;letter-spacing:-.035em;
  text-transform:lowercase;
}
/* 18, the same head-to-subtext gap as the before/after and where-to-start
   bands. The four were on 18, 18, 16 and 20. */
.tr-sub{margin:18px 0 0;font-size:15px;line-height:1.6;color:rgba(246,241,234,.68)}

.tr-link{
  display:inline-flex;align-items:center;gap:9px;margin-top:20px;
  font-size:15px;color:var(--n12-cream);
  border-bottom:1px solid rgba(246,241,234,.3);padding-bottom:2px;
  transition:border-color .16s ease;
}
.tr-link:hover{border-color:var(--n12-cream)}
.tr-link svg{width:17px;height:17px;transition:transform .2s ease}
.tr-link:hover svg{transform:translateX(4px)}

/* Held in a container rather than sitting loose. A bare rule on the left
   was the same device the result lines use inside the rows, so the one
   outside voice in the section looked like more of the company's own copy.

   Sharp corners throughout: the page has no rounded shapes except the
   screenshots, which are rounded because real windows are. */
/* The slab: no outline, a solid tint and a thick clay edge. No quote glyph
   -- the words are already in quotation marks, so a decorative one was
   saying it twice. */
/* The clay edge is on the RIGHT. The block sits on the right of the band,
   so an edge there frames it against the page rather than fencing it off
   from the heading it sits beside. */
.tr-quote{
  position:relative;margin:0;
  border-right:4px solid var(--lf-accent,#B28479);
  background:rgba(178,132,121,.11);
  padding:26px 26px 24px 28px;
}

/* ------------------ alternatives, kept for comparison ------------------ */

.tr-quote--panel{
  border:1px solid rgba(178,132,121,.32);border-left-width:1px;
  background:rgba(178,132,121,.07);padding:26px 28px 24px;
}
.tr-quote--brackets{
  border:0;background:none;padding:22px 24px;
}
.tr-quote--brackets::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(var(--lf-accent) 0 0) left top/26px 1px no-repeat,
    linear-gradient(var(--lf-accent) 0 0) left top/1px 26px no-repeat,
    linear-gradient(var(--lf-accent) 0 0) right bottom/26px 1px no-repeat,
    linear-gradient(var(--lf-accent) 0 0) right bottom/1px 26px no-repeat;
}
.tr-quote--rules{
  border:0;border-top:1px solid rgba(178,132,121,.45);
  border-bottom:1px solid rgba(178,132,121,.45);
  background:none;padding:24px 0 20px;
}
.tr-quote--rules cite{border-top-color:rgba(178,132,121,.18)}
/* Desktop size unchanged, and text-wrap:balance is what fixes the orphan.

   The orphan was real and it was at 1600px: the size clamps out at 22px
   while the column keeps widening, so line one took nine of the ten words
   and left "efficiency." on its own. I first fixed that by raising the
   ceiling to 26px, which worked but made the quote bigger at every width
   above 1100 -- a change to the desktop that nobody asked for, to solve a
   problem balance already solves. balance evens the two lines at any
   width rather than filling the first and dropping the remainder, so
   there is no width at which one word can be left behind.

   Mobile takes it up to 21px on its own, in mobile-n12.css, because there
   the attribution was outweighing it. */
.tr-quote p{
  position:relative;
  margin:0;font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(18px,1.55vw,22px);line-height:1.24;letter-spacing:-.02em;
  color:var(--lf-accent,#B28479);
  text-wrap:balance;
}
/* Attribution to the right, under a left-aligned quote. Standard editorial
   pairing, and it puts the name against the clay edge. */
/* No rule above it. A dash is enough to mark an attribution, and the page
   had a line for everything by this point. */
.tr-quote cite{
  display:flex;align-items:center;flex-wrap:wrap;justify-content:flex-end;
  margin-top:18px;font-style:normal;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:rgba(246,241,234,.52);
}
.tr-quote cite::before{
  content:"\2014";margin-right:10px;
  color:rgba(178,132,121,.75);
}
/* A real rule, not a middot. The dot sat right after the period in
   "Chris I." and the two read as one piece of punctuation. */
.tr-quote cite span{
  margin-left:12px;padding-left:12px;
  border-left:1px solid rgba(178,132,121,.5);
}

/* ------------------------------- the spine ------------------------------- */

.tr-list{position:relative;margin-top:72px;padding:0 var(--hx-inset)}

.tr-spine{
  position:absolute;left:50%;top:0;bottom:0;width:1px;
  transform:translateX(-.5px);
  background:var(--n12-line);
  /* fade at both ends so the line does not collide with the section edges */
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 46px,#000 calc(100% - 46px),transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 46px,#000 calc(100% - 46px),transparent 100%);
}
/* Clay all the way down. It used to resolve to cream at the bottom, which
   made the line read as a different colour from the nodes it connects. */
.tr-spine i{
  display:block;width:100%;height:100%;
  background:var(--lf-accent,#B28479);
  transform:scaleY(var(--tr-p,0));transform-origin:top center;
}

/* ------------------------------- the rows ------------------------------- */

/* Gutter down from 96 to 68: the copy column was 557px but the paragraphs
   were capped well short of it, so the text sat in a narrow strip with
   dead space beside it. */
.tr-row{
  position:relative;
  display:grid;grid-template-columns:minmax(0,1fr) 68px minmax(0,1fr);
  align-items:center;
  padding:38px 0;
}
.tr-row + .tr-row{padding-top:38px}
/* The last row's own bottom padding sat on top of the section's, making the
   space below 142 against 112 above. */
.tr-row:last-child{padding-bottom:0}

/* Odd rows put the picture left, even rows swap. The node stays in the
   middle column either way, so the spine is never interrupted. */
/* grid-row:1 on all three is what makes align-items:center work. Without
   it, an even row asks for column 3 (figure), then column 2 (node), then
   column 1 (body) -- and auto-placement will not move backwards, so it
   pushed the node and the body into rows 2 and 3. That is why the plan's
   copy sat below its picture instead of beside it. */
.tr-figure{margin:0;grid-column:1;grid-row:1}
.tr-node{grid-row:1}
.tr-body{grid-column:3;grid-row:1}
.tr-row:nth-of-type(even) .tr-figure{grid-column:3}
.tr-row:nth-of-type(even) .tr-body{grid-column:1;text-align:right}
.tr-row:nth-of-type(even) .tr-result{
  border-left:0;border-right:2px solid var(--lf-accent,#B28479);
  padding-left:0;padding-right:14px;
}
.tr-row:nth-of-type(even) .tr-note,
.tr-row:nth-of-type(even) .tr-claim{margin-left:auto}

.tr-node{
  position:relative;
  grid-column:2;justify-self:center;
  width:11px;height:11px;border-radius:50%;
  background:var(--lf-ground,#171413);
  border:2px solid var(--lf-accent,#B28479);
  box-shadow:0 0 0 6px var(--lf-ground,#171413);
}
/* A tick out of each node toward the row it belongs to, so the spine reads
   as connected to the content rather than running past it. It points at the
   TEXT side, not the picture: the text is what the node is marking. */
/* SOLID FOR MOST OF ITS RUN, then a short fade.

   It used to fade across the whole 22px, which is the same 1px the spine
   is but reads as half of it -- a gradient that starts fading at pixel
   one never gets to be the weight it was declared. Solid to 64% and out
   over the rest keeps the soft ending and matches the vertical line. */
.tr-node::after{
  content:"";position:absolute;top:50%;
  width:22px;height:1px;
  background:linear-gradient(90deg,
    var(--lf-accent,#B28479) 0,
    var(--lf-accent,#B28479) 64%,
    rgba(178,132,121,0) 100%);
  transform:translateY(-.5px);
  left:100%;margin-left:5px;
}
.tr-row:nth-of-type(even) .tr-node::after{
  left:auto;right:100%;margin-left:0;margin-right:5px;
  background:linear-gradient(270deg,
    var(--lf-accent,#B28479) 0,
    var(--lf-accent,#B28479) 64%,
    rgba(178,132,121,0) 100%);
}
/* Same reason: dimmed only when there is a script to undim it. */
.rv .tr-node{
  opacity:.35;transform:scale(.7);
  transition:opacity .45s ease,transform .45s cubic-bezier(.16,1,.3,1),
             background-color .5s ease;
}
.rv .tr-row.is-in .tr-node{opacity:1;transform:scale(1)}

/* THE NODE FILLS WHEN YOU REACH IT.

   It was a clay ring on the ground colour whether you had got to it or
   not, so the spine's own progress was the only thing marking where you
   were. Filled, each node is a step taken -- and because the fill stays,
   the column reads as a path walked rather than a cursor. */
.tr-row.is-in .tr-node{background:var(--lf-accent,#B28479)}

/* And a slight breath on the ones that are filled. A ring outside the
   node, not the node itself: scaling the node would move the tick that
   hangs off it. Staggered, because four dots pulsing in unison is a
   loading spinner. */
.tr-node::before{
  content:"";position:absolute;inset:-2px;border-radius:50%;
  border:1px solid var(--lf-accent,#B28479);
  opacity:0;pointer-events:none;
}
.tr-row.is-in .tr-node::before{animation:tr-breathe 3.2s ease-out infinite}
.tr-row:nth-of-type(2) .tr-node::before{animation-delay:.8s}
.tr-row:nth-of-type(3) .tr-node::before{animation-delay:1.6s}
.tr-row:nth-of-type(4) .tr-node::before{animation-delay:2.4s}
@keyframes tr-breathe{
  0%{opacity:.4;transform:scale(1)}
  55%,100%{opacity:0;transform:scale(1.85)}
}
@media(prefers-reduced-motion:reduce){
  .tr-row.is-in .tr-node::before{animation:none}
}

/* ------------------------------ the pieces ------------------------------ */

.tr-figure{position:relative}
/* height:auto, no object-fit. A fixed height meant cover, and cover crops:
   the agenda is 2.66:1 in a 1.89:1 frame, so it was cutting about 29% of
   the width and taking the start of every label with it. Each file now
   shows exactly as captured, at its own ratio, so the three heights differ
   a little -- which is what actual screenshots do. */
.tr-shot{
  display:block;width:100%;height:auto;
  /* NO BORDER AND NO RADIUS.

     These PNGs are rendered windows that carry their own frame, so a CSS
     border drew a second line just outside the one in the picture -- the
     thin double edge. The 12px radius made it worse at the corners,
     where a rounded CSS border curves away from a square drawn one, the
     same fault as the modal's mock corners. The picture's own frame is
     the edge, and square matches the rest of the site. */
  border:0;
  border-radius:0;background:rgba(0,0,0,.3);
}
/* Taken out of the flow. Only one row has a caption, and letting it add to
   that figure's height made the row centre on a taller box than the others
   -- which is why the plan's copy sat lower than its picture. */
.tr-cap{
  position:absolute;top:100%;left:0;right:0;
  margin:10px 0 0;font-size:11.5px;color:rgba(246,241,234,.49);
}
.tr-row:nth-of-type(even) .tr-cap{text-align:right}

.tr-label{
  display:block;margin:0 0 12px;
  font-size:12px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  line-height:1.5;
}
.tr-label b{font-weight:700;color:var(--lf-accent,#B28479)}
.tr-label span{color:rgba(246,241,234,.5)}
.tr-label span::before{content:"\00b7";margin:0 .6em;color:rgba(246,241,234,.34)}
/* The disclosure gets its own line, smaller and in brackets, rather than
   running on after the company name -- where it broke mid-phrase and read
   as part of the name. It is an aside about who owns this example, which
   is exactly what a bracketed line under the name is for. It has to stay
   legible: naming Moto without saying it is ours would be the problem. */
.tr-label small{
  display:block;margin-top:5px;
  /* 12px, the small-text floor. It was 11. */
  font-size:12px;font-weight:400;letter-spacing:.04em;text-transform:none;
  color:rgba(246,241,234,.49);
}

/* Both were capped far inside the column they sit in. The claim now runs to
   the full width and the note nearly so. */
.tr-claim{
  margin:0 0 12px;max-width:none;
  font-family:'League Spartan',sans-serif;font-weight:700;
  font-size:clamp(22px,2.1vw,30px);line-height:1.08;letter-spacing:-.03em;
  text-transform:lowercase;
}
/* No cap. 60ch still held the paragraph ~140px short of its column, which
   is what kept reading as a narrow strip with space beside it. It fills the
   column now -- wide for body copy at about 79 characters, but the column
   is the measure here, not a typographic ideal. */
/* 74ch, about 590px. Walked out in stages -- uncapped, 52ch, 60ch, 68ch --
   and this is the last one that still does anything: it leaves the column
   alone up to about 1500px and only bites above that, where the column
   reaches 806px and 14.5px text stops being readable across it.

   On an even row the text is set right, so the cap has to take width off
   the LEFT or it would pull the copy away from the spine it belongs to. */
.tr-note{margin:0 0 10px;max-width:74ch;font-size:14.5px;line-height:1.55;color:rgba(246,241,234,.66)}
.tr-row:nth-of-type(even) .tr-note{margin-left:auto}

/* A before/now pair lived here for one commit and came back out. It said
   the same thing twice: the headline is already the result, so "now" was
   a restatement of the line directly above it. The single paragraph plus
   a result does the job without the echo. */
.tr-result{
  display:inline-block;margin:14px 0 0;padding-left:14px;
  border-left:2px solid var(--lf-accent,#B28479);
  font-size:15px;line-height:1.5;color:var(--n12-cream);text-align:left;
}

/* ------------------------------ the reveal ------------------------------ */

/* Scoped to .rv, which an inline script sets on <html> before the first
   paint. Unscoped, these rows started at opacity 0 and waited for a class
   that only script can add -- so with scripts off the entire section was
   blank: three screenshots and every word explaining them, gone. That did
   not matter while this was a concept page. It matters a great deal on a
   home page, where anything that does not run scripts, including most
   social scrapers, would have seen a hole where the proof is. */
.rv .tr-figure,.rv .tr-body{
  opacity:0;
  transition:opacity .6s cubic-bezier(.16,1,.3,1),transform .6s cubic-bezier(.16,1,.3,1);
}
.rv .tr-figure{transform:translateX(-26px)}
.rv .tr-body{transform:translateX(26px)}
.rv .tr-row:nth-of-type(even) .tr-figure{transform:translateX(26px)}
.rv .tr-row:nth-of-type(even) .tr-body{transform:translateX(-26px)}
.tr-row.is-in .tr-figure,
.tr-row.is-in .tr-body{opacity:1;transform:translateX(0)}

/* ---------------------------- responsive ---------------------------- */

@media(max-width:900px){
  .tr{padding:80px 0 74px}
  .tr-list{margin-top:48px}
  /* The spine moves to the left edge and every row reads the same way
     down, because alternating needs two columns to alternate between. */
  .tr-spine{left:6px}
  .tr-row{grid-template-columns:32px minmax(0,1fr);gap:0;padding:34px 0}
  .tr-figure,.tr-row:nth-of-type(even) .tr-figure{grid-column:2;grid-row:1}
  .tr-body,.tr-row:nth-of-type(even) .tr-body{grid-column:2;grid-row:2;text-align:left;margin-top:20px}
  .tr-node{grid-column:1;grid-row:1;justify-self:start;align-self:start;margin-top:10px}
  .tr-row:nth-of-type(even) .tr-result{border-left:2px solid var(--lf-accent,#B28479);border-right:0;padding-left:14px;padding-right:0}
  .tr-row:nth-of-type(even) .tr-cap{text-align:left}
  .tr-claim,.tr-note{max-width:none}
  .rv .tr-figure,.rv .tr-body,.rv .tr-row:nth-of-type(even) .tr-figure,.rv .tr-row:nth-of-type(even) .tr-body{transform:translateY(20px)}
  .rv .tr-row.is-in .tr-figure,.rv .tr-row.is-in .tr-body{transform:translateY(0)}
}

@media(prefers-reduced-motion:reduce){
  .rv .tr-figure,.rv .tr-body{opacity:1;transform:none;transition:none}
  .rv .tr-node{opacity:1;transform:none;transition:none}
  .tr-spine i{transform:scaleY(1)}
}


/* ================= EYEBROW TO HEADING =================
   5px under a section eyebrow, 12 under a hero one. The pair is
   addressed as a sibling so no heading that does NOT follow an
   eyebrow moves with it. */
.tr-eyebrow + h1,
.tr-eyebrow + h2,
.tr-eyebrow + h3{margin-top:5px}
