
/* ============ tokens ============ */
:root{
  --paper:#FFFFFF;
  --wash:#F4F5F4;
  --ink:#0A0A0A;
  --muted:#52525B;
  --rule:#E3E4E3;
  --accent:#0B7A3E;
  --accent-dark:#095F31;
  --figure:#0B7A3E;
  --measure:66ch;
  --gut:clamp(1.25rem,4.5vw,4rem);
  --bandY:clamp(2.75rem,6vw,5rem);
  --tap:44px;
  /* ── motion system ──
     Four durations tied to purpose, two curves, one stagger step.
     Accumulated motion uses a different value everywhere and reads as
     unconsidered; a small scale reads as designed. Ambient loops keep
     ease-in-out because they alternate — everything else eases out. */
  --t-fast:150ms;    /* hover, focus, colour  */
  --t-ui:260ms;      /* state change the user caused */
  --t-enter:480ms;   /* element arriving */
  --t-slow:900ms;    /* large or hero movement */
  --ease:cubic-bezier(.22,.61,.36,1);   /* entrances, settling */
  --ease-ui:cubic-bezier(.4,0,.2,1);    /* reversible UI state */
  --stagger:55ms;

  --shell:96rem;      /* page shell — widened from 74rem */
  --measure-p:72ch;   /* prose stays readable regardless of shell width */
  --tint:#EDF5F0;
  --surface:#FFFFFF;
  --lift:0 1px 2px rgba(16,24,40,.05), 0 12px 28px -12px rgba(16,24,40,.14);
  --lift-sm:0 1px 2px rgba(16,24,40,.06);
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* Metric-adjusted fallbacks: keeps CLS at 0 while webfonts load */
@font-face{font-family:"Sans Fallback";src:local("Helvetica Neue"),local("Arial"),local("Roboto");
  size-adjust:100%;ascent-override:92%;descent-override:24%;line-gap-override:0%}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;
  font-size:clamp(1rem,.965rem + .17vw,1.075rem);
  line-height:1.65;
  letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  -webkit-tap-highlight-color:rgba(16,24,40,.14);
}
img,svg,table{max-width:100%}
h1,h2{font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;
  font-weight:700;line-height:1.07;letter-spacing:-.031em;overflow-wrap:break-word}
h3,.sans{font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:600;
  line-height:1.2;letter-spacing:-.017em;overflow-wrap:break-word}
a{color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;text-decoration-color:rgba(11,122,62,.5);
  transition:text-decoration-color var(--t-fast) var(--ease-ui)}
a:hover{text-decoration-color:var(--ink);text-decoration-thickness:2px}
a:hover{text-decoration:underline}
.wrap{max-width:var(--shell,96rem);margin:0 auto;padding-inline:max(var(--gut),env(safe-area-inset-left))}
/* Skip link. Hidden until the first Tab press, then it takes the whole
   top bar rather than floating over the logo. Required by WCAG 2.4.1 and
   stated in our accessibility statement, so it stays. */
.skip{text-decoration:none;position:fixed;top:0;left:0;right:0;z-index:70;
  transform:translateY(-100%);
  display:flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:3rem;padding:.75rem 1rem;
  background:var(--ink);color:#fff;text-decoration:none;
  font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;
  font-weight:500;font-size:.9375rem;letter-spacing:-.01em;
  transition:transform var(--t-fast) var(--ease-ui)}
.skip:focus{transform:none;outline:none;box-shadow:inset 0 -3px 0 var(--accent)}
/* Make room rather than covering the header, so nothing is hidden while
   the link is focused. The sibling selector works because .skip is the
   first element in the body. */
.skip:focus ~ .masthead{margin-top:3rem}
.skip:focus-visible{outline:none}
@media(prefers-reduced-motion:reduce){.skip{transition:none}}

/* ============ buttons ============ */
.btn,.btn-plain{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--tap);
  font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:500;font-size:.9375rem;
  padding:.625rem 1.375rem;border-radius:7px;
  transition:background var(--t-fast) var(--ease-ui),border-color var(--t-fast) var(--ease-ui),transform 120ms var(--ease-ui);
}
.btn:active,.btn-plain:active{transform:translateY(1px)}
.btn{text-decoration:none;background:var(--accent);color:#fff;border:1px solid var(--accent);border-radius:7px;box-shadow:var(--lift-sm)}
.btn:hover{background:var(--accent-dark);border-color:var(--accent-dark);text-decoration:none;color:#fff}
.btn-plain{text-decoration:none;background:var(--surface);color:var(--ink);border:1px solid var(--rule);border-radius:7px;box-shadow:var(--lift-sm)}
.btn-plain:hover{border-color:var(--ink);text-decoration:none}

/* ============ header ============ */
.masthead{border-bottom:1px solid var(--rule);background:var(--paper);position:sticky;top:0;z-index:40}
.masthead .wrap{display:flex;align-items:center;gap:1.5rem;min-height:4.25rem}
.brand{text-decoration:none;min-height:var(--tap);display:inline-flex;align-items:center;min-height:var(--tap);font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:600;font-size:clamp(.9375rem,.9rem + .2vw,1.0625rem);color:var(--ink);letter-spacing:-.02em;white-space:nowrap}
.brand:hover{text-decoration:none;color:var(--accent)}
.brand span{color:var(--muted);font-weight:400}
.nav{margin-left:auto;display:flex;align-items:center;gap:clamp(.875rem,1.6vw,1.75rem);font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-size:.9375rem;font-weight:500}
.nav a:not(.btn){text-decoration:none;color:var(--ink);display:inline-flex;align-items:center;min-height:var(--tap)}
.nav a:not(.btn):hover{color:var(--accent);text-decoration:none}

.menu-btn{
  display:none;margin-left:auto;align-items:center;gap:.5rem;
  min-height:var(--tap);min-width:var(--tap);padding:.5rem .75rem;
  background:none;border:1px solid var(--rule);border-radius:3px;cursor:pointer;
  font:500 .875rem "Google Sans Flex","Sans Fallback",system-ui,sans-serif;color:var(--ink);
}
.menu-btn i{display:block;width:16px;height:1.5px;background:var(--ink);position:relative}
.menu-btn i::before,.menu-btn i::after{content:"";position:absolute;left:0;width:16px;height:1.5px;background:var(--ink)}
.menu-btn i::before{top:-5px}
.menu-btn i::after{top:5px}

/* drawer */
.scrim{position:fixed;inset:0;background:rgba(16,24,40,.45);opacity:0;pointer-events:none;transition:opacity var(--t-ui) var(--ease-ui);z-index:45}
.drawer{
  position:fixed;top:0;right:0;bottom:0;width:min(20rem,86vw);z-index:50;
  background:var(--paper);border-left:1px solid var(--rule);
  transform:translateX(101%);transition:transform var(--t-ui) var(--ease);
  display:flex;flex-direction:column;
  padding:1rem max(1.25rem,env(safe-area-inset-right)) max(1.25rem,env(safe-area-inset-bottom)) 1.25rem;
  overflow-y:auto;overscroll-behavior:contain;
}
body.open .scrim{opacity:1;pointer-events:auto}
body.open .drawer{transform:none}
body.open{overflow:hidden}
/* while the cookie banner is visible, reserve space so it never
   covers the call-to-action or the footer contact details */
body.cc-on{padding-bottom:calc(var(--cc-h,190px) + 2rem)}
@media(prefers-reduced-motion:reduce){.drawer,.scrim{transition:none}}
.drawer-top{display:flex;justify-content:flex-end;margin-bottom:.5rem}
.close-btn{
  min-height:var(--tap);min-width:var(--tap);border:1px solid var(--rule);border-radius:3px;
  background:none;cursor:pointer;font:400 1.375rem/1 "Google Sans Flex","Sans Fallback",system-ui,sans-serif;color:var(--ink);
}
.drawer nav{display:flex;flex-direction:column}
.drawer nav a:not(.btn){text-decoration:none;
  display:flex;align-items:center;min-height:var(--tap);
  padding:.5rem 0;border-bottom:1px solid var(--rule);
  font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:500;font-size:1.0625rem;color:var(--ink);
}
.drawer nav a:not(.btn):hover{color:var(--accent);text-decoration:none}
.drawer .btn{margin-top:1.25rem;width:100%}
.drawer-mail{margin-top:auto;padding-top:1.5rem;font-size:.875rem;color:var(--muted);overflow-wrap:anywhere}

/* ============ hero ============ */

.hero .wrap{position:relative}
.hero h1{font-size:clamp(2rem,1.3rem + 3.2vw,3.75rem);max-width:15ch}
.hero .lede{margin-top:1.25rem;max-width:56ch;color:var(--muted);font-size:clamp(1rem,.97rem + .2vw,1.125rem)}
.hero .actions{margin-top:2rem;display:flex;flex-wrap:wrap;gap:.75rem}
@media(prefers-reduced-motion:no-preference){
  .panel .row,.panel-foot{opacity:0;animation:rise var(--t-enter) cubic-bezier(.22,.61,.36,1) forwards}
  @keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
}

/* ============ bands ============ */
.band{padding-block:var(--bandY);border-top:1px solid var(--rule);scroll-margin-top:6rem}
.band-wash{background:var(--wash)}
.head{max-width:var(--measure)}
.head p{max-width:var(--measure-p)}
.head h2{font-size:clamp(1.625rem,1.25rem + 1.5vw,2.125rem)}
.head p{margin-top:.75rem;color:var(--muted)}
.job .meta{font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:600;font-size:.9375rem;color:var(--figure);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.job .meta span{display:block;color:var(--muted);font-weight:400;font-size:.8125rem;margin-top:.1875rem}

/* ============ faq ============ */
/* FAQ shares the document block's shape so its edges line up with the
   other full-width sections instead of ending short of them. Reading
   measure is held on the answer text inside, where it matters. */
.faq{margin-top:2rem;background:var(--surface);border:1px solid var(--rule);border-radius:10px;
  box-shadow:var(--lift);overflow:hidden}
.faq details{border-bottom:1px solid var(--rule)}
.faq details:last-child{border-bottom:0}
.faq summary{cursor:pointer;padding:1.125rem 3rem 1.125rem 1.5rem;position:relative;list-style:none;min-height:var(--tap);display:flex;align-items:center;font-family:"Google Sans Flex","Sans Fallback",system-ui,sans-serif;font-weight:600;font-size:1.1875rem;letter-spacing:-.017em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:1.5rem;color:var(--accent);font-size:1.25rem;font-weight:400}
.faq details[open] summary::after{content:"−"}
.faq .ans{overflow:hidden}
.faq summary::after{transition:transform var(--t-ui) var(--ease)}
.faq details[open] summary::after{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){.faq summary::after{transition:none}}
@media print{.faq details{display:block}}

/* ============ cta ============ */
.cta{border:1px solid var(--rule);border-radius:14px;
  padding:clamp(2rem,4vw,3.5rem) clamp(1.5rem,4vw,3rem);
  background:var(--surface);box-shadow:var(--lift);
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:.25rem}
.cta h2{font-size:clamp(1.625rem,1.25rem + 1.5vw,2.125rem);max-width:22ch;margin:0;order:1}
.cta > div{display:contents}
.cta p{margin-top:.875rem;color:var(--muted);max-width:52ch;font-size:.9375rem;order:2}
.cta .mail{margin-top:1.5rem;font-size:.9375rem;overflow-wrap:anywhere;order:4}

/* ============ footer ============ */








/* ============================================
   BREAKPOINTS
   1080  small laptop
   900   tablet landscape
   760   tablet portrait  → drawer nav starts
   560   large phone
   380   small phone
   ============================================ */



@media(max-width:900px){
  .nav{display:none}
  .menu-btn{display:inline-flex}
}

@media(max-width:760px){
  .steps{grid-template-columns:1fr}
  

}

@media(max-width:560px){
  .hero h1{max-width:none}
  .hero .actions{gap:.625rem}
  .hero .actions .btn,.hero .actions .btn-plain{flex:1 1 100%}
  .job .meta{text-align:left}
  .job .meta span{display:inline;margin-left:.625rem}
  
  
}

@media(max-width:380px){
  :root{--gut:1.125rem}
  .masthead .wrap{gap:.75rem}
}


/* trader identification */
.trader{margin-top:1.75rem;padding-top:1.25rem;border-top:1px solid var(--rule);
  font-size:.8125rem;line-height:1.7;color:var(--muted);max-width:84ch}
.trader p+p{margin-top:.5rem}
.trader p{max-width:70ch}   /* ~78 real characters; ch is the "0" width, which runs wider than an average glyph */

/* cookie consent — Reject must be as prominent as Accept (PECR / ePrivacy) */
.cc{position:fixed;left:0;right:0;bottom:0;z-index:55;background:var(--paper);
  border-top:1px solid var(--ink);padding:1.25rem var(--gut);
  padding-bottom:max(1.25rem,env(safe-area-inset-bottom));
  box-shadow:0 -8px 24px rgba(22,32,43,.08)}
.cc[hidden]{display:none}
.cc-in{max-width:var(--shell,96rem);margin:0 auto;display:grid;grid-template-columns:1fr auto;
  gap:.75rem 1.5rem;align-items:center}
.cc h2{font-size:.9375rem;margin-bottom:.1875rem}
.cc p{font-size:.8125rem;color:var(--muted);max-width:70ch;line-height:1.5}
.cc-btns{display:flex;gap:.625rem;flex-wrap:wrap}
.cc-btns button{min-height:var(--tap);padding:.5rem 1.125rem;border-radius:3px;cursor:pointer;
  font:500 .9375rem "Google Sans Flex","Sans Fallback",system-ui,sans-serif}
/* identical weight and size: neither choice is nudged */
.cc-accept{background:var(--accent);color:#fff;border:1px solid var(--accent)}
.cc-reject{background:transparent;color:var(--ink);border:1px solid var(--ink)}
.cc-accept:hover{background:var(--accent-dark);border-color:var(--accent-dark)}
.cc-reject:hover{background:var(--wash)}
@media(max-width:760px){.cc-in{grid-template-columns:1fr}.cc-btns button{flex:1 1 auto}}





/* answer block — a self-contained, quotable summary near the top */


/* ── hero field ──
   A ruled grid of nodes behind the hero, the motif of the ruled document
   the whole business is built on. The cursor lifts and tints the nodes
   near it. Canvas rather than DOM because a few hundred elements
   animating would cost layout; this costs one composited bitmap. */
#field{position:absolute;inset:0;z-index:-2;pointer-events:none;
  opacity:0;transition:opacity 700ms var(--ease)}
#field.on{opacity:1}
@media(prefers-reduced-motion:reduce){#field{display:none}}
@media print{#field{display:none}}

/* ── label ──
   One spec for every eyebrow label on the page: the cost factors, the
   comparison headers, the shaper questions, the directory and footer
   headings, and the floating card captions. Three near-identical
   treatments read as three decisions; one reads as a system. */
.factor .n,.vs-head span,.q legend .qn,.browse-col > h3,.related h2,
.foot h3,.float .lab,.meter-lab,.badge{
  font-size:.75rem;font-weight:600;letter-spacing:.055em;text-transform:uppercase}

/* ── answer block ──
   The lead sentence promises three things, so the layout delivers three
   things. Numbered like the clauses elsewhere, revealed in sequence, and
   scannable in a way a paragraph never is. */
.answer{display:block;margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--ink)}
.answer .lead{font-size:clamp(1.125rem,1rem + .5vw,1.4375rem);line-height:1.42;
  font-weight:600;letter-spacing:-.02em;max-width:30ch;margin:0}
.factors{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin-top:2rem;
  border-top:1px solid var(--rule)}
.factor{position:relative;padding:1.5rem 1.75rem 1.5rem 0;border-right:1px solid var(--rule);
  transition:background var(--t-fast) var(--ease-ui)}
.factor:last-child{border-right:0}
.factor + .factor{padding-left:1.75rem}
.factor:hover{background:var(--wash)}
.factor .n{display:flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent);font-variant-numeric:tabular-nums}
.factor .n::after{content:"";flex:1;height:1px;background:var(--rule)}
.factor h3{font-size:1.1875rem;margin:.625rem 0 .375rem;letter-spacing:-.017em}
.factor p{font-size:.875rem;color:var(--muted);line-height:1.55;margin:0;max-width:32ch}
/* weight bar: how much each factor actually moves a quote */
.factor .wt{margin-top:.875rem;height:4px;border-radius:2px;background:rgba(16,24,40,.09);
  overflow:hidden}
.factor .wt i{display:block;height:100%;border-radius:2px;background:var(--accent);
  transform-origin:left;transform:scaleX(0)}
.answer.go .factor .wt i{animation:wt var(--t-slow) var(--ease) forwards}
.answer.go .factor:nth-child(2) .wt i{animation-delay:calc(var(--stagger) * 2)}
.answer.go .factor:nth-child(3) .wt i{animation-delay:calc(var(--stagger) * 4)}
@keyframes wt{to{transform:scaleX(var(--w,1))}}
.answer .tail{margin-top:1.75rem;display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(1.5rem,4vw,3rem);padding-top:1.5rem;border-top:1px solid var(--rule)}
.answer .tail p{font-size:.9375rem;line-height:1.65;color:var(--muted);margin:0;max-width:56ch}
@media(prefers-reduced-motion:reduce){.factor .wt i{transform:scaleX(var(--w,1))}}
@media(max-width:860px){
  .factors{grid-template-columns:1fr}
  .factor{border-right:0;border-bottom:1px solid var(--rule);padding:1.25rem 0}
  .factor + .factor{padding-left:0}
  .factor:last-child{border-bottom:0}
  .answer .tail{grid-template-columns:1fr;gap:1rem}
  .answer .lead{max-width:none}
}





/* selection picks up the brand rather than the browser default */
::selection{background:#EDF5F0;color:#0A0A0A}

/* focus ring sits on a halo so it reads on both paper and tinted bands */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px;
  box-shadow:0 0 0 5px rgba(11,122,62,.16)}

/* links in prose get an underline that thickens on hover, rather than
   appearing from nowhere */
.body a,.lede a,.answer a,.faq a,.panel-foot a{
  text-decoration:underline;text-decoration-color:rgba(11,122,62,.5);
  text-decoration-thickness:1px;text-underline-offset:3px;
  transition:text-decoration-color var(--t-fast) var(--ease-ui)}
.body a:hover,.lede a:hover,.answer a:hover,.faq a:hover,.panel-foot a:hover{
  text-decoration-color:var(--accent);text-decoration-thickness:2px}

/* ── print ──
   People print quotes and legal pages. Default browser output wastes
   ink on tints, hides link destinations and orphans headings. */
@media print{
  *{background:#fff !important;color:#000 !important;box-shadow:none !important}
  body{font-size:11pt;line-height:1.45}
  .masthead,.dock,.cc,.scrim,.drawer,.skip,.related,.cta a,.menu-btn{display:none !important}
  .band,.hero{padding-block:.75rem !important;border:0 !important}
  .wrap{max-width:none;padding:0}
  h1{font-size:20pt}
  h2{font-size:14pt;margin-top:1rem}
  h3{font-size:11.5pt}
  h2,h3{break-after:avoid}
  p,li,.tl-row,.range{break-inside:avoid}
  .panel,.cta{border:1px solid #999 !important;border-radius:0 !important}
  .bar,.tl-bar{box-shadow:inset 0 0 0 1px #000 !important}
  .b-us,.bar{background:#ccc !important}
  /* show where links actually go */
  .body a[href^="/"]::after,.body a[href^="http"]::after{
    content:" (" attr(href) ")";font-size:9pt;color:#555 !important}
  .faq details{border-bottom:1px solid #ccc}
  .faq details p{display:block !important}
  a[href^="mailto"]::after{content:""}
}




/* hero backdrop: a soft field behind the panel so it sits on something
   rather than floating on flat paper */
.hero{position:relative;isolation:isolate;overflow:clip}
.hero::before{content:"";position:absolute;inset:-10% -20% auto auto;
  width:min(46rem,80vw);aspect-ratio:1;z-index:-1;pointer-events:none;
  background:radial-gradient(circle at 65% 35%, var(--wash) 0%, transparent 64%);
  opacity:1}
@media(max-width:900px){.hero::before{inset:-6% -30% auto auto;width:min(34rem,110vw)}}

@media(prefers-reduced-motion:no-preference){
  /* the one page-load moment: headline settles, then the panel fills in */
  .hero h1{animation:settle var(--t-slow) cubic-bezier(.22,.61,.36,1) both}
  .hero h1.split .w{opacity:1;transform:none;animation:none}
  .hero .lede{animation:lift var(--t-enter) cubic-bezier(.22,.61,.36,1) both .12s}
  .hero .lede+.lede{animation-delay:calc(var(--stagger) * 3)}
  .hero .actions{animation:lift var(--t-enter) cubic-bezier(.22,.61,.36,1) both .26s}
  @keyframes settle{
    from{opacity:0;letter-spacing:-.055em;transform:translateY(6px)}
    to{opacity:1;letter-spacing:-.031em;transform:none}}
  @keyframes lift{from{opacity:0;transform:translateY(8px)}}
}


/* ── project shaper ──
   Interactive rather than ambient: every change answers a click and shows
   what moved. Outputs a timeline and a brief, never a price. */
.shape{margin-top:2rem;display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(1.5rem,4vw,3rem);align-items:start}
.q{border:0;margin:0;padding:1.125rem 0;border-bottom:1px solid var(--rule);min-inline-size:0}
.q:first-child{border-top:1px solid var(--rule)}
.q legend{font-weight:600;font-size:.9375rem;letter-spacing:-.015em;padding:0;margin-bottom:.125rem}
.q p{font-size:.8125rem;color:var(--muted);margin:0 0 .75rem;max-width:56ch}
.opts{display:flex;flex-wrap:wrap;gap:.5rem}
.opts label{position:relative}
.opts input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
.opts span{display:inline-flex;align-items:center;justify-content:center;min-height:var(--tap);
  padding:.5rem 1rem;border:1px solid var(--rule);border-radius:7px;background:var(--surface);
  font-size:.875rem;font-weight:500;cursor:pointer;
  transition:border-color var(--t-fast) var(--ease-ui),background var(--t-fast) var(--ease-ui),color var(--t-fast) var(--ease-ui)}
.opts input:hover+span{border-color:var(--ink)}
.opts input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}
.opts input:checked+span{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}

.out{position:sticky;top:5.5rem;border:1px solid var(--rule);border-radius:10px;
  background:var(--surface);box-shadow:var(--lift);overflow:hidden}
.out-head{padding:.9375rem 1.25rem;background:var(--tint);border-bottom:1px solid var(--rule);
  font-weight:600;font-size:.9375rem}
.out-body{padding:1.25rem}
.weeks{display:flex;align-items:baseline;gap:.5rem}
.weeks b{font-size:clamp(2.25rem,1.5rem + 2.2vw,3rem);font-weight:700;letter-spacing:-.03em;
  color:var(--figure);font-variant-numeric:tabular-nums;line-height:1}
.weeks span{font-size:.9375rem;color:var(--muted)}
.meter{margin-top:1rem;height:9px;border-radius:5px;background:rgba(255,255,255,.10)}
.meter i{display:block;height:100%;border-radius:5px;width:20%;
  background:linear-gradient(90deg,#0B7A3E,#0F9450);
  transition:width var(--t-enter) var(--ease)}
.meter-lab{display:flex;justify-content:space-between;font-size:.75rem;color:var(--muted);
  margin-top:.5rem}
.drivers{margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--rule);
  list-style:none;font-size:.875rem}
.drivers li{padding:.375rem 0 .375rem 1.125rem;position:relative;color:var(--muted)}
.drivers li::before{content:"";position:absolute;left:0;top:.9375rem;width:5px;height:5px;
  border-radius:50%;background:var(--accent)}
.out .btn{margin-top:1.25rem;width:100%}
.out-note{margin-top:.75rem;font-size:.75rem;color:var(--muted);line-height:1.5}
@media(prefers-reduced-motion:reduce){.meter i{transition:none}}
@media(max-width:820px){
  .shape{grid-template-columns:1fr}
  .out{position:static}
}







/* ── FAQ ──
   Numbered like every other enumerated block. The marker is a plus that
   rotates to a minus, and the open row tints and carries an accent rule,
   so the state is readable without relying on the marker alone. */
.faq details{position:relative;border-bottom:1px solid var(--rule);
  transition:background var(--t-fast) var(--ease-ui)}
.faq details[open]{background:var(--wash)}
.faq details::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--accent);transform:scaleY(0);transform-origin:top;
  transition:transform var(--t-ui) var(--ease)}
.faq details[open]::before{transform:scaleY(1)}
.faq summary{gap:1rem}
.faq summary .qn{flex:none;font-size:.75rem;font-weight:600;letter-spacing:.06em;
  color:var(--accent);font-variant-numeric:tabular-nums;min-width:1.75rem}
.faq summary .qx{flex:1}
.faq details[open] summary{color:var(--ink)}
@media(max-width:640px){ }

/* answer text lines up under the question, clear of the number */
.faq .ans p{margin:0;padding:0 1.5rem 1.25rem calc(1.5rem + 1.75rem + 1rem);
  color:var(--muted);font-size:.9375rem;line-height:1.6;max-width:70ch}
@media(max-width:640px){
  .faq .ans p{padding:0 1.125rem 1.125rem calc(1.125rem + 1.75rem + .75rem)}
}

/* ── dark band ──
   Used sparingly: two sections plus the footer. Black is punctuation
   here, not alternation. Its own tokens, because the light theme's
   greys and the dark green accent both fail on a black ground. */
.band-dark{
  --ink:#F4F4F5; --muted:#A1A1AA; --rule:#2A2A2E; --surface:#141417;
  --wash:#18181B; --tint:#12211A; --accent:#3DDC84; --accent-dark:#2FD16B;
  background:#0A0A0A; color:var(--ink); border-top:0;
  position:relative; isolation:isolate}
.band-dark a{color:var(--ink);text-decoration-color:rgba(244,244,245,.42)}
.band-dark a:hover{color:#fff;text-decoration-color:#fff}
.band-dark .btn{background:var(--accent);border-color:var(--accent);color:#062012;
  box-shadow:0 0 0 1px rgba(61,220,132,.22), 0 8px 24px -10px rgba(61,220,132,.5)}
.band-dark .btn:hover{box-shadow:0 0 0 1px rgba(61,220,132,.4), 0 10px 30px -10px rgba(61,220,132,.65)}
.band-dark .btn-plain{background:transparent;border-color:var(--rule);color:var(--ink)}
.band-dark .cta{background:var(--surface);border-color:var(--rule);
  box-shadow:0 1px 2px rgba(0,0,0,.5), 0 20px 44px -20px rgba(0,0,0,.8)}
.band-dark .vs-now{background:linear-gradient(90deg,var(--wash),transparent 92%)}
.band-dark .vs-row:hover .vs-now{background:linear-gradient(90deg,var(--tint),transparent 92%)}
/* a soft field so the black band has depth rather than reading flat */
.band-dark::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(60rem 30rem at 18% 0%, rgba(61,220,132,.10), transparent 62%)}
@media(prefers-reduced-motion:no-preference){
  .band-dark::after{animation:darkfield 28s ease-in-out infinite alternate}
  @keyframes darkfield{from{transform:translate3d(0,0,0) scale(1)}
                         to{transform:translate3d(14%,6%,0) scale(1.2)}}
}
@media print{.band-dark{background:#fff !important;color:#000 !important}
  .band-dark::after{display:none}}

/* ── footer ──
   Dark, to close the page and separate the fine print from the sales
   copy above it. Its own colour tokens because the site is otherwise
   light: reusing --muted here would fail contrast. */
.foot{--f-ink:#F4F4F5;--f-muted:#A1A1AA;--f-rule:#2A2A2E;
  background:#0A0A0A;color:var(--f-ink);border-top:0;
  margin-top:clamp(3rem,7vw,5.5rem);
  padding-block:clamp(2.75rem,5vw,4rem) 2rem;
  padding-bottom:max(2rem,env(safe-area-inset-bottom))}
.foot a{color:var(--f-ink);text-decoration-color:rgba(244,244,245,.4)}
.foot a:hover{color:#fff;text-decoration-color:#fff}

.foot-top{display:grid;grid-template-columns:1.3fr repeat(6,minmax(0,1fr));gap:clamp(1.5rem,2.2vw,2.25rem);padding-bottom:2.25rem;border-bottom:1px solid var(--f-rule);align-items:start}
.foot-brand .b{font-weight:600;font-size:1.0625rem;letter-spacing:-.02em}
.foot-brand .b span{color:var(--f-muted);font-weight:400}
.foot-brand p{margin-top:.625rem;font-size:.875rem;color:var(--f-muted);line-height:1.55;max-width:34ch}
.foot-brand a{font-size:.875rem;display:inline-flex;align-items:center;min-height:1.75rem;margin-top:.75rem}

.foot h3{display:flex;align-items:center;gap:.5rem;margin:0 0 .625rem;
  font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--f-muted)}
.foot ul{list-style:none;margin:0;padding:0}
.foot li{margin:0}
.foot li > *{display:flex;align-items:center;gap:.5rem;min-height:2.25rem;
  font-size:.875rem;color:var(--f-ink);text-decoration:none;
  transition:color var(--t-fast) var(--ease-ui),padding-left var(--t-ui) var(--ease)}
.foot li > a:hover{color:#fff;padding-left:.25rem}
.foot li > span{color:var(--f-muted)}
.foot li > span::after{content:"soon";margin-left:auto;font-size:.625rem;letter-spacing:.05em;
  text-transform:uppercase;opacity:.6}

.foot-base{margin-top:1.75rem;padding-top:0;border-top:0;display:flex;flex-wrap:wrap;
  gap:.75rem 1.5rem;justify-content:space-between;align-items:center;
  font-size:.8125rem;color:var(--f-muted)}
.foot-base nav{display:flex;flex-wrap:wrap;gap:.5rem 1.25rem}
.foot-base nav a{display:inline-flex;align-items:center;min-height:1.75rem}
.foot-base a{font-size:.8125rem}

.foot .trader{max-width:none;margin-top:1.75rem;padding-top:1.5rem;border-top:1px solid var(--f-rule);display:grid;grid-template-columns:repeat(auto-fit,minmax(21rem,1fr));gap:1rem clamp(2rem,5vw,4rem);font-size:.75rem;line-height:1.7;color:var(--f-muted)}
.foot .trader p{max-width:62ch;margin:0}
.foot .trader a{color:var(--f-muted);text-decoration-color:rgba(161,161,170,.45)}
.foot .trader a:hover{color:var(--f-ink)}
@media(max-width:900px){
  .foot-top{grid-template-columns:1fr 1fr;gap:1.75rem}
  .foot-brand{grid-column:1/-1}
  .foot .trader{grid-template-columns:1fr}
}
@media(max-width:560px){ .foot-top{grid-template-columns:1fr} }
@media print{ .foot{background:#fff !important;color:#000 !important} }

/* ── related ──
   A card grid rather than a bulleted list. Each card is one target, the
   whole card is the hit area, and the arrow only moves on hover so the
   row reads as a destination rather than decoration. */
.related{margin-top:clamp(2.5rem,6vw,4rem)}
.related h2{display:flex;align-items:center;gap:.625rem;margin:0 0 1.25rem;
  font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent)}
.related h2::after{content:"";flex:1;height:1px;background:var(--rule)}
.related ul{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(17rem,1fr));
  gap:clamp(.75rem,1.5vw,1rem)}
.related li{display:flex}
.related li > *{position:relative;flex:1;display:block;padding:1.125rem 2.25rem 1.25rem 1.25rem;
  background:var(--surface);border:1px solid var(--rule);border-radius:10px;
  text-decoration:none;color:var(--ink);
  transition:border-color var(--t-fast) var(--ease-ui),
             box-shadow var(--t-ui) var(--ease),
             transform var(--t-ui) var(--ease)}
.related a:hover{border-color:var(--accent);box-shadow:var(--lift);transform:translateY(-2px)}
.related a:focus-visible{border-color:var(--accent)}
.related .t{display:block;font-weight:600;font-size:1rem;line-height:1.35;
  letter-spacing:-.017em}
.related .d{display:block;margin-top:.375rem;font-size:.8125rem;line-height:1.5;
  color:var(--muted)}
/* arrow sits still until the card is engaged */
.related a::after{content:"";position:absolute;right:1.125rem;top:1.375rem;
  width:7px;height:7px;border-right:1.5px solid var(--muted);border-top:1.5px solid var(--muted);
  transform:rotate(45deg);
  transition:transform var(--t-ui) var(--ease),border-color var(--t-fast) var(--ease-ui)}
.related a:hover::after{border-color:var(--accent);transform:rotate(45deg) translate(2px,-2px)}
/* an unpublished target reads as pending rather than broken */
.related li > span{cursor:default}
.related li > span .t{color:var(--muted)}
.related li > span::after{content:"soon";position:absolute;right:1.125rem;top:1.25rem;
  font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);opacity:.7}

/* ── browse grid ──
   Two columns, one row per entry, aligned on a shared baseline. Styled
   to read as a directory rather than a bulleted list, and to hold that
   shape whether an entry is a live link or plain text while its page is
   still unbuilt. */
.browse{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(2rem,5vw,4.5rem);margin-top:2rem}
/* an entry whose page is not published yet reads as pending, not broken */
.browse li > span{color:var(--muted)}
@media(max-width:760px){
  .browse{grid-template-columns:1fr;gap:2rem}
}

/* ── shaper refinements ──
   Numbered like every other enumerated block on the page. Selection is a
   sweep rather than a snap, so the choice registers. The readout header
   carries one slow scan so the panel reads as live without distracting
   from the figure. */
.q legend{display:flex;align-items:center;gap:.625rem;width:100%}
.q legend .qn{font-size:.75rem;font-weight:600;letter-spacing:.06em;color:var(--accent);
  font-variant-numeric:tabular-nums}
.q legend .qt{font-weight:600;font-size:.9375rem;letter-spacing:-.015em}
.q legend::after{content:"";flex:1;height:1px;background:var(--rule)}

.opts span{position:relative;overflow:hidden;z-index:0}
.opts span::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--accent);
  transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-ui) var(--ease)}
.opts input:checked+span::before{transform:scaleX(1)}
.opts input:checked+span{background:transparent;border-color:var(--accent);color:#fff}

/* readout: a slow scan across the header, and a soft pulse on the figure
   when the value changes */
@media(prefers-reduced-motion:no-preference){
  .out-head{position:relative;overflow:hidden}
  .out-head::after{content:"";position:absolute;top:0;bottom:0;width:40%;
    background:linear-gradient(90deg,transparent,rgba(11,122,62,.10),transparent);
    transform:translateX(-140%);animation:scan 5.5s ease-in-out infinite}
  @keyframes scan{0%{transform:translateX(-140%)}55%,100%{transform:translateX(320%)}}
  .weeks b{transition:transform var(--t-ui) var(--ease)}
  .weeks b.bump{animation:bump 420ms var(--ease)}
  @keyframes bump{0%{transform:scale(1)}35%{transform:scale(1.06)}100%{transform:scale(1)}}
}

/* answered-so-far marks in the readout header */
.prog-dots{display:flex;gap:4px;align-items:center}
.prog-dots i{width:5px;height:5px;border-radius:50%;background:var(--rule);
  transition:background var(--t-fast) var(--ease-ui),transform var(--t-fast) var(--ease)}
.prog-dots i.on{background:var(--accent);transform:scale(1.25)}

/* ── contrast rows ──
   Numbered like the clauses and the cost factors, so the three
   enumerated blocks on the page share one visual language. The left
   column recedes, the right carries the accent: the layout itself is
   the argument. */
.vs{margin-top:2rem}
.vs-head{display:grid;grid-template-columns:2.5rem minmax(0,1fr) minmax(0,1fr);
  gap:0 clamp(1.5rem,4vw,3rem);padding-bottom:.75rem;border-bottom:1px solid var(--ink)}
.vs-head span{display:flex;align-items:center;gap:.625rem;font-size:.75rem;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.vs-head span::after{content:"";flex:1;height:1px;background:var(--rule)}
.vs-head span:first-child{grid-column:2}
.vs-head span.now{color:var(--accent)}
.vs-head span.now::after{background:var(--accent);opacity:.35}

.vs-row{display:grid;grid-template-columns:2.5rem minmax(0,1fr) minmax(0,1fr);
  gap:0 clamp(1.5rem,4vw,3rem);border-bottom:1px solid var(--rule);align-items:start}
.vs-n{grid-column:1;padding-top:1.5rem;font-size:.75rem;font-weight:600;color:var(--accent);
  font-variant-numeric:tabular-nums;letter-spacing:.04em}
.vs-row > .vs-then{grid-column:2}
.vs-row > .vs-now{grid-column:3}
.vs-row > div{padding:1.375rem 0 1.5rem}

.vs-then h3{font-size:1.1875rem;font-weight:500;color:var(--muted);margin:0 0 .4375rem;
  letter-spacing:-.015em}
.vs-then p{font-size:.9375rem;line-height:1.6;color:var(--muted);margin:0;max-width:56ch;opacity:.82}

.vs-now{position:relative;padding-left:clamp(1.25rem,2.5vw,2rem) !important;
  margin-left:calc(clamp(1.25rem,2.5vw,2rem) * -1);
  background:linear-gradient(90deg,var(--wash),transparent 92%);
  transition:background var(--t-fast) var(--ease-ui)}
.vs-row:hover .vs-now{background:linear-gradient(90deg,var(--tint),transparent 92%)}
.vs-now::before{content:"";position:absolute;left:0;top:1.375rem;bottom:1.5rem;
  width:3px;background:var(--accent);border-radius:2px;
  transform:scaleY(0);transform-origin:top;
  transition:transform var(--t-enter) var(--ease)}
.vs.go .vs-row .vs-now::before{transform:scaleY(1)}
.vs.go .vs-row:nth-child(3) .vs-now::before{transition-delay:calc(var(--stagger) * 2)}
.vs.go .vs-row:nth-child(4) .vs-now::before{transition-delay:calc(var(--stagger) * 4)}
.vs-now h3{font-size:1.1875rem;margin:0 0 .4375rem;letter-spacing:-.017em}
.vs-now p{font-size:.9375rem;line-height:1.6;margin:0;max-width:56ch}

@media(max-width:820px){
  .vs-head{display:none}
  .vs-row{grid-template-columns:2.25rem 1fr;gap:0 .875rem}
  .vs-n{padding-top:1.125rem}
  .vs-row > .vs-then,.vs-row > .vs-now{grid-column:2}
  .vs-row > .vs-then{padding-bottom:.5rem}
  .vs-then h3::after{content:" \2014 usually";font-weight:400;opacity:.7;font-size:.875rem}
  .vs-now{margin-left:0;padding:1rem 0 1.25rem 1rem !important}
}

/* ── written terms block ──
   One document with ruled clauses, not four separate cards. The section
   is literally about what you get on paper, so it reads as an extract. */
.doc-block{margin-top:2rem;background:var(--surface);border:1px solid var(--rule);
  border-radius:10px;box-shadow:var(--lift);overflow:hidden}
.doc-head{display:flex;flex-wrap:wrap;gap:.5rem 1rem;align-items:baseline;
  padding:1rem 1.5rem;background:var(--tint);border-bottom:1px solid var(--rule)}
.doc-head strong{font-weight:600;font-size:.9375rem;letter-spacing:-.015em}
.doc-head span{font-size:.8125rem;color:var(--muted)}
.clause{display:grid;grid-template-columns:1.75rem 1fr auto;gap:.375rem 1rem;
  padding:1.25rem 1.5rem;border-bottom:1px solid var(--rule)}
.clause:last-child{border-bottom:0}
.clause-n{font-size:.8125rem;font-weight:600;color:var(--accent);
  font-variant-numeric:tabular-nums;padding-top:.1875rem}
.clause h3{font-size:1.1875rem;margin:0}
.clause p{grid-column:2;font-size:.9375rem;color:var(--muted);margin:.25rem 0 0;max-width:68ch}
.clause-when{font-size:.75rem;color:var(--ink);font-weight:600;text-transform:none;white-space:nowrap;
  padding:.25rem .5rem;background:#E8EBE9;border-radius:5px;align-self:start}
@media(max-width:640px){
  .faq summary{padding:1.125rem 2.5rem 1.125rem 1.125rem}
  .faq summary::after{right:1.125rem}
  .clause{grid-template-columns:1.5rem 1fr;padding:1.125rem 1.125rem}
  .clause-when{grid-column:2;justify-self:start;margin-top:.5rem}
  .doc-head{padding:.875rem 1.125rem}
}


/* ── one reveal pattern, reused ──
   The timeline already reveals its rows in sequence when scrolled to.
   The comparison rows and the numbered clauses are the other two
   enumerable lists on the page, so they use the same mechanism rather
   than each getting an effect of its own. Nothing fades in that is not
   part of a sequence. */
@media(prefers-reduced-motion:no-preference){
  .reveal.armed > .vs-row,
  .reveal.armed > .clause{opacity:0;transform:translateY(10px)}
  .reveal.armed.go > .vs-row,
  .reveal.armed.go > .clause{animation:step var(--t-enter) cubic-bezier(.22,.61,.36,1) forwards}
  .reveal.armed.go > *:nth-child(2){animation-delay:calc(var(--stagger) * 1)}
  .vs.reveal.armed.go > *:nth-child(3){animation-delay:calc(var(--stagger) * 1)}
  .vs.reveal.armed.go > *:nth-child(4){animation-delay:calc(var(--stagger) * 2)}
  .reveal.armed.go > *:nth-child(3){animation-delay:calc(var(--stagger) * 2)}
  .reveal.armed.go > *:nth-child(4){animation-delay:calc(var(--stagger) * 3)}
  .reveal.armed.go > *:nth-child(5){animation-delay:calc(var(--stagger) * 5)}
  @keyframes step{to{opacity:1;transform:none}}
}

/* rows respond to the pointer, so the list reads as scannable */
.vs-row,.clause{transition:background var(--t-fast) var(--ease-ui)}
.vs-row:hover{background:linear-gradient(90deg,transparent,var(--wash) 60%)}
.clause:hover{background:var(--wash)}
@media(hover:none){.vs-row:hover,.clause:hover{background:none}}



/* ── dark-theme luminance ──
   A faint halo reads as lit rather than merely light-coloured. Only
   possible on a dark ground, so it is specific to this theme rather
   than a generic glow. */
.btn{box-shadow:0 1px 2px rgba(11,122,62,.18), 0 8px 20px -10px rgba(11,122,62,.4)}
.btn:hover{box-shadow:0 2px 4px rgba(11,122,62,.22), 0 12px 26px -10px rgba(11,122,62,.5)}
.opts input:checked+span{box-shadow:0 1px 3px rgba(11,122,62,.2), 0 6px 16px -8px rgba(11,122,62,.35)}
.chip i{box-shadow:0 0 0 3px rgba(11,122,62,.14)}
.badge i{box-shadow:0 0 0 3px rgba(11,122,62,.16)}

/* figures that count use tabular digits so the box never reflows */
.tick{font-variant-numeric:tabular-nums}

/* a single easing curve everywhere, so motion feels like one system */
:root{--ease:cubic-bezier(.22,.61,.36,1)}
.btn,.btn-plain,.opts span,.top,.dock,.skip,.meter i,.chip{transition-timing-function:var(--ease)}
.meter i{transition:width var(--t-enter) var(--ease)}









/* ── 3D stage ──
   A real perspective scene rather than a flat parallax: cards sit at
   different Z depths and the whole stage rotates toward the pointer.
   Depth is cued three ways — position, scale and dimming — so it still
   reads as space on a screen with no shadows to speak of. */
.hero{perspective:1400px;perspective-origin:50% 45%}
.hero-cards{transform-style:preserve-3d;
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
  transition:transform var(--t-enter) var(--ease)}
.hero-cards.live{transition:transform 120ms linear}
.float{transform-style:preserve-3d;--z:0px}
/* front to back */
.f1{--z:70px}  .f5{--z:52px}
.f3{--z:34px}  .f6{--z:16px}
.f2{--z:-30px} .f4{--z:-52px}
/* things further back sit slightly smaller and dimmer */
/* depth on white comes from shadow weight and a touch of recession,
   not from fading the card out — faded cards just look broken here */
.f1{--card-sh:0 2px 6px rgba(16,24,40,.06), 0 22px 44px -18px rgba(16,24,40,.30)}
.f5{--card-sh:0 2px 5px rgba(16,24,40,.06), 0 18px 38px -18px rgba(16,24,40,.26)}
.f3{--card-sh:0 1px 4px rgba(16,24,40,.05), 0 14px 30px -18px rgba(16,24,40,.20)}
.f6{--card-sh:0 1px 3px rgba(16,24,40,.05), 0 10px 24px -16px rgba(16,24,40,.16)}
.f2{--card-sh:0 1px 2px rgba(16,24,40,.04), 0 7px 18px -14px rgba(16,24,40,.13);opacity:.94}
.f4{--card-sh:0 1px 2px rgba(16,24,40,.04), 0 5px 14px -12px rgba(16,24,40,.11);opacity:.9}
.f6{opacity:.94}
@media(prefers-reduced-motion:reduce){
  .hero-cards{transform:none !important;transition:none}
}

/* ── green-specific motion ──
   The accent now carries a hue, so it can do things white could not:
   a travelling highlight along the meter, and a signal pulse on the
   spine mark. Both compositor-only. */
@media(prefers-reduced-motion:no-preference){
  /* meter gains a moving sheen so the readout looks live */
  .meter i{position:relative;overflow:hidden}
  .meter i::after{content:"";position:absolute;inset:0;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.5),transparent);
    transform:translateX(-100%);animation:sheen 2.8s ease-in-out infinite}
  @keyframes sheen{0%{transform:translateX(-100%)}60%,100%{transform:translateX(200%)}}

  /* the active spine mark emits a soft signal */
  .spine li.on a::before{box-shadow:0 0 0 3px rgba(11,122,62,.18)}
  .spine li.on a{animation:mark 2.4s ease-in-out infinite}
  @keyframes mark{0%,100%{opacity:1}50%{opacity:.72}}

  /* ticker items warm to the accent as they pass the centre */
  .ticker:hover span{color:var(--accent)}

  /* primary button carries a slow travelling edge light */
  .btn{position:relative;overflow:hidden}
  .btn::after{content:"";position:absolute;top:0;bottom:0;width:35%;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.3),transparent);
    transform:translateX(-160%);animation:edge 4.5s ease-in-out infinite}
  .btn:hover::after{animation-duration:1.6s}
  @keyframes edge{0%{transform:translateX(-160%)}55%,100%{transform:translateX(360%)}}
}

/* ── clause spine ──
   The business's whole argument is that everything is written down and
   numbered before work starts. So the page carries a document index:
   numbered marks down the edge, the current one filled, click to jump.
   Structure as argument rather than decoration. */
.spine{position:fixed;left:max(1rem,calc((100vw - var(--shell,96rem))/2 - 3.25rem));
  top:50%;transform:translateY(-50%);z-index:30;display:none;
  flex-direction:column;gap:.5rem;padding:0;margin:0;list-style:none}
.spine li{margin:0}
.spine a{display:flex;align-items:center;gap:.5rem;text-decoration:none;
  font-size:.75rem;font-variant-numeric:tabular-nums;color:var(--muted);
  opacity:.45;transition:opacity var(--t-fast) var(--ease-ui),color var(--t-fast) var(--ease-ui)}
.spine a::before{content:"";width:14px;height:1px;background:currentColor;
  transition:width var(--t-ui) var(--ease)}
.spine a:hover{opacity:1;color:var(--ink)}
.spine li.on a{opacity:1;color:var(--ink);font-weight:600}
.spine li.on a::before{width:26px;height:2px}
.spine a:focus-visible{opacity:1;color:var(--ink);outline:2px solid var(--ink);
  outline-offset:4px;border-radius:2px}
@media(min-width:1700px){ .spine{display:flex} }
@media print{ .spine{display:none} }

/* ── universal reveal layer ──
   One keyframe, one duration, stagger by document order within each
   group. A single system reads as deliberate; a different effect per
   section reads as accumulated. Short (.42s) so scanning is never
   blocked, and compositor-only so it costs no layout. */
@media(prefers-reduced-motion:no-preference){
  [data-rv]{opacity:0;transform:translate3d(0,14px,0);will-change:transform,opacity}
  [data-rv].in{animation:rv var(--t-enter) cubic-bezier(.22,.61,.36,1) forwards}
  @keyframes rv{to{opacity:1;transform:none}}
}

/* ── heading reveal ──
   Words rise in sequence rather than the whole block fading. Split by
   word, not letter: letter-splitting breaks screen-reader pronunciation
   and hyphenation, word-splitting does not. The heading text stays in
   the DOM either way, so this degrades to plain text without JS. */
.w{display:inline-block}
@media(prefers-reduced-motion:no-preference){
  .split .w{opacity:0;transform:translateY(.5em) rotate(1.5deg);
    transform-origin:0 100%;will-change:transform,opacity}
  .split.go .w{animation:word var(--t-enter) cubic-bezier(.19,1,.22,1) forwards}
  @keyframes word{to{opacity:1;transform:none}}
}

/* section rules draw in rather than appearing */
@media(prefers-reduced-motion:no-preference){
  .band{position:relative}
  .band::after{content:"";position:absolute;top:0;left:0;height:1px;width:0;
    background:var(--ink);opacity:.35}
  .band.lit::after{animation:draw var(--t-slow) cubic-bezier(.22,.61,.36,1) forwards}
  @keyframes draw{to{width:100%}}
}

/* ── platform ticker ──
   Continuous motion that also carries information: which platforms we
   build on. Two identical tracks, the second offset by exactly its own
   width, so the seam never shows. Pauses on hover and on focus so it
   cannot run away from someone reading it. */
.ticker{position:relative;overflow:hidden;border-top:1px solid var(--rule);
  border-bottom:1px solid var(--rule);padding:1.125rem 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.ticker-track{display:flex;width:max-content;will-change:transform}
.ticker-track > div{display:flex;align-items:center;gap:clamp(2rem,5vw,4rem);
  padding-right:clamp(2rem,5vw,4rem)}
.ticker span{display:inline-flex;align-items:center;gap:.625rem;white-space:nowrap;
  font-size:clamp(1rem,.9rem + .4vw,1.25rem);font-weight:600;letter-spacing:-.02em;
  color:var(--muted);transition:color var(--t-fast) var(--ease-ui)}
.ticker span::before{content:"";width:5px;height:5px;border-radius:50%;
  background:var(--rule);flex:none}
.ticker:hover span{color:var(--ink)}
@media(prefers-reduced-motion:no-preference){
  .ticker-track{animation:slide 38s linear infinite}
  .ticker:hover .ticker-track,.ticker:focus-within .ticker-track{animation-play-state:paused}
  @keyframes slide{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
}

/* ── pill navigation ── */
.masthead{background:transparent;border-bottom:0;position:sticky;top:0;z-index:40;
  padding-top:.875rem}
.masthead .wrap{max-width:var(--shell,96rem)}
.pill{display:flex;align-items:center;gap:.75rem;width:100%;
  background:rgba(255,255,255,.86);backdrop-filter:blur(14px);
  border:1px solid var(--rule);border-radius:999px;padding:.4375rem .4375rem .4375rem 1.25rem}
.pill .brand{min-height:2.5rem}
.pill .nav{gap:clamp(.75rem,1.4vw,1.5rem)}
.pill .btn{border-radius:999px;padding:.5rem 1.125rem;min-height:2.5rem}
.pill .menu-btn{border-radius:999px}

/* ── floating constellation ──
   Cards carry real commitments, not invented dashboard screenshots.
   They are decorative in position only; every figure is checkable. */
.hero{position:relative;isolation:isolate;overflow:clip;padding-block:var(--bandY);
  min-height:min(46rem,86vh)}
.stage{position:relative;text-align:center;max-width:46rem;margin:0 auto;z-index:2}
.hero .wrap{min-height:inherit;display:flex;flex-direction:column;justify-content:center}
.stage h1{font-size:clamp(2.25rem,1.2rem + 4.6vw,4.5rem);max-width:none;margin:0 auto}
.stage .lede{margin:1.5rem auto 0;max-width:46ch;text-align:center}
.stage .actions{margin-top:2rem;justify-content:center}

.float{position:absolute;z-index:1;pointer-events:none;max-width:12.25rem;
  translate:0 var(--px,0);border-color:#DCDEDC;
  background:var(--surface);border:1px solid var(--rule);border-radius:14px;
  padding:.875rem 1rem;box-shadow:var(--card-sh, 0 8px 22px -12px rgba(16,24,40,.16));
  text-align:left;min-width:9.5rem}
.float .lab{color:var(--muted);font-size:.75rem}
.float .val{display:block;margin-top:.3125rem;font-size:1.375rem;font-weight:700;
  letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.float .sub{display:block;margin-top:.1875rem;font-size:.75rem;color:var(--muted)}
.f1{top:2%;left:0}
.f2{top:33%;left:1%}
.f3{top:6%;right:0}
.f4{top:37%;right:0}
.f5{bottom:4%;left:3%}
.f6{bottom:8%;right:2%}

/* mini bar chart, drawn in CSS rather than shipped as an image */
.spark{display:flex;align-items:flex-end;gap:3px;height:26px;margin-top:.5rem}
.spark i{flex:1;height:100%;background:var(--rule);border-radius:2px}
.spark i.on{background:var(--accent)}

@media(prefers-reduced-motion:no-preference){
  /* Six distinct paths rather than one shared keyframe: identical drift on
     every card reads as a single moving layer. Different durations keep
     them out of phase indefinitely, so the loop never visibly repeats.
     Transform and opacity only, so this stays off the main thread. */
  .float{will-change:transform}
  .f1{animation:driftA 11s ease-in-out infinite alternate}
  .f2{animation:driftB 14s ease-in-out infinite alternate}
  .f3{animation:driftC 12.5s ease-in-out infinite alternate}
  .f4{animation:driftD 16s ease-in-out infinite alternate}
  .f5{animation:driftE 13s ease-in-out infinite alternate}
  .f6{animation:driftF 15s ease-in-out infinite alternate}
  @keyframes driftA{from{transform:translate3d(0,-7px,var(--z)) rotate(-.5deg)}
                      to{transform:translate3d(4px,7px,var(--z)) rotate(.4deg)}}
  @keyframes driftB{from{transform:translate3d(3px,6px,var(--z)) rotate(.6deg)}
                      to{transform:translate3d(-3px,-8px,var(--z)) rotate(-.4deg)}}
  @keyframes driftC{from{transform:translate3d(-4px,5px,var(--z)) rotate(.5deg)}
                      to{transform:translate3d(2px,-7px,var(--z)) rotate(-.6deg)}}
  @keyframes driftD{from{transform:translate3d(2px,-6px,var(--z)) rotate(-.4deg)}
                      to{transform:translate3d(-4px,8px,var(--z)) rotate(.5deg)}}
  @keyframes driftE{from{transform:translate3d(-3px,-5px,var(--z)) rotate(.4deg)}
                      to{transform:translate3d(4px,6px,var(--z)) rotate(-.5deg)}}
  @keyframes driftF{from{transform:translate3d(4px,7px,var(--z)) rotate(-.6deg)}
                      to{transform:translate3d(-2px,-6px,var(--z)) rotate(.4deg)}}

  /* the sparkline reads as a live meter; scaleY keeps it off layout */
  .spark i{transform-origin:bottom;animation:pulse 3.2s ease-in-out infinite}
  .spark i:nth-child(2){animation-delay:-.4s}
  .spark i:nth-child(3){animation-delay:-.8s}
  .spark i:nth-child(4){animation-delay:-1.2s}
  .spark i:nth-child(5){animation-delay:-1.6s}
  .spark i:nth-child(6){animation-delay:-2s}
  @keyframes pulse{0%,100%{transform:scaleY(.62)}50%{transform:scaleY(1)}}

  /* the status dot breathes, so the chip reads as current */
  .chip i{animation:breathe 2.6s ease-in-out infinite}
  @keyframes breathe{0%,100%{opacity:.55;box-shadow:0 0 0 2px rgba(11,122,62,.12)}
                      50%{opacity:1;box-shadow:0 0 0 5px rgba(11,122,62,.2)}}

  /* backdrop drifts slowly enough to feel like depth rather than motion */
  .hero::before{animation:bloom 24s ease-in-out infinite alternate}
  @keyframes bloom{from{transform:translate3d(0,0,0) scale(1);opacity:.85}
                     to{transform:translate3d(-3%,2%,0) scale(1.12);opacity:1}}
}
@media(max-width:1280px){ .f2,.f4{display:none} }
@media(max-width:1100px){
  .float{position:static;display:none}
  .stage{max-width:none}
  .hero-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:.625rem;margin-top:2.25rem}
  .hero-cards .float{display:block;min-width:0;animation:none}
}
@media(min-width:1101px){ .hero-cards{display:contents} }

/* ── commitment band ──
   Agency sites use a big-number row for earned metrics: funding raised,
   awards won, users reached. With no track record yet, the honest
   equivalent is the commitments themselves — each one verifiable in the
   terms rather than asserted. */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:0;
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.stat{padding:clamp(1.5rem,3vw,2.25rem) clamp(1rem,2vw,2rem) clamp(1.5rem,3vw,2.25rem) 0;
  border-right:1px solid var(--rule)}
.stat:last-child{border-right:0}
.stat:not(:first-child){padding-left:clamp(1rem,2vw,2rem)}
.stat .fig{display:flex;align-items:baseline;gap:.3rem}
.stat b{font-size:clamp(2.25rem,1.4rem + 3vw,3.75rem);font-weight:700;
  line-height:1;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.stat em{font-style:normal;font-size:clamp(.9375rem,.85rem + .4vw,1.25rem);
  letter-spacing:-.02em;color:var(--muted);font-weight:600;line-height:1}
.stat p{margin-top:.75rem;font-size:.875rem;color:var(--muted);line-height:1.5;max-width:26ch}
.stat a{font-size:.8125rem}
@media(max-width:860px){
  .stats{grid-template-columns:1fr 1fr}
  .stat{padding:1.25rem 1rem 1.25rem 0}
  .stat:nth-child(2n){border-right:0}
  .stat:nth-child(2n+1){padding-left:0}
  .stat:nth-child(-n+2){border-bottom:1px solid var(--rule)}
}
@media(max-width:480px){
  .stats{grid-template-columns:1fr}
  .stat{border-right:0;border-bottom:1px solid var(--rule);padding:1.125rem 0}
  .stat:last-child{border-bottom:0}
}

/* ── metric chips ──
   Borrowed from operations dashboards: a dense row of labelled figures
   above the fold. Each one is a commitment, not a vanity number. */
.chips{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.5rem}
.chip{display:inline-flex;align-items:center;gap:.5rem;padding:.4375rem .75rem;
  background:var(--surface);border:1px solid var(--rule);border-radius:7px;
  font-size:.8125rem;color:var(--muted);white-space:nowrap}
.chip b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.chip i{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;
  box-shadow:0 0 0 3px rgba(244,244,245,.12)}

/* ── readout ──
   The shaper output styled as an instrument panel: a state badge, a large
   tabular figure, and a meter that moves when the inputs change. */
.out-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem}
.out-head > span:first-child{margin-right:auto}
.badge{display:inline-flex;align-items:center;gap:.375rem;padding:.25rem .5rem;
  border:1px solid var(--rule);border-radius:5px;background:var(--paper);
  font-size:.75rem;font-weight:600;letter-spacing:.02em;text-transform:uppercase;
  color:var(--muted)}
.badge i{width:5px;height:5px;border-radius:50%;background:var(--accent)}
.weeks b{font-variant-numeric:tabular-nums;letter-spacing:-.04em}
.meter{background:rgba(16,24,40,.08);box-shadow:inset 0 0 0 1px rgba(16,24,40,.04)}
.meter-lab{font-variant-numeric:tabular-nums;letter-spacing:.01em;text-transform:uppercase;
  font-size:.75rem}

/* ── project timeline ──
   The one genuinely sequential section on the page, so a time axis is
   information rather than decoration. Bars are shaded by who owns the
   stage, because "where you are the bottleneck" is the actual message. */
.tl{margin-top:2rem}
.tl-key{display:flex;flex-wrap:wrap;gap:1.25rem;padding-bottom:1rem;
  font-size:.8125rem;color:var(--muted)}
.tl-key i{display:inline-block;width:1.5rem;height:.625rem;border-radius:3px;
  margin-right:.5rem;vertical-align:-1px}
.k-us{background:var(--accent)}
.k-you{background:transparent;box-shadow:inset 0 0 0 1.5px var(--accent)}
.tl-grid{border-top:1px solid var(--rule)}
.tl-axis{display:grid;grid-template-columns:minmax(9rem,13rem) repeat(6,1fr);
  gap:0 .375rem;padding:.625rem 0 .5rem;font-size:.75rem;color:var(--muted);
  font-variant-numeric:tabular-nums;border-bottom:1px solid var(--rule)}
.tl-axis span{text-align:center}
.tl-axis span:first-child{text-align:left}
.tl-row{display:grid;grid-template-columns:minmax(9rem,13rem) repeat(6,1fr);
  gap:0 .375rem;align-items:center;padding:.75rem 0;border-bottom:1px solid var(--rule)}
.tl-name{font-weight:600;font-size:.9375rem;letter-spacing:-.015em;padding-right:1rem}
.tl-name span{display:block;max-width:46ch;font-weight:400;font-size:.8125rem;color:var(--muted);
  margin-top:.125rem;letter-spacing:0}
.tl-bar{transform:translateX(-6px);height:1.75rem;border-radius:5px;display:flex;align-items:center;
  padding:0 .625rem;font-size:.75rem;font-weight:500;white-space:nowrap;overflow:hidden}
.b-us{background:var(--accent);color:#fff}
.b-you{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--accent)}
@media(prefers-reduced-motion:no-preference){
  .tl-grid.armed .tl-bar{opacity:0}
  .tl-grid.armed.go .tl-bar{animation:slot var(--t-enter) cubic-bezier(.22,.61,.36,1) forwards}
  .tl-grid.armed.go .tl-row:nth-child(2) .tl-bar{animation-delay:calc(var(--stagger) * 1)}
  .tl-grid.armed.go .tl-row:nth-child(3) .tl-bar{animation-delay:calc(var(--stagger) * 2)}
  .tl-grid.armed.go .tl-row:nth-child(4) .tl-bar{animation-delay:calc(var(--stagger) * 3)}
  .tl-grid.armed.go .tl-row:nth-child(5) .tl-bar{animation-delay:calc(var(--stagger) * 4)}
  .tl-grid.armed.go .tl-row:nth-child(6) .tl-bar{animation-delay:calc(var(--stagger) * 5)}
  .tl-grid.armed.go .tl-row:nth-child(7) .tl-bar{animation-delay:calc(var(--stagger) * 6)}
  @keyframes slot{to{opacity:1;transform:none}}
}
@media(max-width:780px){
  .tl-axis{display:none}
  .tl-row{grid-template-columns:1fr;gap:.5rem;padding:1rem 0}
  /* !important is needed: each bar carries an inline grid-column for the
     week axis, which has to be neutralised once the axis is gone */
  .tl-bar{grid-column:1 / -1 !important;justify-content:space-between;
    height:2rem;padding:0 .75rem}
  .tl-bar::after{content:attr(data-when);font-weight:400;opacity:.85}
}

/* ── price range chart ──
   Each project sits on a shared 0–12k scale, so relative cost is
   readable at a glance. This is the data, not decoration: publishing
   prices openly is the whole positioning. */
.ranges{margin-top:2rem;border-top:1px solid var(--rule)}
@media(prefers-reduced-motion:no-preference){
  /* held at zero until scrolled into view, so the reveal is actually seen */
  .ranges.armed .bar{transform:scaleX(0);transform-origin:left}
  .ranges.armed.go .bar{animation:grow var(--t-enter) cubic-bezier(.22,.61,.36,1) forwards}
  .ranges.armed.go .range:nth-child(2) .bar{animation-delay:calc(var(--stagger) * 1)}
  .ranges.armed.go .range:nth-child(3) .bar{animation-delay:calc(var(--stagger) * 2)}
  .ranges.armed.go .range:nth-child(4) .bar{animation-delay:calc(var(--stagger) * 3)}
  .ranges.armed.go .range:nth-child(5) .bar{animation-delay:calc(var(--stagger) * 4)}
  @keyframes grow{to{transform:scaleX(1)}}
}
@media(max-width:700px){
  .range{grid-template-columns:1fr auto;gap:.5rem 1rem}
}

/* sticky action bar — mobile only, appears once the hero scrolls away */
.dock{
  position:fixed;left:0;right:0;bottom:0;z-index:35;display:none;
  gap:.625rem;padding:.75rem var(--gut);
  padding-bottom:max(.75rem,env(safe-area-inset-bottom));
  background:rgba(251,252,253,.94);backdrop-filter:blur(8px);
  border-top:1px solid var(--rule);
  transform:translateY(105%);transition:transform var(--t-ui) var(--ease);
}
.dock.show{transform:none}
.dock a{flex:1 1 0;min-height:var(--tap);display:inline-flex;align-items:center;
  justify-content:center;border-radius:3px;font:500 .9375rem "Google Sans Flex","Sans Fallback",system-ui,sans-serif}
.dock .p{background:var(--accent);color:#fff;border:1px solid var(--accent)}
.dock .p:hover{background:var(--accent-dark);text-decoration:none;color:#fff}
.dock .s{color:var(--ink);border:1px solid var(--rule);background:var(--paper)}
.dock .s:hover{border-color:var(--ink);text-decoration:none}
@media(max-width:760px){
  .dock{display:flex;bottom:0}
  body.cc-on .dock{display:none}
  body{padding-bottom:5rem}
  body.cc-on{padding-bottom:calc(var(--cc-h,190px) + 7rem)}
}
@media(prefers-reduced-motion:reduce){.dock{transition:none}}

/* mailto hint — tells people an email app will open */
.mailto-hint{color:var(--muted);font-size:.8125rem;white-space:nowrap;margin-left:.375rem}

/* landscape phones: trim vertical padding, unstick header */
@media(max-height:520px) and (orientation:landscape){
  .hero{padding-block:2rem}
  .masthead{position:static}
}

/* ── back to top ──
   Sits clear of the sticky action bar and the cookie banner rather than
   stacking on top of them. Only appears once there is something to go
   back to. */
.top{
  position:fixed;right:var(--gut);z-index:36;
  bottom:calc(1.25rem + var(--dock-h,0px) + env(safe-area-inset-bottom));
  width:2.75rem;height:2.75rem;display:grid;place-items:center;
  background:var(--paper);color:var(--ink);
  border:1px solid var(--rule);border-radius:8px;box-shadow:var(--lift);
  cursor:pointer;opacity:0;pointer-events:none;transform:translateY(6px);
  transition:opacity var(--t-ui) var(--ease-ui),transform var(--t-ui) var(--ease-ui),border-color var(--t-fast) var(--ease-ui);
}
.top.show{opacity:1;pointer-events:auto;transform:none}
.top:hover{border-color:var(--ink)}
.top svg{display:block}
@media(prefers-reduced-motion:reduce){.top{transition:none}}
@media print{.top{display:none !important}}

/* inline links in running text keep their underline in monochrome */
.trader a,.drawer-mail a,.foot-base a{text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;
  text-decoration-color:rgba(11,122,62,.5)}
.trader a:hover,.drawer-mail a:hover,.foot-base a:hover{
  text-decoration-color:var(--ink);text-decoration-thickness:2px}



/* ── section imagery ──
   Illustrative, not portfolio: these are conceptual images, so nothing
   here is captioned or framed as client work. WebP with a JPEG fallback,
   explicit dimensions so nothing shifts as they load, and lazy loading
   below the fold. */
.shot{display:block;position:relative;margin:0;border-radius:12px;overflow:hidden;
  border:1px solid var(--rule);background:var(--wash);
  box-shadow:0 1px 2px rgba(16,24,40,.05), 0 14px 32px -16px rgba(16,24,40,.18)}
.shot img{display:block;width:100%;height:auto;aspect-ratio:2.35}
.band-dark .shot{border-color:var(--rule);box-shadow:0 2px 6px rgba(0,0,0,.5), 0 22px 44px -20px rgba(0,0,0,.85)}

/* a wide image sitting under a section's content */
.shot-wide{margin-top:clamp(1.75rem,3vw,2.5rem)}
.with-shot > .shot{position:sticky;top:6rem}
@media(max-width:900px){
  .with-shot{grid-template-columns:1fr}
  .with-shot > .shot{position:static;order:-1}
}
@media(prefers-reduced-motion:no-preference){
  .shot img{transition:transform 700ms var(--ease)}
  .shot:hover img{transform:scale(1.03)}
}