:root {
  --cream:#F7F4EE; --sand:#EDE9E1; --forest:#1E4035;
  --ink:#1A1916; --ink-mid:#5C5750; --ink-soft:#9C9690;
  --accent:#C47A3A; --accent-hov:#A1612C; --sand-text:#A0612B;
  --gold:#C8964A; --line:#DDD9D1;
  --serif:'Source Serif 4',Georgia,serif; --sans:'Inter',sans-serif;

  /* Height of the sticky nav's occluding box: the 72px inner row plus its 1px
     border-bottom. The same at every width — the mobile rules below change
     what sits inside the nav, never how tall it is. .site-nav__inner derives
     its height from this, and section anchors offset by it, so the two cannot
     drift apart. */
  --nav-height:73px;

  /* MOTION. Calm and deliberate: one gentle ease-out, three durations.
     Nothing linear, nothing that overshoots. */
  --ease:cubic-bezier(0.22,0.61,0.36,1);
  --dur-quick:200ms;
  --dur:360ms;
  --dur-slow:560ms;
  /* Drift. --ease starts at speed, which reads as a pop when several elements
     fire in sequence. This one eases in as well as out, so staggered elements
     blend into one another instead of stepping. */
  --ease-soft:cubic-bezier(0.37,0,0.28,1);
  /* Screenshots arrive slower and travel further than the copy around them, so
     they read as trailing it under their own weight. Shared by the §5 timeline
     exhibits and the §6 diagnostic shot — retune here and both follow. */
  --shot-in:2000ms;
}
*,*::before,*::after{box-sizing:border-box;}
/* <picture> is only a wrapper for the WebP source. display:contents keeps
   it out of the box tree so every existing selector and layout rule still
   sees the <img> exactly where it was before. */
picture{display:contents;}
body{margin:0;overflow-x:hidden;font-family:var(--sans);background:var(--cream);}
a{color:var(--accent);}a:hover{color:var(--accent-hov);}

/* BAND */
/* Vertical and horizontal band padding interpolate between the design's
   mobile (64/24) and desktop (96/80) values instead of jumping at 768px. */
.band{padding:clamp(64px,53.333px + 2.963vw,96px) clamp(24px,5.333px + 5.185vw,80px);position:relative;}
.band--cream{background:var(--cream);}
.band--sand{background:var(--sand);}
.band--forest{background:var(--forest);color:var(--cream);}
.band__inner{margin:0 auto;width:100%;}
.w-wide{max-width:1100px;}
.w-reading{max-width:760px;}
.w-narrow{max-width:600px;}

/* SECTION HEAD */
/* Eyebrows are always flush left, lined up with the copy underneath them.
   text-align pins the text; align-self keeps a short eyebrow from shrinking to
   its own width and centring when its parent is a centring flex container
   (the phone hero stack on the Brief Builder pages does exactly that). */
.eyebrow{display:block;text-align:left;align-self:flex-start;font-family:var(--sans);font-size:clamp(12px,11.667px + 0.093vw,13px);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--eyebrow-color,var(--sand-text));margin-bottom:24px;}
.title{font-family:var(--serif);font-weight:400;line-height:1.1;letter-spacing:-.01em;color:var(--ink);text-wrap:pretty;margin:0 0 24px;}
h1.title{font-size:clamp(42px,33.333px + 2.407vw,68px);}
h2.title{font-size:clamp(32px,28px + 1.111vw,44px);}
.title b{color:var(--accent);font-weight:400;}
.standfirst{font-family:var(--serif);font-size:clamp(17px,16px + 0.278vw,20px);line-height:1.5;color:var(--ink-mid);margin:0 0 40px;max-width:480px;}
.standfirst b{color:var(--accent-hov);font-style:italic;}

/* BUTTONS */
.btn{display:inline-flex;align-items:center;font-family:var(--sans);font-size:15px;font-weight:600;padding:14px 28px;min-height:44px;background:var(--accent);color:#fff;border-radius:6px;text-decoration:none;transition:background var(--dur) var(--ease),transform var(--dur) var(--ease),border-color var(--dur) var(--ease);}
.btn:hover,.btn:focus{background:var(--accent-hov);color:#fff;}
/* Subtle lift. Same colours as the approved design, just eased in. */
.btn:hover,.btn:focus-visible{transform:translateY(-1px);}
.btn:active{transform:translateY(0);}
.fineprint{font-family:var(--sans);font-size:clamp(12px,11.667px + 0.093vw,13px);color:var(--ink-soft);margin:16px 0 0;}

/* SPLIT */
.split{display:grid;grid-template-columns:55fr 45fr;gap:72px;align-items:center;}
.photo-frame{aspect-ratio:3/4;border:1px solid var(--line);border-radius:4px;overflow:hidden;background:var(--sand);}
.photo-frame img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block;}
.caption{font-family:var(--sans);font-size:clamp(11.5px,11.333px + 0.046vw,12px);color:var(--ink-mid);margin:8px 0 0;line-height:1.5;}

/* TIMELINE §5 */
.tl{position:relative;max-width:880px;margin:0 auto;padding:0 clamp(24px,18.667px + 1.481vw,40px) clamp(60px,53.333px + 1.852vw,80px);}
.tl::before{content:"";position:absolute;left:66px;top:12px;bottom:90px;width:2px;background:var(--line);}
.tl-step{position:relative;display:grid;grid-template-columns:54px 1fr;gap:30px;padding-bottom:52px;}
/* Scroll reveal. Only ever applied once JS has added .js to the timeline,
   so the no-JS and reduced-motion default is fully visible.

   The step used to arrive as one block. It now ripples internally, the same
   way the §4 steps do: the node leads and the copy follows 90ms behind it,
   over an entrance many times that gap, so the text is always in flight
   together and drifts rather than ticks.

   The screenshot is deliberately out of step with the copy. It starts well
   after the text has committed, travels further and takes half as long again
   to arrive, so it settles a full second after the words have. Reading order
   is text first; the image should feel like it is catching up to a step that
   is already made its point, not competing with it for the same beat.

   Unlike §4 this cannot run off one trigger — the timeline is far taller than
   the viewport, so each step keeps its own observer and ripples as it arrives.
   Delays come from --n, set by position, so the rule does not care that the
   last step has a sixth child the others lack. */
.tl.js{--tl-in:1300ms;--tl-lag:90ms;--tl-img-in:var(--shot-in);--tl-img-delay:700ms;}
.tl.js .tl-step > .tl-node,
.tl.js .tl-step > div:not(.tl-node) > *{opacity:0;}
@keyframes tl-node-in{
  0%{opacity:0;transform:translateY(16px) scale(0.94);}
  100%{opacity:1;transform:none;}
}
@keyframes tl-copy-in{
  0%{opacity:0;transform:translateY(14px);}
  100%{opacity:1;transform:none;}
}
/* Further travel than the copy, so the lag reads as weight rather than as a
   delay someone dialled in. */
@keyframes tl-img-in{
  0%{opacity:0;transform:translateY(24px);}
  100%{opacity:1;transform:none;}
}
.tl.js .tl-step.in > .tl-node{animation:tl-node-in var(--tl-in) var(--ease-soft) both;}
.tl.js .tl-step.in > div:not(.tl-node) > *{
  animation:tl-copy-in var(--tl-in) var(--ease-soft) both;
  animation-delay:calc(var(--n,1) * var(--tl-lag));
}
/* Matched by class, not by index: the exhibit is the fifth child in four steps
   and the fifth and sixth in the last one. */
.tl.js .tl-step.in > div:not(.tl-node) > .tl-exhibit,
.tl.js .tl-step.in > div:not(.tl-node) > .tl-learn-mob{
  animation-name:tl-img-in;
  animation-duration:var(--tl-img-in);
  animation-delay:var(--tl-img-delay);
}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(1){--n:1;}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(2){--n:2;}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(3){--n:3;}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(4){--n:4;}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(5){--n:5;}
.tl.js .tl-step > div:not(.tl-node) > *:nth-child(6){--n:6;}
.tl-node{width:54px;height:54px;border-radius:50%;background:var(--cream);border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;transition:border-color var(--tl-in,var(--dur-slow)) var(--ease-soft);z-index:1;flex-shrink:0;}
.tl-node svg{width:26px;height:26px;stroke:var(--sand-text);}
/* The rim warms to terracotta over the same span the node takes to arrive, so
   the colour blooms with the step rather than snapping after it. */
.tl-step.in .tl-node{border-color:var(--accent);}
.tl-eyb{font-size:12px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--sand-text);margin:6px 0 5px;}
.tl-ti{font-family:var(--serif);font-size:26px;line-height:1.08;color:var(--ink);margin:0 0 8px;}
.tl-desc{font-size:16px;line-height:1.5;color:var(--ink-mid);margin:0 0 6px;max-width:560px;}
.tl-tag{font-size:13px;color:var(--ink-soft);margin:0;}

/* TL EXHIBIT — tap/click to zoom */
/* height:auto is load-bearing. The <img> tags carry width/height attributes
   so the browser can reserve space before the image lands; without an explicit
   CSS height those attributes act as presentational hints and pin the element
   to its full intrinsic pixel height. */
.tl-exhibit{margin:24px 0 0;overflow:visible;position:relative;}
.tl-exhibit__trigger{display:inline-block;padding:0;border:0;background:none;cursor:zoom-in;border-radius:12px;}
.tl-exhibit__trigger:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:12px;}
.tl-exhibit__img{display:block;max-width:600px;width:100%;height:auto;border-radius:12px;transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease);}
/* Grow on hover and on keyboard focus, so pointer and keyboard match. */
.tl-exhibit__trigger:hover .tl-exhibit__img,
.tl-exhibit__trigger:focus-visible .tl-exhibit__img{transform:scale(1.03);box-shadow:0 8px 28px rgba(0,0,0,.12);}
.tl-exhibit__img--framed{border:1px solid var(--line);}
.tl-learn-mob{display:none;}
.tl-exhibit__duo{display:flex;gap:12px;align-items:flex-start;overflow:visible;}
.tl-exhibit__duo .tl-exhibit__trigger{width:calc(50% - 6px);flex-shrink:0;}
.tl-exhibit__duo .tl-exhibit__trigger .tl-exhibit__img{width:100%;max-width:none;}
/* LIGHTBOX */
.lbx{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(26,25,22,.88);opacity:0;transition:opacity var(--dur-slow) var(--ease);}
.lbx.is-open{opacity:1;}
.lbx[hidden]{display:none;}
.lbx__img{max-width:min(1100px,92vw);max-height:90vh;width:auto;height:auto;border-radius:12px;box-shadow:0 20px 60px rgba(0,0,0,.45);transform:scale(.97);transition:transform var(--dur-slow) var(--ease);will-change:transform;}
.lbx.is-open .lbx__img{transform:none;}
.lbx__close{position:absolute;top:16px;right:20px;width:44px;height:44px;border:0;border-radius:50%;background:var(--cream);color:var(--forest);font-size:26px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.lbx__close:focus-visible{outline:2px solid var(--cream);outline-offset:2px;}
/* SITE NAV */
/* The nav shares the band's box model exactly: gutter on the outer element,
   then a 1100px cap on the inner, so the logo lines up with the hero eyebrow
   and the actions line up with the hero image's right edge at every width. */
.site-nav{background:var(--cream);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:100;padding-left:clamp(24px,5.333px + 5.185vw,80px);padding-right:clamp(24px,5.333px + 5.185vw,80px);}
.site-nav__inner{max-width:1100px;margin:0 auto;padding:0;height:calc(var(--nav-height) - 1px);display:flex;align-items:center;justify-content:space-between;gap:16px;}
.site-nav__logo img{height:34px;display:block;}
/* flex:none, not a shrink factor. The CTA is the one thing in this row that
   must never be squeezed: let the actions box shrink and the button inside it
   does not, so below ~340px it spills into the nav's right padding. The links
   absorb the shrink instead - at phone widths they are not in the bar at all. */
.site-nav__actions{display:flex;align-items:center;gap:12px;flex:none;}
.site-nav__logo{flex-shrink:0;}

/* ---- THE PRODUCT LINKS -------------------------------------------------
   One row of links to the three things the site sells, identical on every
   page: The System (the homepage), Brief Builder, Review Checklist. They sit
   between the logo and the page's own primary CTA, and they are the SAME
   markup everywhere - there is no build step, so the only thing keeping them
   in step is that every copy is identical. If you edit one, edit them all.

   aria-current="page" marks the page you are on. It is an attribute rather
   than a class so the state is announced as well as drawn.

   THERE IS ONE SET OF LINKS, NOT TWO. A desktop row and a separate phone
   drawer would be two lists to keep in sync, which on a hand-maintained site
   is two lists that drift. This is one <nav> that changes shape: a row in the
   bar from 880px, and a panel under the bar below it.
   ------------------------------------------------------------------------ */
.site-nav__links{display:flex;align-items:center;gap:clamp(14px,1.6vw,26px);
  min-width:0;}
.site-nav__links a{font-family:var(--sans);font-size:14px;font-weight:500;
  line-height:1.2;color:var(--ink-mid);text-decoration:none;white-space:nowrap;
  transition:color var(--dur-quick) var(--ease);}
.site-nav__links a:hover,.site-nav__links a:focus{color:var(--forest);}
.site-nav__links a[aria-current="page"]{color:var(--forest);font-weight:600;}

/* The burger. Hidden unless JavaScript is running AND the row has run out of
   room - with neither, the links are simply visible and there is nothing to
   disclose. 44px square, which is the site's minimum target everywhere else. */
.site-nav__burger{display:none;width:44px;height:44px;flex:none;padding:0;
  border:0;background:none;cursor:pointer;align-items:center;
  justify-content:center;border-radius:6px;}
.site-nav__burger span{display:block;position:relative;width:20px;height:2px;
  border-radius:2px;background:var(--forest);
  transition:transform var(--dur-quick) var(--ease),
    opacity var(--dur-quick) var(--ease);}
.site-nav__burger span::before,.site-nav__burger span::after{content:"";
  position:absolute;left:0;width:20px;height:2px;border-radius:2px;
  background:var(--forest);
  transition:transform var(--dur-quick) var(--ease);}
.site-nav__burger span::before{top:-6px;}
.site-nav__burger span::after{top:6px;}
/* Open: the middle bar goes, the outer two cross. */
.site-nav__burger[aria-expanded="true"] span{background:transparent;}
.site-nav__burger[aria-expanded="true"] span::before{transform:translateY(6px) rotate(45deg);}
.site-nav__burger[aria-expanded="true"] span::after{transform:translateY(-6px) rotate(-45deg);}

@media(max-width:879px){
  /* WITHOUT JAVASCRIPT the links stay in the document, in a row of their own
     under the bar. The header grows by that row and everything still works;
     --nav-height keeps describing the BAR, so anchor offsets are a row short
     on a no-JS phone, which is the whole cost of not shipping a second copy of
     the list for that case.

     WITH JAVASCRIPT the same element becomes an absolutely positioned panel
     that the burger discloses, so the bar is back to its 73px and the sticky
     offsets are exact. .js is set by the pre-paint script in every page's
     <head>, so the swap is never seen. */
  .site-nav{display:flex;flex-direction:column;}
  .site-nav__inner{width:100%;flex:none;}
  .site-nav__links{order:3;width:100%;justify-content:flex-start;
    flex-wrap:wrap;gap:10px 20px;padding:0 0 12px;}

  .js .site-nav{display:block;}
  /* The burger is the rightmost thing in the bar, after the CTA: logo left,
     [CTA][burger] right. order moves it visually without moving the markup,
     so in the DOM it still comes straight before the links it discloses;
     margin-left:auto on the actions pushes the right-hand pair together. */
  .js .site-nav__burger{display:flex;order:4;}
  .js .site-nav__actions{margin-left:auto;}
  .js .site-nav__links{position:absolute;top:100%;left:0;right:0;z-index:1;
    flex-direction:column;align-items:stretch;gap:0;padding:4px 0;
    background:var(--cream);border-bottom:1px solid var(--line);
    box-shadow:0 10px 24px rgba(26,25,22,.07);
    /* Collapsed. visibility, not display, so the panel can animate and so the
       links stay in the accessibility tree's shape rather than appearing and
       disappearing from the DOM. aria-hidden on the element is what actually
       takes them out of it while shut; js/site.js owns that. */
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity var(--dur-quick) var(--ease),
      transform var(--dur-quick) var(--ease),
      visibility 0s linear var(--dur-quick);}
  .js .site-nav.is-open .site-nav__links{opacity:1;visibility:visible;
    transform:none;transition:opacity var(--dur-quick) var(--ease),
      transform var(--dur-quick) var(--ease),visibility 0s;}
  .js .site-nav__links a{padding:14px clamp(24px,5.333px + 5.185vw,80px);
    font-size:16px;min-height:48px;display:flex;align-items:center;}
  .js .site-nav__links a[aria-current="page"]{
    box-shadow:inset 3px 0 0 var(--sand-text);}
}

/* ANCHOR LANDING UNDER THE STICKY NAV (BUG-052).
   The nav is sticky, so it covers the top --nav-height of whatever an in-page
   link scrolls to: the "$129" buttons pointing at #s11 dropped the pricing
   band's top edge and, at phone widths where the band padding is only ~65px,
   its "expected it to cost $250 to $500" lead-in underneath the nav.

   scroll-margin-top offsets the browser's own scroll target, so it fixes the
   click and a direct /#s11 hash load identically with no JS. Applied to every
   id'd band, not just #s11, because the clones' "#s5" link lands the same way.
   16px of air so the band edge is visibly clear of the nav rather than flush.

   The id'd FAQ item is in here for a second reason: chatgpt-clone.js scrolls it
   itself, but on a direct /#faq-chatgpt load the browser jumps there first and
   the script only corrects it a tick later. Giving the item the same margin
   makes that first jump already right, so there is no race to lose. */
.band[id],.faq-item[id]{scroll-margin-top:calc(var(--nav-height) + 16px);}
.btn--primary{background:var(--forest)!important;color:var(--cream)!important;}
.btn--primary:hover,.btn--primary:focus{background:#163329!important;color:var(--cream)!important;}
.btn--ghost{background:transparent!important;color:var(--forest)!important;border:1px solid var(--line)!important;}
.btn--ghost:hover,.btn--ghost:focus{border-color:var(--forest)!important;color:var(--forest)!important;background:transparent!important;}
/* THE TOOLS GRID (homepage §10b).
   Three cards, each a whole link: the two standalone tools and the system that
   contains them. One column on a phone, three from 820px - never two, because
   a 2+1 wrap leaves the system card orphaned on its own row looking like an
   afterthought rather than the thing §11 is about to detail.

   The CARD IS THE LINK, not a button inside it: the whole target is tappable,
   which at phone widths is the difference between a 48px target and a 300px
   one. The arrow row reads as the affordance; it is not a nested control.

   Built from tokens the page already uses - cream card, --line hairline, 4px
   radius, serif price - so it reads as the same site as the §11 pricing card
   it sits above. */
.tools-grid{display:grid;grid-template-columns:1fr;gap:16px;align-items:stretch;}
@media(min-width:820px){
  .tools-grid{grid-template-columns:repeat(3,1fr);}
}
.tool-card{display:flex;flex-direction:column;background:var(--color-bg-card);
  border:1px solid var(--line);border-radius:4px;padding:26px 24px;
  text-decoration:none;color:inherit;
  transition:border-color var(--dur) var(--ease),
    transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease);}
.tool-card:hover,.tool-card:focus-visible{border-color:var(--forest);
  transform:translateY(-2px);box-shadow:0 8px 22px rgba(26,25,22,.07);
  color:inherit;}
.tool-card__step{font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft);
  margin-bottom:14px;}
.tool-card__name{font-family:var(--serif);font-size:26px;font-weight:400;
  line-height:1.15;color:var(--ink);margin-bottom:10px;}
.tool-card__desc{font-family:var(--sans);font-size:15px;line-height:1.6;
  color:var(--ink-mid);margin-bottom:24px;}
/* margin-top:auto pins the price row to the card's bottom, so the three line
   up across the row however long the descriptions run. */
.tool-card__foot{margin-top:auto;display:flex;align-items:baseline;
  justify-content:space-between;gap:12px;padding-top:18px;
  border-top:1px solid var(--line);}
.tool-card__price{font-family:var(--serif);font-size:32px;font-weight:400;
  line-height:1;color:var(--ink);}
.tool-card__go{display:inline-flex;align-items:center;gap:6px;
  font-family:var(--sans);font-size:14px;font-weight:600;color:var(--sand-text);
  white-space:nowrap;}
.tool-card__go svg{width:16px;height:16px;flex:none;
  transition:transform var(--dur) var(--ease);}
.tool-card:hover .tool-card__go svg,
.tool-card:focus-visible .tool-card__go svg{transform:translateX(3px);}
/* The system card is the one that contains the other two, so it carries the
   forest surface the §11 card and the final CTA already use for "the whole
   thing". Same box, inverted. */
.tool-card--all{background:var(--forest);border-color:var(--forest);}
.tool-card--all .tool-card__step{color:var(--color-gold);}
.tool-card--all .tool-card__name,
.tool-card--all .tool-card__price{color:var(--cream);}
.tool-card--all .tool-card__desc{color:#CAD7CF;}
.tool-card--all .tool-card__foot{border-top-color:rgba(247,244,238,.22);}
.tool-card--all .tool-card__go{color:var(--color-gold);}
.tool-card--all:hover,.tool-card--all:focus-visible{border-color:var(--color-gold);}

@media(prefers-reduced-motion:reduce){
  .tool-card:hover,.tool-card:focus-visible{transform:none;}
  .tool-card:hover .tool-card__go svg,
  .tool-card:focus-visible .tool-card__go svg{transform:none;}
}

/* SITE FOOTER */
.site-footer{background:#163329;}
.site-footer__in{max-width:1200px;margin:0 auto;padding:clamp(32px,21.333px + 2.963vw,64px) clamp(24px,13.333px + 2.963vw,56px) 0;}
.site-footer__grid{display:flex;justify-content:space-between;gap:48px;flex-wrap:wrap;}
/* EXPERIMENT (revert this commit to restore the wordmark).
   The footer mark is the monogram glyph, sized by HEIGHT rather than width.
   The wordmark it replaces was width-driven at 190px, which on its 3.265
   ratio rendered 58px tall; pinning that same 58px keeps the footer's
   vertical rhythm and the 18px gap below it identical. The monogram is a
   tall glyph, so it is much narrower here - that is expected. */
.ft-wm{height:58px;width:auto;display:block;margin-bottom:18px;}
.ft-tag{margin:0 0 22px;font-size:15px;color:#B7C4BD;font-family:var(--sans);}
.ft-soc{display:flex;gap:12px;}
.ft-soc a{color:#C7D3CD;display:inline-flex;width:40px;height:40px;align-items:center;justify-content:center;border:1px solid #2C4E43;border-radius:8px;text-decoration:none;transition:color 150ms,border-color 150ms;}
.ft-soc a:hover{color:#C8964A;border-color:#C8964A;}
.ft-cols{flex:1;min-height:1px;}
.ft-sign{max-width:300px;}
.ft-sign-head{font-family:var(--sans);font-size:15px;font-weight:600;color:#F7F4EE;margin:4px 0 8px;}
.ft-sign p{font-size:13px;color:#9FB1A9;margin:0 0 14px;line-height:1.5;font-family:var(--sans);}
.ft-form{display:flex;gap:8px;}
.ft-form input{flex:1;min-width:0;height:44px;border:1px solid #2C4E43;border-radius:6px;background:#F7F4EE;color:#1A1916;padding:0 12px;font-size:14px;font-family:var(--sans);}
.ft-form input:focus-visible{outline:2px solid #F7F4EE;outline-offset:2px;}
.ft-form button{height:44px;padding:0 18px;border:0;border-radius:6px;background:#C8964A;color:#3A2A12;font-weight:600;font-size:14px;cursor:pointer;font-family:var(--sans);transition:background 150ms;}
.ft-form button:hover{background:#D5A659;}
.ft-form button:focus-visible{outline:2px solid #F7F4EE;outline-offset:2px;}
.ft-rule{height:1px;background:#C8964A;opacity:.7;margin:56px 0 0;}
.ft-bottom{text-align:center;padding:14px 0 20px;}
.ft-legal{display:flex;gap:26px;justify-content:center;align-items:center;margin-bottom:8px;}
.ft-legal a{font-size:13px;color:#C7D3CD;text-decoration:none;transition:color 150ms;}
.ft-legal a:hover{color:#F7F4EE;}
.ft-co{margin:0;font-size:12.5px;color:#7E938A;font-family:var(--sans);}
.ft-addr{margin:4px 0 0;font-size:12.5px;color:#7E938A;font-family:var(--sans);}
/* FOCUS RINGS */
a:focus-visible,button:focus-visible{outline:2px solid var(--forest);outline-offset:2px;border-radius:inherit;}

/* HERO ENTRANCE. Runs once on load. --hero-step is the gap between elements;
   raise it for a slower sequence, lower it to get the CTA on screen sooner. */
:root{--hero-step:240ms;}
.anim #s1 .eyebrow,
.anim #s1 .title,
.anim #s1 .standfirst,
.anim #s1 .btn,
.anim #s1 .fineprint,
.anim #s1 .split > div + div{
  opacity:0;transform:translateY(14px);
  transition:opacity var(--dur-slow) var(--ease),transform var(--dur-slow) var(--ease);
}
.anim.hero-in #s1 .eyebrow,
.anim.hero-in #s1 .title,
.anim.hero-in #s1 .standfirst,
.anim.hero-in #s1 .btn,
.anim.hero-in #s1 .fineprint,
.anim.hero-in #s1 .split > div + div{opacity:1;transform:none;}
.anim #s1 .eyebrow{transition-delay:0ms;}
.anim #s1 .title{transition-delay:var(--hero-step);}
.anim #s1 .standfirst{transition-delay:calc(var(--hero-step) * 2);}
.anim #s1 .btn{transition-delay:calc(var(--hero-step) * 3);}
.anim #s1 .fineprint{transition-delay:calc(var(--hero-step) * 3.5);}
/* The image column settles alongside the copy rather than after it. */
.anim #s1 .split > div + div{transition-delay:calc(var(--hero-step) * 1.5);}

/* BAND REVEAL. Same calm fade-rise as the section 5 steps, one per band.
   .band-reveal is added by JS right before the observer attaches, so a browser
   that never runs the script keeps every band visible. */
.band-reveal{opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-slow) var(--ease),transform var(--dur-slow) var(--ease);}
.band-reveal.in{opacity:1;transform:none;}

/* LOOP DRAW. Each SVG child fades in on a delay derived from its position along
   the loop, so the diagram builds in reading order instead of all at once.
   Delays are written inline by JS once the diagram is actually on screen. */
.loop-draw > *{opacity:0;transition:opacity var(--dur-slow) var(--ease);}
.loop-draw.in > *{opacity:1;}

/* §7 STEP NUMBERS */
.step-num{font-family:var(--serif);font-size:clamp(36px,30.667px + 1.481vw,52px);font-weight:400;line-height:1;display:block;padding-right:12px;color:var(--accent);background:var(--cream);}

/* §2 BROKEN LOOP */
.bl-desk-wrap{display:block;margin:64px 0 0;}
.bl-mob-wrap{display:none;max-width:280px;margin:48px auto 40px;}

/* FLOW DIAGRAM SEQUENCE — §2 the broken loop, §8 the Fern & Field loop.
   One component, two usages. The nodes ripple in along the diagram, then each
   arrow draws into the next node and that node pulses as the arrow lands, and
   a return arrow closes the loop. Plays once, on first sight.

   §8 adds two parts §2 has no use for: a .flow-trail, the dotted re-score line,
   which fades in after the loop has closed rather than drawing like the arrows,
   and a .flow-final that arrives after everything else has settled.

   Everything below hangs off .flow-seq, which JS adds only when motion is allowed
   and the observer is about to attach. Without JS, or under reduced motion, the
   diagram is simply already there — nothing is hidden in the first place.

   The two durations live here rather than in :root because they are longer than
   anything else on the site — this sequence drifts where the rest of the page
   settles. The JS constants mirror them; change both together. */
.flow-seq{--flow-entrance:1000ms;--flow-draw:820ms;}

.flow-seq .flow-node{
  opacity:0;transform:translateY(11px);
  transform-box:fill-box;transform-origin:50% 50%;
  transition:opacity var(--flow-entrance) var(--ease-soft),transform var(--flow-entrance) var(--ease-soft);
}
.flow-seq .flow-node.is-in{opacity:1;transform:none;}

/* Pulse is scale only, peaking dead centre on a sine-like curve so it swells and
   recedes at the same rate — a breath, not a beat. The gold "Nothing learned"
   node goes further and picks up a soft glow; it is the point of the section. */
@keyframes flow-pulse{
  0%{transform:scale(1);} 50%{transform:scale(1.05);} 100%{transform:scale(1);}
}
@keyframes flow-pulse-accent{
  0%{transform:scale(1);filter:drop-shadow(0 0 0 rgba(200,150,74,0));}
  50%{transform:scale(1.09);filter:drop-shadow(0 0 8px rgba(200,150,74,0.5));}
  100%{transform:scale(1);filter:drop-shadow(0 0 0 rgba(200,150,74,0));}
}
.flow-seq .flow-node.is-pulse{animation:flow-pulse 1000ms var(--ease-soft) both;}
.flow-seq .flow-node--accent.is-pulse{animation:flow-pulse-accent 1180ms var(--ease-soft) both;}

/* Arrows draw source to target. --flow-len is the measured path length, written
   inline by JS once the SVG is on screen and actually has a layout box. */
/* The fallback keeps the arrows hidden in the frame between the class landing
   and JS writing the measured length — without it they would flash on. */
.flow-seq .flow-arrow__line{stroke-dasharray:var(--flow-len,9999);stroke-dashoffset:var(--flow-len,9999);}
.flow-seq .flow-arrow__head{opacity:0;}
/* Eased in as well as out: the line creeps away from its node and glides to a
   stop at the next one, rather than shooting off at full speed. */
.flow-seq .flow-arrow.is-drawn .flow-arrow__line{
  stroke-dashoffset:0;transition:stroke-dashoffset var(--flow-draw) var(--ease-soft);
}
/* The head resolves as the line arrives, not before. */
.flow-seq .flow-arrow.is-drawn .flow-arrow__head{
  opacity:1;transition:opacity var(--dur) var(--ease-soft) calc(var(--flow-draw) * 0.62);
}
/* The return arrow travels roughly eight times the distance of a single hop and
   is the beat the section rests on — the loop closing on itself. It takes its
   time, slower per pixel than the hops rather than merely longer. */
.flow-seq .flow-arrow--return.is-drawn .flow-arrow__line{
  transition-duration:calc(var(--flow-draw) * 2.6);
}
.flow-seq .flow-arrow--return.is-drawn .flow-arrow__head{
  transition-delay:calc(var(--flow-draw) * 2.2);
}

/* THE RE-SCORE TRAIL (§8 only).
   This one fades; it does not draw. Two reasons, and the first is structural:
   the draw effect works by setting stroke-dasharray to the path length, which
   is the same property that makes this line dotted — animating the draw would
   overwrite "4 3" and silently render it solid.

   The second is emphasis. A line that draws pulls the eye and claims the beat.
   The re-score cycle is an aside to the loop, not a step in it, so it settles
   in quietly after the terracotta return arrow has closed the loop. Its own
   parts are namespaced so the .flow-arrow draw rules cannot reach them. */
.flow-seq .flow-trail,
.flow-seq .flow-trail__label{opacity:0;}
.flow-seq .flow-trail.is-in{
  opacity:1;transition:opacity var(--flow-entrance) var(--ease-soft);
}
.flow-seq .flow-trail__label.is-in{
  opacity:1;transition:opacity var(--dur-slow) var(--ease-soft);
}

/* The closing line, after everything else has settled. */
.flow-seq .flow-final{opacity:0;transform:translateY(8px);}
.flow-seq .flow-final.is-in{
  opacity:1;transform:none;
  transition:opacity var(--flow-entrance) var(--ease-soft),transform var(--flow-entrance) var(--ease-soft);
}

/* §3 WHO IT'S FOR — TRIANGLE.
   The three role panels arrive one at a time, then the centre "You" fills in
   underneath them: the roles converge on the reader. Plays once, on first
   sight, and stops there.

   Same shape as the §2 sequence — hidden only under .wf-seq, which JS adds when
   motion is allowed, so no-JS and reduced motion both get the finished diagram.

   Entrance and settle are one keyframe rather than a transition plus a separate
   pulse: a single animation owns transform throughout, so the rise flows into
   the swell instead of the two fighting over the same property. */
.wf-seq{--wf-entrance:1900ms;--wf-center:3500ms;}
.wf-seq .wf-panel,.wf-seq .wf-center{
  opacity:0;transform-box:fill-box;transform-origin:50% 50%;
}
/* Rise and fade in, swell to a gentle peak, settle. Never dips back below its
   resting size, so it reads as a breath rather than a spring.

   Two things about the peak keyframe. Its scale is small because the gutter
   between panels is only ~16 units: the top panel is 330 tall, so even 1.04
   grew it 13 and the panels visibly closed on each other at the top of the
   swell. And it carries its own easing, because a timing function applies to
   every keyframe segment — with an ease-in curve the settle hesitated at the
   peak before releasing, which read as a hitch at the end. Ease-out leaves the
   peak immediately and decelerates into rest. */
@keyframes wf-panel-in{
  0%{opacity:0;transform:translateY(13px) scale(0.985);}
  45%{opacity:1;}
  58%{transform:translateY(0) scale(1.02);animation-timing-function:var(--ease);}
  100%{opacity:1;transform:none;}
}
/* The centre goes further — it is the point the three roles are converging on.
   No rise: it grows in place, out of the middle of the triangle. Same ceiling
   applies: at 1.08 it grew 12 into a 16 gap and all but touched its neighbours,
   and it paints over them, so the collision showed. */
@keyframes wf-center-in{
  0%{opacity:0;transform:scale(0.94);}
  45%{opacity:1;}
  58%{transform:scale(1.05);animation-timing-function:var(--ease);}
  100%{opacity:1;transform:scale(1);}
}
/* The terracotta saturates a little behind the shape, so the panel reads as
   filling in rather than simply appearing. */
@keyframes wf-fill-in{0%{fill-opacity:0;} 100%{fill-opacity:1;}}
.wf-seq .wf-panel.is-in{animation:wf-panel-in var(--wf-entrance) var(--ease-soft) both;}
.wf-seq .wf-center.is-in{animation:wf-center-in var(--wf-center) var(--ease-soft) both;}
.wf-seq .wf-center.is-in .wf-center__fill{
  animation:wf-fill-in calc(var(--wf-center) * 0.75) var(--ease-soft) both;
}

/* NUMBERED ROW BUILD — §4 the system way, §7 getting started.
   One component, two usages. Rows arrive in order, each number leading its own
   copy in by a beat. The point is that it reads as one continuous drift rather
   than separate lines: the entrance is far longer than the gap between rows, so
   several elements are always in flight at once and the wave never lands on a
   single row. Widening --row-step or shortening --row-in is what breaks that.

   Delays come from --i, written inline on each row, so the whole sequence is
   CSS and every element shares one clock — setTimeout per element would let
   them drift apart under load. Inline rather than nth-of-type because §7's
   rows sit alongside an absolutely positioned rule element; counting siblings
   would silently offset the whole sequence by one.

   Hidden only under .row-seq, added by JS when motion is allowed, so no-JS and
   reduced motion both get the finished list. */
.row-seq{--row-step:340ms;--row-in:1600ms;--row-lag:240ms;}
.row-seq .sw-num,.row-seq .sw-copy,
.row-seq .step-num,.row-seq .gs-copy{opacity:0;}

/* The number drifts up and forward a touch — it leads, so it gets the small
   scale. The copy only rises and fades: scaling live text softens the glyphs
   for the whole of a 1.6s entrance, which is exactly where it would show. */
@keyframes row-num-in{
  0%{opacity:0;transform:translateY(12px) scale(0.97);}
  100%{opacity:1;transform:none;}
}
@keyframes row-copy-in{
  0%{opacity:0;transform:translateY(10px);}
  100%{opacity:1;transform:none;}
}
.row-seq.is-in .sw-num,
.row-seq.is-in .step-num{
  animation:row-num-in var(--row-in) var(--ease-soft) both;
  animation-delay:calc(var(--i) * var(--row-step));
}
.row-seq.is-in .sw-copy,
.row-seq.is-in .gs-copy{
  animation:row-copy-in var(--row-in) var(--ease-soft) both;
  animation-delay:calc(var(--i) * var(--row-step) + var(--row-lag));
}

/* STANDALONE SCREENSHOT ARRIVAL.
   Deliberately reuses the §5 exhibit keyframe, duration and curve rather than
   restating them, so every screenshot on the page arrives the same way: the
   same 24px of travel over the same 2000ms. If the timeline exhibits are
   retuned, this follows them.

   The caption trails into that arrival and lands with it — a caption sitting
   under an image that has not appeared yet reads as orphaned. */
.shot-lag.shot-seq > picture > img,
.shot-lag.shot-seq > .caption{opacity:0;}
.shot-lag.shot-seq.is-in > picture > img{
  animation:tl-img-in var(--shot-in) var(--ease-soft) both;
}
.shot-lag.shot-seq.is-in > .caption{
  animation:tl-copy-in 1300ms var(--ease-soft) 700ms both;
}

/* §8 LOOP DIAGRAM */
.loop-h{display:block;}
.loop-h svg{display:block;width:100%;height:auto;}
.loop-v{display:none;text-align:center;}
.loop-v svg{display:block;width:100%;max-width:244px;height:auto;margin:0 auto;}
.loop-caption{text-align:center;font-size:12.5px;font-weight:600;color:#6B655C;margin-top:6px;}

/* §4 GRID */
.s4-grid{display:grid;grid-template-columns:.82fr 1.18fr;gap:26px;align-items:start;}

/* §9 FOUNDER */
.founder-grid{display:grid;grid-template-columns:3fr 2fr;gap:80px;align-items:start;}

/* §10 PROOF CARDS */
.proof-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:56px;align-items:stretch;}
.proof-card{background:var(--cream);border-radius:4px;padding:40px 36px 36px;display:flex;flex-direction:column;min-height:600px;}
.proof-card__qm{font-family:var(--serif);font-size:128px;color:var(--sand-text);line-height:.72;margin:0 0 24px -6px;user-select:none;}
.proof-card__body{font-family:var(--serif);font-size:24px;font-weight:400;line-height:1.45;color:var(--ink);margin:0;}
.proof-card__spacer{flex:1;min-height:64px;}
.proof-card__attr{margin-top:auto;padding-top:20px;border-top:1px solid var(--line);}
.proof-card__tool{font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);margin:0 0 6px;}
.proof-card__name{font-family:var(--sans);font-size:13px;color:var(--ink-mid);margin:0;line-height:1.45;}

/* §12 FAQ */
.faq-list{border-top:1px solid var(--line);}
.faq-item{border-bottom:1px solid var(--line);}
.faq-btn{display:flex;align-items:center;justify-content:space-between;width:100%;padding:18px 0;background:none;border:none;cursor:pointer;text-align:left;min-height:44px;font-family:var(--sans);font-size:17px;font-weight:600;color:var(--ink);line-height:1.3;}
/* Answers are open by default so they are readable with JavaScript off.
   The .js class on <html> is what collapses them, which is the only state
   a scripted browser ever sees. Height is animated from a measured value in
   js/site.js. padding-bottom animates alongside it: under box-sizing:border-box
   a box cannot shrink below its own padding, so height:0 alone would leave an
   18px stub behind every closed answer. */
.faq-answer{display:block;padding:0 0 18px;font-family:var(--sans);font-size:16px;color:var(--ink-mid);line-height:1.65;}
.js .faq-answer{height:0;padding-bottom:0;overflow:hidden;opacity:0;
  transition:height var(--dur) var(--ease),padding-bottom var(--dur) var(--ease),opacity var(--dur) var(--ease);}
.js .faq-answer.is-open{padding-bottom:18px;opacity:1;}
[data-faq-chevron]{transition:transform var(--dur) var(--ease);}

#sticky-cta{transform:translateY(100%);transition:transform var(--dur) var(--ease);}

@media(max-width:768px){
  .split,.founder-grid{grid-template-columns:1fr;gap:32px;}
  .bl-desk-wrap{display:none;}.bl-mob-wrap{display:block;}
  .loop-h{display:none;}.loop-v{display:block;}
  .tl::before{left:38px;}
  .tl-step{grid-template-columns:38px 1fr;gap:18px;}
  .tl-node{width:38px;height:38px;}
  .tl-node svg{width:18px;height:18px;}
  .tl-exhibit__img{max-width:100%!important;}
  .tl-exhibit__duo{flex-direction:column;gap:12px;}
  .tl-exhibit__duo .tl-exhibit__trigger{width:100%!important;}
  .tl-learn-desk{display:none!important;}
  .tl-learn-mob{display:flex;flex-direction:column;gap:18px;margin:24px 0 0;}
  .site-nav__actions .btn--ghost .nav-ghost-long{display:none;}
  .site-nav__actions .btn--ghost .nav-ghost-short{display:inline;}
  .site-footer__grid{flex-direction:column;}
  .ft-sign{max-width:100%;}
  .ft-cols{display:none;}
  .s4-grid{grid-template-columns:1fr!important;}
  .proof-cards{grid-template-columns:1fr!important;}
  .s5-head{padding:0 24px 32px!important;}
  .s9-photo-col{display:flex!important;flex-direction:column!important;align-items:flex-start!important;}
  .s9-photo-wrap{width:80px!important;aspect-ratio:4/5!important;margin-top:12px!important;}
}
@media(min-width:769px){#sticky-cta{display:none!important;}}
@media(min-width:769px){
  .site-nav__actions .btn--ghost .nav-ghost-short{display:none;}
  .site-nav__actions .btn--ghost .nav-ghost-long{display:inline;}
}
@media(prefers-reduced-motion:reduce){
  /* Everything visible, nothing moves. The accordion and lightbox still
     work, they just change state instantly. */
  .tl.js .tl-step{opacity:1!important;transform:none!important;transition:none!important;}
  .loop-draw > *{opacity:1!important;transition:none!important;transition-delay:0ms!important;}
  .band-reveal{opacity:1!important;transform:none!important;transition:none!important;}
  .anim #s1 .eyebrow,.anim #s1 .title,.anim #s1 .standfirst,
  .anim #s1 .btn,.anim #s1 .fineprint,.anim #s1 .split > div + div{
    opacity:1!important;transform:none!important;transition:none!important;transition-delay:0ms!important;}
  .tl-exhibit__img{transition:none!important;}
  .tl-exhibit__trigger:hover .tl-exhibit__img,
  .tl-exhibit__trigger:focus-visible .tl-exhibit__img{transform:none!important;}
  .btn:hover,.btn:focus-visible,.btn:active{transform:none!important;}
  .lbx{opacity:1;transition:none!important;}
  .lbx__img{transform:none!important;transition:none!important;will-change:auto;}
  *,*::before,*::after{animation-duration:.001s!important;transition-duration:.001s!important;scroll-behavior:auto!important;}
}

/* The export marked the two forest CTA buttons with a style-hover
   attribute that only the design tool's runtime applied. Reproduced here
   as a real CSS rule so the hover survives the port. */
.btn[style-hover]:hover,.btn[style-hover]:focus{background:#163329;}

/* LEGAL PAGES.
   .list-terms lays out a fixed label column plus a 1fr value column. A long
   unbreakable value (support@siebertcreative.com) sets a min-content floor that
   the 1fr track cannot go below, which pushed /terms and /privacy about 38px
   wider than a 360px screen. min-width:0 lets the track shrink; the wrap rule
   is the backstop. Below 480px the pair stacks, which reads better than
   breaking an email address mid-string. */
.legal-doc .list-terms li{min-width:0;}
.legal-doc .list-terms .term,
.legal-doc .list-terms .detail{min-width:0;overflow-wrap:anywhere;}
@media(max-width:479px){
  .legal-doc .list-terms li{grid-template-columns:1fr;gap:4px;}
}

/* MOBILE NAV OVERFLOW — HISTORICAL, NOW A NO-OP BY DESIGN.
   This rule used to drop the primary CTA below 600px, because the nav then
   held a logo plus TWO CTAs and at 390px that wanted 502px of content in 342px
   of space.

   The shared product nav removed the second CTA: every page now carries a logo,
   a burger and ONE primary button at phone widths, which measures comfortably
   inside 342px. So the rule is gone and the buy button stays reachable from the
   top of every page at every width - which matters more now that the nav is
   also the only place some pages name a price.

   The one thing still required of a page is that its nav CTA has a label short
   enough to fit beside the burger. Use the .nav-cta-long / .nav-cta-short pair
   if the desktop label is a sentence. */
.site-nav__actions .nav-cta-short{display:none;}
@media(max-width:599px){
  .site-nav__actions .nav-cta-long{display:none;}
  .site-nav__actions .nav-cta-short{display:inline;}
  .site-nav__actions .btn{font-size:13px!important;padding:0 14px!important;}
}
