/* ============================================================
   Adagrad IT / Site 2: "Arc"

   One continuous scroll journey that starts in near-black and
   resolves into the studio's warm paper white by the time the
   visitor reaches the form. The dark is a starting point, not
   a style: it exists so the arrival into light means something.

   Reference studied: wearebrand.io/brand (camera push from a
   dark porthole down to a lit Earth). Borrowed: the continuous
   scrubbed camera, the pinned single CTA, the absent nav, type
   set over the scene rather than beside it. Not borrowed: the
   space imagery, the gradients, the glass.

   Palette is the studio's own. Teal is rationed hard: it is the
   filament, the active tab, and the submit button. Nothing else.
   ============================================================ */

:root{
  /* the arc: act 1 to act 5 */
  --void:#1e222b;
  --void-2:#2a2f3a;
  --paper:#fbfaf8;
  --paper-2:#f4f2ee;
  /* where the travelling ground stops. Short of paper on purpose: full
     white after that much dark is hard on the eyes. Mirrors LANDING in
     journey.js, which is the only other place this value exists. */
  --landing:#e7e4dd;

  --ink:#101014;
  --ink-soft:#4a4a52;
  /* #86868f, carried over from the incumbent stylesheet, computed 3.17:1 and
     failed AA. Darkened once to #6b6b75, then again to #63636d when the scene
     was capped short of full white: dropping the ground from #fbfaf8 to
     #e7e4dd took #6b6b75 from 5.05:1 to 4.15:1 and back under AA. Now 4.68:1
     on the landing tone and 5.31:1 on the form card.
     Same reasoning for --light-dim below (2.95:1 to 6.1:1). */
  --ink-dim:#63636d;

  --light:#f2f2f5;
  --light-soft:#a8a8b4;
  --light-dim:#8f8f9c;

  --accent:#00c2a8;          /* the adagradit.com teal */
  --accent-ink:#00594e;      /* teal that reads as text on paper */
  --accent-glow:rgba(0,194,168,.34);

  --rule-dark:rgba(255,255,255,.11);
  --rule-light:#e4e1db;

  --maxw:1180px;
  --r:3px;

  --sans:"Inter",system-ui,-apple-system,sans-serif;
  --display:"Space Grotesk",var(--sans);
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --ease:cubic-bezier(.22,1,.36,1);
}

*{box-sizing:border-box;margin:0;padding:0;}
html{
  scroll-behavior:smooth;
  /* the journey is long on purpose: the scene needs runway to travel */
  background:var(--void);
}
body{
  font-family:var(--sans);
  background:transparent;
  color:var(--light);
  line-height:1.55;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
a{color:inherit;text-decoration:none;}
ul{list-style:none;}
img,svg{display:block;max-width:100%;}
button{font-family:inherit;cursor:pointer;border:0;background:none;color:inherit;}
::selection{background:var(--accent);color:#04120f;}

/* ---------- the scene sits behind everything, permanently ---------- */
#scene{
  position:fixed;
  inset:0;
  width:100%;
  height:100%;
  z-index:0;
  display:block;
  pointer-events:none;
}

/* ---------- persistent chrome: no nav, by decision ---------- */
.chrome{
  position:fixed;
  top:0;left:0;right:0;
  z-index:40;
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:22px clamp(18px,4vw,44px);
  mix-blend-mode:normal;
  transition:color .5s var(--ease),opacity .35s var(--ease),transform .35s var(--ease);
}
/* The chrome has no ground of its own, which is right for four acts and
   wrong for the fifth: over the form it landed straight on top of the
   first field label. It leaves with the pinned pill. */
body.at-form .chrome{opacity:0;pointer-events:none;transform:translateY(-12px);}
.brand{display:flex;align-items:center;gap:11px;font-family:var(--display);font-weight:700;letter-spacing:-.03em;font-size:19px;}
.brand .tile{
  width:30px;height:30px;border-radius:7px;
  background:var(--accent);
  display:grid;place-items:center;
  flex:none;
}
.brand .tile svg{width:17px;height:17px;}
.brand .it{color:var(--accent);}
.chrome-right{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.12em;
  text-transform:uppercase;
  opacity:.72;
  transition:opacity .3s;
}
@media (hover:hover) and (pointer:fine){.chrome-right:hover{opacity:1;}}

/* The CTA that never leaves. This is the whole navigation.

   Bottom right rather than bottom centre: wearebrand can centre theirs
   because their pages are a single screen with nothing beneath the fold.
   Ours has live copy running down the left column the whole way, and a
   centred pill sat straight on top of it. */
.cta-pin{
  position:fixed;
  right:clamp(18px,4vw,44px);
  bottom:clamp(20px,4vh,34px);
  z-index:45;
  display:inline-flex;
  align-items:center;
  gap:12px;
  padding:15px 26px;
  border-radius:999px;
  background:var(--light);
  color:var(--ink);
  font-weight:600;
  font-size:15px;
  letter-spacing:-.01em;
  white-space:nowrap;
  box-shadow:0 2px 0 rgba(0,0,0,.18);
  transition:transform .18s var(--ease),background .4s var(--ease),color .4s var(--ease),opacity .25s var(--ease);
}
@media (hover:hover) and (pointer:fine){.cta-pin:hover{transform:translateY(-3px);}}
.cta-pin:active{transform:scale(.97);}
.cta-pin .arrow{
  width:26px;height:26px;border-radius:50%;
  background:var(--accent);
  display:grid;place-items:center;
  flex:none;
  color:#04120f;
  font-size:13px;
}
/* once the journey lands in the light, the pill inverts to stay legible */
body.is-light .cta-pin{background:var(--ink);color:var(--light);}
body.is-light .chrome{color:var(--ink);}
body.is-light .brand .it{color:var(--accent-ink);}
/* the pill would sit on top of the form's own submit button */
body.at-form .cta-pin{opacity:0;pointer-events:none;transform:translateY(14px);}

/* ---------- acts ---------- */
main{position:relative;z-index:10;}
.act{
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding:120px clamp(18px,4vw,44px);
  max-width:var(--maxw);
  margin:0 auto;
  width:100%;
}
.act-title{
  font-family:var(--display);
  font-weight:700;
  letter-spacing:-.035em;
  line-height:1.02;
  font-size:clamp(34px,5.4vw,68px);
  margin-bottom:22px;
}
.kicker{
  font-family:var(--mono);
  font-size:11px;
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--light-soft);
  margin-bottom:26px;
  display:flex;
  align-items:center;
  gap:12px;
}
.kicker::after{content:"";height:1px;flex:1;background:var(--rule-dark);max-width:220px;}

/* ---------- act 1: the open ---------- */
.act-open h1{
  font-family:var(--display);
  font-weight:700;
  letter-spacing:-.038em;
  line-height:.92;
  font-size:clamp(58px,13vw,168px);
  margin-bottom:30px;
}
/* The pivot word, in white.

   One word of a headline set in the brand colour is the most reproduced move
   in current SaaS and AI landing pages, which makes it read as a template
   rather than as a choice. It was redundant here too: italic, a 300 weight
   against 700, and a colour change are three signals doing one job. The two
   kept are typographic, so they still work in greyscale, in print, and for
   anyone who cannot separate teal from white.

   Colour is now reserved for what a visitor can act on and for a number that
   indexes a real sequence. Teal means something on this page rather than
   decorating it. */
.act-open h1 .to{
  font-weight:300;
  font-style:italic;
  letter-spacing:-.02em;
}
.lede{
  font-size:clamp(17px,2vw,22px);
  line-height:1.5;
  color:var(--light-soft);
  max-width:36ch;
}

/* ---------- act 2: three ways in (the tabs) ---------- */
.ways{margin-top:26px;}
/* These are controls, not a header row. The old version sat inside a single
   top-and-bottom rule with no boundaries between the three, so it read as a
   heading that happened to have three parts and nobody knew to press it. Now
   each one is a discrete bordered target that lights up when chosen. */
.way-tabs{
  display:flex;
  gap:8px;
  margin-bottom:32px;
  overflow-x:auto;
  scrollbar-width:none;
}
.way-tabs::-webkit-scrollbar{display:none;}
.way-tab{
  flex:1 1 0;
  min-width:150px;
  text-align:left;
  /* Taller than it was. The tab used to hold a number above the title and the
     padding was set for two lines; with one line it needs the height back or
     the control reads as cramped next to everything else on the page. */
  padding:22px 18px;
  display:flex;
  flex-direction:column;
  gap:6px;
  position:relative;
  color:var(--light-dim);
  border:1px solid var(--rule-dark);
  background:transparent;
  transition:color .22s var(--ease),border-color .22s var(--ease),
             background .22s var(--ease),transform .16s var(--ease);
}
.way-tab:active{transform:scale(.99);}
/* Dwell indicator. It sits on the active tab and fills over the dwell time,
   so the strip announces that it is going to move before it moves. */
.way-tab .tprog{
  position:absolute;left:-1px;right:-1px;bottom:-1px;height:3px;
  background:var(--accent);
  transform:scaleX(0);
  transform-origin:left;
  pointer-events:none;
  z-index:2;
}
/* The track. Without it the bar has no length to be measured against, so you
   cannot tell how much time is left, only that something is moving. */
.way-tab[aria-selected="true"]::after{
  content:"";
  position:absolute;left:-1px;right:-1px;bottom:-1px;height:3px;
  background:rgba(255,255,255,.16);
  pointer-events:none;
  z-index:1;
}
/* .n is gone from the markup: three parallel ways in are not a sequence, so
   numbering them said nothing. The rule stays only because the mobile block
   below and the selected state below that would otherwise dangle. */
.way-tab .t{
  font-family:var(--display);
  font-weight:700;
  font-size:clamp(18px,2.2vw,25px);
  letter-spacing:-.025em;
  line-height:1.1;
}
.way-tab[aria-selected="true"]{
  color:var(--light);
  border-color:var(--accent);
  background:rgba(0,194,168,.10);
}
@media (hover:hover) and (pointer:fine){
  .way-tab:hover{color:var(--light);border-color:var(--light-dim);}
}

.way-panel{display:none;}
@keyframes panelIn{
  from{opacity:0;transform:translateY(7px);}
  to{opacity:1;transform:none;}
}
.way-panel.is-on{animation:panelIn .3s var(--ease) both;display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(28px,5vw,72px);align-items:start;}
.way-panel h3{
  font-family:var(--display);
  font-weight:700;
  font-size:clamp(24px,3.4vw,40px);
  letter-spacing:-.032em;
  line-height:1.06;
  margin-bottom:18px;
}
.way-panel p{color:var(--light-soft);font-size:16.5px;max-width:46ch;}
.way-panel p + p{margin-top:14px;}
.way-runs{
  margin-top:20px;
  padding-top:16px;
  border-top:1px solid var(--rule-dark);
}
.way-runs .lbl{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--light-dim);margin-bottom:12px;
}
.way-runs ul{display:flex;flex-wrap:wrap;gap:8px;}
.way-runs li{
  font-family:var(--mono);font-size:12.5px;
  padding:6px 11px;
  border:1px solid var(--rule-dark);
  border-radius:999px;
  color:var(--light-soft);
}
/* the small stepped diagram beside each panel */
.way-steps{display:flex;flex-direction:column;gap:2px;}
.way-step{
  display:flex;align-items:baseline;gap:16px;
  padding:16px 0;
  border-bottom:1px solid var(--rule-dark);
}
.way-step .s-n{font-family:var(--mono);font-size:11px;color:var(--accent);flex:none;width:22px;}
.way-step .s-t{font-weight:600;font-size:15.5px;}
.way-step .s-d{color:var(--light-dim);font-size:14px;margin-left:auto;text-align:right;font-family:var(--mono);}

/* ---------- act 3: the week ---------- */
.act-week .act-title{max-width:16ch;}
.week-note{color:var(--light-soft);font-size:clamp(16px,1.9vw,19px);max-width:48ch;}
.week-cols{
  margin-top:30px;
  display:grid;
  grid-template-columns:1.15fr .85fr;
  gap:clamp(24px,4vw,54px);
  align-items:start;
}
.week-list{display:grid;gap:0;}

/* The desk. It is the only photograph on the page and it carries the whole
   recognition argument, so it gets real size rather than a thumbnail. */
.week-shot{margin:0;position:relative;}
.week-shot img{
  width:100%;
  /* The width/height attributes stay on the tag so the box is reserved before
     the file arrives. A height attribute is a presentational hint that counts
     as a declared height, and aspect-ratio only applies when height is auto,
     so without this line the ratio below was inert: the photo rendered
     441x768 on desktop and 350x768 on mobile, squeezing a landscape source
     into a portrait slot and showing a narrow vertical strip of it. Setting
     auto hands the box back to aspect-ratio without giving up the
     reservation. */
  height:auto;
  /* Portrait, and this is the whole point of the block. The image sits beside
     a 370px list. At 4:3 it rendered 441x331, shorter than the text next to it,
     and a picture that is smaller than the paragraph beside it reads as a
     thumbnail rather than as evidence. At 4:5 it is 441x551 and overhangs the
     list, which is what gives the section its anchor. The phone gets the wide
     crop through <picture> and the ratio below, because down there the image
     stacks and has nothing to balance. */
  aspect-ratio:4/5;
  /* The file is now cropped to 4:3 at source, so cover has nothing left to
     crop and object-position has nothing to position. Cover stays only as a
     guard against a future asset with a different ratio. */
  object-fit:cover;
  /* Top and bottom fade into the ground.

     A MASK, not a dark overlay. The ground under this section is painted by
     the canvas and its colour moves with scroll, so an overlay would only
     match at one scroll position and band at every other. Fading the image's
     own alpha reveals whatever is actually behind it, which is right at every
     point in the arc and in the light state as well.

     Replaces a radial vignette whose radii were measured from the centre:
     112% put the entire falloff outside a 441px frame, so it rendered 100%
     opaque at the left edge and 90% at the other three. It was doing nothing.

     Vertical only. The left and right edges stay hard because the image sits
     in a column beside the list and a soft vertical edge there would read as
     a rendering fault rather than as a choice. The stops are asymmetric: the
     top has wall and the top of the screen, which can afford to go early,
     while the bottom holds the paper stack and the mug, so it holds longer
     and fades faster. */
  -webkit-mask-image:linear-gradient(to bottom,
    transparent 0%, rgba(0,0,0,.55) 7%, #000 20%,
    #000 86%, rgba(0,0,0,.6) 95%, transparent 100%);
  mask-image:linear-gradient(to bottom,
    transparent 0%, rgba(0,0,0,.55) 7%, #000 20%,
    #000 86%, rgba(0,0,0,.6) 95%, transparent 100%);
}
.week-item{
  display:flex;align-items:baseline;gap:clamp(14px,3vw,30px);
  padding:20px 0;border-top:1px solid var(--rule-dark);
}
.week-item:last-child{border-bottom:1px solid var(--rule-dark);}
.week-item .w-when{
  font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--light-dim);flex:none;width:96px;
}
.week-item .w-what{font-size:16.5px;color:var(--light);}
.week-item .w-what em{font-style:normal;color:var(--accent);}

/* ---------- act 4: method ---------- */
.method-grid{
  margin-top:30px;
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:0;
  background:transparent;
  border:1px solid var(--rule-dark);
}
.method-cell{
  /* Not transparent, and not the opaque fill it used to be. This block sits
     exactly where the scene is mid-grey on its way to the landing tone, and
     on that ground --light-soft measured 1.46:1. A 66% scrim keeps the metal
     and the cursor bubble visible through it while putting the body copy back
     at 4.72:1. Fully clear looks better in a screenshot and cannot be read. */
  background:rgba(16,19,26,.66);
  border-left:1px solid var(--rule-dark);
  padding:26px 22px 30px;
}
.method-cell:first-child{border-left:0;}
.method-cell .m-n{font-family:var(--mono);font-size:11px;color:var(--accent);letter-spacing:.16em;}
.method-cell h3{
  font-family:var(--display);font-weight:700;font-size:21px;letter-spacing:-.025em;
  margin:14px 0 10px;
}
.method-cell p{color:var(--light-soft);font-size:14.5px;line-height:1.5;}
.method-cell .m-meta{
  margin-top:18px;padding-top:14px;border-top:1px solid var(--rule-dark);
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--light-soft);   /* --light-dim was 3.48:1 on the scrim */
}

/* ---------- act 5: the landing, in light ---------- */
.act-start{
  color:var(--ink);
  min-height:auto;
  padding-bottom:90px;
  position:relative;
  /* This section is the one place on the site where the type inverts, and it
     used to paint its own opaque light ground. Making the texture translucent
     so the filament could pass through took that guarantee away with it: the
     light ground here comes from the canvas, and with JavaScript off the
     canvas never paints, leaving #101014 type on the void at 1.2:1.

     So the landing tone is the default and the transparent version is the
     enhancement. journey.js sets .has-scene on <html> only once it has a 2d
     context in hand, which is the only moment the canvas can be relied on. */
  background-color:var(--landing);
}
html.has-scene .act-start{background-color:transparent;}
/* The arrival, as a translucent layer rather than an opaque background.

   The texture used to paint directly on the section, which sealed the canvas
   off completely: the filament travels the entire page and then hit a wall at
   the one section that matters most, so the form read as a separate document
   pasted over the end of the journey. At 34% the wall is gone and the lines
   carry through underneath, still faint enough that nothing crosses the type.

   The tint gradient went with it. The canvas is already sitting on the landing
   tone here, so a second copy of that colour was only hiding the first.

   The url is relative to THIS FILE, not to the page that links it. From css/
   the assets are two levels up; ../_assets resolved to site-2-arc/_assets,
   which does not exist, and this texture 404ed from the day it was written. */
.act-start::before{
  content:"";
  position:absolute;
  inset:0;
  background-image:url("../assets/arrival-light.jpg");
  background-size:cover;
  background-position:center 30%;
  background-repeat:no-repeat;
  opacity:.34;
  pointer-events:none;
}
/* Positioned layers paint above static content, so the section's own children
   need a stacking position of their own or the texture covers the form. */
.act-start > *{position:relative;z-index:1;}

.act-start .kicker{color:var(--ink-dim);}
.act-start .kicker::after{background:var(--rule-light);}
.act-start .act-title{max-width:14ch;}
.act-start .lede{color:var(--ink-soft);max-width:44ch;margin-bottom:8px;}
.start-grid{
  margin-top:32px;
  display:grid;
  grid-template-columns:.85fr 1.15fr;
  gap:clamp(30px,5vw,70px);
  align-items:start;
}
.start-facts{display:grid;gap:0;}
.start-fact{padding:18px 0;border-top:1px solid var(--rule-light);}
.start-fact:last-child{border-bottom:1px solid var(--rule-light);}
.start-fact .f-l{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-dim);margin-bottom:6px;
}
.start-fact .f-v{font-size:16px;color:var(--ink);}
.start-fact a{border-bottom:1px solid var(--accent);}

/* the form, modelled on the wearebrand contact card: chips first, fields after */
.form-card{
  background:var(--paper-2);
  border:1px solid var(--rule-light);
  border-radius:var(--r);
  padding:clamp(22px,3.4vw,38px);
}
.form-card .f-head{
  font-family:var(--sans);font-size:15px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink);margin-bottom:16px;
}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:26px;}
.chip{
  padding:9px 15px;
  transition:transform .16s var(--ease);
  border:1px solid var(--rule-light);
  border-radius:999px;
  background:var(--paper);
  font-size:13.5px;
  color:var(--ink-soft);
  transition:border-color .25s,color .25s,background .25s;
}
@media (hover:hover) and (pointer:fine){.chip:hover{border-color:var(--ink-dim);color:var(--ink);}}
.chip:active{transform:scale(.97);}
.chip[aria-pressed="true"]{
  background:var(--ink);border-color:var(--ink);color:var(--paper);
}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px;}
.field{display:flex;flex-direction:column;gap:7px;}
.field label{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-dim);
}
.field input,.field textarea,.field select{
  font-family:inherit;font-size:15px;color:var(--ink);
  background:var(--paper);
  border:1px solid var(--rule-light);
  border-radius:var(--r);
  padding:13px 14px;
  width:100%;
  transition:border-color .2s;
}
.field textarea{resize:vertical;min-height:118px;line-height:1.5;}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-dim);opacity:1;}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--accent-ink);
}
.submit{
  margin-top:20px;
  width:100%;
  padding:16px 22px;
  background:var(--accent);
  color:#04120f;
  border-radius:var(--r);
  font-weight:700;
  font-size:15.5px;
  letter-spacing:-.01em;
  transition:background .25s,transform .25s var(--ease);
}
@media (hover:hover) and (pointer:fine){.submit:hover{background:#00d9bb;transform:translateY(-2px);}}
.submit:active{transform:scale(.985);}
.submit[disabled]{
  cursor:default;
  background:var(--accent-ink);
  color:var(--paper);
  animation:sending 1.1s ease-in-out infinite;
}
.submit[disabled]:active{transform:none;}
@keyframes sending{0%,100%{opacity:1}50%{opacity:.72}}
.form-note{margin-top:14px;font-size:13px;color:var(--ink-dim);}
.hp-field{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;}

/* ---------- footer ---------- */
.foot{
  position:relative;z-index:10;
  color:var(--ink-soft);
  border-top:1px solid var(--rule-light);
  padding:34px clamp(18px,4vw,44px) 46px;
  max-width:var(--maxw);
  margin:0 auto;
  display:flex;
  flex-wrap:wrap;
  gap:18px 34px;
  align-items:center;
  font-size:13.5px;
}
.foot .f-brand{font-family:var(--display);font-weight:700;color:var(--ink);letter-spacing:-.02em;}
.foot nav{display:flex;gap:20px;flex-wrap:wrap;margin-left:auto;}
.foot nav a{border-bottom:1px solid transparent;transition:border-color .2s;}
@media (hover:hover) and (pointer:fine){.foot nav a:hover{border-bottom-color:var(--ink-dim);}}

/* focus visibility, since nothing here has been audited yet */
a:focus-visible,button:focus-visible,input:focus-visible,
textarea:focus-visible,select:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:2px;
}

/* ============================================================
   Responsive. Written mobile-considered rather than mobile-last:
   the incumbent site's phone layout is the thing being fixed.
   ============================================================ */
@media (max-width:900px){
  .way-panel.is-on{grid-template-columns:1fr;gap:32px;}
  .method-grid{grid-template-columns:repeat(2,1fr);}
  .start-grid{grid-template-columns:1fr;}
}

@media (max-width:640px){
  .act{padding:44px 20px 88px;min-height:auto;}
  .act-open{min-height:82vh;justify-content:flex-end;padding-bottom:88px;}
  .act-open h1{font-size:clamp(52px,17vw,86px);line-height:.94;}
  .lede{max-width:none;font-size:17px;}
  
  /* On a phone the pinned pill is the element that has to persist, not the
     logo. Fixed, the logo has no ground of its own and lands on top of
     whatever copy is passing underneath it. Let it scroll away instead. */
  .chrome{padding:16px 20px;position:absolute;}
  .chrome-right{display:none;}          /* an email string is unreadable at this size */
  .brand{font-size:17px;}

  /* the pill is the only navigation, so it gets real width on a phone */
  .cta-pin{
    left:20px;right:20px;
    transform:none;
    justify-content:center;
    bottom:18px;
    padding:16px 22px;
  }
  @media (hover:hover) and (pointer:fine){.cta-pin:hover{transform:translateY(-3px);}}
.cta-pin:active{transform:scale(.97);}
  body.at-form .cta-pin{transform:translateY(14px);}

  /* All three fit, or none of them do. A horizontal scroll strip clipped the
     third tab mid-word with nothing to say it was there, which is the exact
     defect this rebuild is meant to fix on the incumbent site. Three equal
     columns, smaller type, no scrolling. */
  .way-tabs{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:6px;
    overflow:visible;
  }
  .way-tab{min-width:0;padding:11px 10px;gap:4px;}
  .way-tab .t{font-size:14px;line-height:1.15;letter-spacing:-.02em;}

  .week-item{flex-direction:column;gap:4px;padding:14px 0;}
  .week-cols{grid-template-columns:1fr;gap:20px;}
  .week-shot img{aspect-ratio:4/3;}   /* the wide crop, via <picture> */
  .week-item .w-when{width:auto;}

  .method-grid{grid-template-columns:1fr 1fr;}
  .method-cell:nth-child(3){border-left:0;}
  .method-cell:nth-child(n+3){border-top:1px solid var(--rule-dark);}
  .method-cell{padding:18px 15px 22px;}
  .method-cell h3{font-size:18px;margin:10px 0 8px;}
  .method-cell p{font-size:13.5px;}
  .method-cell .m-meta{margin-top:12px;padding-top:10px;}
  .field-row{grid-template-columns:1fr;}
  .foot{flex-direction:column;align-items:flex-start;}
  .foot nav{margin-left:0;}
}

/* Anyone who asks for less motion gets the whole page, statically, at once. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
    *{transition-duration:.01ms !important;animation-duration:.01ms !important;}
}


/* ============================================================
   SUB PAGES  (/agent, /website, /workflow, /stories, /pricing, /about)

   Same scene, same arc, same form. journey.js needs nothing new:
   it guards on every selector and only requires #start to exist,
   so the ground still travels dark to light and lands on the form
   exactly as it does on the landing page.

   The one structural difference is the open. A sub page arrived at
   from search has to say what it is inside a viewport, so it gets a
   shorter hero than the landing page's full screen.
   ============================================================ */

.page-open{min-height:auto;padding-top:clamp(96px,16vh,150px);padding-bottom:clamp(40px,7vh,72px);}
.page-open h1{
  font-family:var(--display);font-weight:700;
  font-size:clamp(40px,7.6vw,96px);
  letter-spacing:-.038em;line-height:.96;margin-bottom:24px;
}
/* Same reasoning as .act-open h1 .to above. */
.page-open h1 .to{font-weight:300;font-style:italic;letter-spacing:-.02em;}

/* ---------- hairline rows: the reusable list on every sub page ---------- */
.rows{margin-top:26px;border-top:1px solid var(--rule-dark);}
.row-item{
  display:grid;grid-template-columns:60px 1fr 1.25fr;
  gap:clamp(12px,3vw,36px);align-items:start;
  padding:22px 0;border-bottom:1px solid var(--rule-dark);
}
.row-item .r-n{font-family:var(--mono);font-size:11px;letter-spacing:.16em;color:var(--accent);padding-top:5px;}

/* Rows with no index.

   A number beside a heading is structure only when the order is information.
   Trigger, Reason, Act, Report is a sequence and keeps its numbers. Seven
   things you get, six things that change a price and five ways we work are
   lists, and numbering a list is a page numbering its own chapters: it looks
   like hierarchy without adding any.

   The number column is removed rather than hidden, so the heading starts at
   the rule and the measure gets the width back. */
.rows--plain .row-item{grid-template-columns:1fr 1.25fr;}
.row-item h3{font-family:var(--display);font-weight:700;font-size:clamp(18px,2vw,24px);letter-spacing:-.028em;}
.row-item p{color:var(--light-soft);font-size:15.5px;}
.row-item .r-meta{font-family:var(--mono);font-size:12.5px;color:var(--light-dim);margin-top:8px;}

/* ---------- "sounds like you if" ---------- */
.shapes{margin-top:24px;display:grid;gap:0;max-width:760px;}
.shape{
  padding:16px 0;border-top:1px solid var(--rule-dark);
  font-size:clamp(16px,1.8vw,19px);color:var(--light);
}
.shape:last-child{border-bottom:1px solid var(--rule-dark);}
.shape em{font-style:normal;color:var(--accent);}

/* ---------- the boundary: what it can and cannot reach ----------
   Two columns that read against each other. This is the block worth
   coming to the page for, so it gets the only fill on the page. */
.boundary{
  margin-top:30px;display:grid;grid-template-columns:1fr 1fr;
  gap:0;border:1px solid var(--rule-dark);
}
.boundary > div{background:rgba(16,19,26,.66);padding:clamp(20px,2.6vw,30px);}
.boundary > div + div{border-left:1px solid var(--rule-dark);}
.boundary h3{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:16px;
}
.boundary .can h3{color:var(--accent);}
.boundary .cant h3{color:var(--light-soft);}
.boundary li{
  padding:11px 0;border-top:1px solid var(--rule-dark);
  font-size:15px;color:var(--light-soft);
}
.boundary li:first-of-type{border-top:0;padding-top:0;}

/* ---------- what we will not do ---------- */
.wont{margin-top:26px;max-width:720px;}
.wont li{
  padding:13px 0;border-top:1px solid var(--rule-dark);
  font-size:16px;color:var(--light);
}
.wont li:last-child{border-bottom:1px solid var(--rule-dark);}

/* ---------- onward: the other ways, and stories ---------- */
.onward{
  margin-top:30px;display:grid;grid-template-columns:repeat(3,1fr);
  gap:8px;
}
.onward a{
  border:1px solid var(--rule-dark);padding:18px 20px;
  display:flex;flex-direction:column;gap:6px;
  transition:border-color .22s var(--ease),background .22s var(--ease),transform .16s var(--ease);
}
.onward a .o-l{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--light-dim);}
.onward a .o-t{font-family:var(--display);font-weight:700;font-size:clamp(17px,2vw,21px);letter-spacing:-.025em;}
@media (hover:hover) and (pointer:fine){
  .onward a:hover{border-color:var(--accent);background:rgba(0,194,168,.08);}
}
.onward a:active{transform:scale(.99);}

@media (max-width:900px){
  .row-item{grid-template-columns:44px 1fr;}
  .row-item > div{grid-column:2;}
  .rows--plain .row-item{grid-template-columns:1fr;}
  .rows--plain .row-item > div{grid-column:1;}
  .boundary{grid-template-columns:1fr;}
  .boundary > div + div{border-left:0;border-top:1px solid var(--rule-dark);}
  .onward{grid-template-columns:1fr;}
}
@media (max-width:640px){
  .page-open{padding-top:78px;padding-bottom:30px;}
  .page-open h1{font-size:clamp(36px,11vw,54px);}
  .row-item{padding:16px 0;}
  .row-item p{font-size:14.5px;}
}


/* ============================================================
   THE FLIP

   body.is-light was only ever restyling the chrome and the pinned
   pill. Everything else kept its dark-ground colours, so any block
   that happened to sit in the last stretch before the form went
   light-on-light and effectively disappeared. It showed up first on
   /agent, where the page is shorter and the onward block lands
   right in the transition.

   Blocks that carry their OWN dark ground are deliberately excluded
   below: .boundary and .method-cell keep a 66% scrim precisely so
   the arc can pass over them, and their text has to stay light.
   ============================================================ */

body.is-light .act-title,
body.is-light .page-open h1,
body.is-light .row-item h3,
body.is-light .shape,
body.is-light .wont li,
body.is-light .onward a .o-t{color:var(--ink);}

body.is-light .lede,
body.is-light .week-note,
body.is-light .row-item p{color:var(--ink-soft);}

body.is-light .kicker,
body.is-light .row-item .r-meta,
body.is-light .onward a .o-l,
body.is-light .week-item .w-when{color:var(--ink-dim);}

body.is-light .rows,
body.is-light .row-item,
body.is-light .shape,
body.is-light .wont li,
body.is-light .onward a,
body.is-light .week-list,
body.is-light .week-item{border-color:var(--rule-light);}

body.is-light .kicker::after{background:var(--rule-light);}
body.is-light .week-item .w-what{color:var(--ink);}
body.is-light .way-runs li{color:var(--ink-soft);border-color:var(--rule-light);}
body.is-light .way-runs .lbl{color:var(--ink-dim);}

/* The scene is teal on dark and teal-ink on light, so accents follow. */
body.is-light .row-item .r-n,
body.is-light .shape em,
body.is-light .week-item .w-what em{color:var(--accent-ink);}

/* Transitions so the flip is a change of light, not a snap. */
.act-title,.page-open h1,.lede,.week-note,.kicker,
.shape,.wont li,.row-item h3,.row-item p,.onward a,
.week-item .w-when,.week-item .w-what{
  transition:color .5s var(--ease),border-color .5s var(--ease);
}


/* ---------- a panel that carries its own ground ----------
   Same 66% scrim as .boundary and .method-cell, so it stays readable
   wherever the arc happens to be when it scrolls past. Used for the
   one block on /stories that has to be impossible to miss. */
.panel{
  margin-top:28px;
  background:rgba(16,19,26,.66);
  border:1px solid var(--rule-dark);
  padding:clamp(22px,3vw,34px);
  max-width:760px;
}
.panel h3{
  font-family:var(--display);font-weight:700;
  font-size:clamp(20px,2.4vw,28px);letter-spacing:-.03em;margin-bottom:14px;
}
.panel p{color:var(--light-soft);font-size:16px;}
.panel p + p{margin-top:12px;}


/* ---------- read-more, from a landing tab into its depth page ---------- */
.more-link{
  display:inline-flex;align-items:center;gap:9px;
  margin-top:20px;font-weight:600;font-size:15px;letter-spacing:-.01em;
  border-bottom:1px solid var(--accent);padding-bottom:3px;
  transition:gap .2s var(--ease),color .2s var(--ease);
}
.more-link .a{color:var(--accent);}
@media (hover:hover) and (pointer:fine){.more-link:hover{gap:14px;}}
body.is-light .more-link{border-bottom-color:var(--accent-ink);}
body.is-light .more-link .a{color:var(--accent-ink);}


/* ---------- pricing tiers ---------- */
.tiers{
  margin-top:28px;display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  border:1px solid var(--rule-dark);
}
.tier{
  background:rgba(16,19,26,.66);
  padding:clamp(22px,2.6vw,32px);
  display:flex;flex-direction:column;
}
.tier + .tier{border-left:1px solid var(--rule-dark);}
.tier .t-l{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--light-dim);margin-bottom:14px;display:flex;align-items:center;gap:10px;
}
.tier .t-l .flag{
  color:var(--accent);border:1px solid var(--accent);
  padding:2px 7px;letter-spacing:.1em;
}
.tier h3{
  font-family:var(--display);font-weight:700;
  font-size:clamp(21px,2.4vw,28px);letter-spacing:-.03em;margin-bottom:8px;
}
.tier .t-sub{color:var(--light-soft);font-size:15.5px;margin-bottom:18px;}
.tier ul{margin-top:auto;}
.tier li{
  padding:10px 0;border-top:1px solid var(--rule-dark);
  font-size:14.5px;color:var(--light-soft);
}

@media (max-width:900px){
  .tiers{grid-template-columns:1fr;}
  .tier + .tier{border-left:0;border-top:1px solid var(--rule-dark);}
}


/* ============================================================
   THE TWO ENDS  (/thanks and /404)

   Every other page travels: dark at the top, paper by the form.
   These two do not travel, and they sit at opposite ends of that
   same arc rather than inventing a third look.

   /thanks opens already landed. Sending the form IS the arrival,
   so the page has nothing left to travel toward. It carries
   id="start", which is all journey.js needs to resolve arrival to
   1 on the first frame.

   /404 never leaves the void. There is no #start on it, so arrival
   stays 0 and the ground holds its opening dark. Being lost is the
   one state on this site the dark is actually describing.
   ============================================================ */

/* The canvas paints on the first animation frame, one frame after the
   document does. Without this the landed page shows a dark flash first,
   because html's own background is the void. Matches LANDING in journey.js. */
html.landed{background:var(--landing);}

/* at-form fires immediately on /thanks, since the section it watches is
   at the top of the page. There is no pinned pill here to compete with,
   so the only thing it would achieve is hiding the way back. */
body.terminus.at-form .chrome{opacity:1;pointer-events:auto;transform:none;}

/* The footer is coloured for the arrival, because on every travelling page
   that is where it sits. On /404 the ground is still void underneath it. */
.foot--void{color:var(--light-soft);border-top-color:var(--rule-dark);}
.foot--void .f-brand{color:var(--light);}
@media (hover:hover) and (pointer:fine){
  .foot--void nav a:hover{border-bottom-color:var(--light-dim);}
}


/* ---------- contact details ----------
   The address is published as a label rather than a mailto. Clicking it
   opens the form, which is where a reply actually gets picked up; a mail
   client hands the enquiry to whichever account the browser happens to be
   configured with, and half the time that is nothing at all. The phone
   number is the one thing here that should bypass the form entirely, so
   it dials. */
.f-tel{border-bottom:1px solid transparent;transition:border-color .2s;font-variant-numeric:tabular-nums;}
@media (hover:hover) and (pointer:fine){.f-tel:hover{border-bottom-color:var(--ink-dim);}}
.foot--void .f-tel{color:var(--light-soft);}
@media (hover:hover) and (pointer:fine){.foot--void .f-tel:hover{border-bottom-color:var(--light-dim);}}

.start-fact .f-v .f-alt{color:var(--ink-soft);}
.start-fact .f-v a[href^="tel:"]{font-variant-numeric:tabular-nums;}


/* ============================================================
   VOICES  (named work on /stories)

   A horizontal carousel that scrolls and never rotates. No timer: nothing
   moves unless a person moves it. Native overflow scrolling does the work,
   so swipe, trackpad, shift-wheel and arrow keys all function before a line
   of JavaScript runs; the two buttons are a convenience on top of that,
   not the mechanism.

   The cards carry the same 66% scrim as .panel, .tier and .boundary. That
   is the whole reason this reads as built rather than as text left on the
   page: everywhere else on the site a block that matters sits on its own
   ground, and these are the only content a visitor can independently check.
   ============================================================ */
.voice-rail{
  margin-top:30px;
  /* Bleed to the viewport edge so a card can sit half off screen. A track
     that stops neatly inside the column looks finished, which is exactly
     wrong: the cut card is what tells you there is more to scroll. */
  margin-right:calc(-1 * clamp(18px,4vw,44px));
}
.voice-track{
  display:flex;
  gap:clamp(14px,1.8vw,22px);
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  padding:2px clamp(18px,4vw,44px) 2px 0;   /* room for the focus ring */
  /* The scrollbar is noise here: the peeking card and the arrows say the
     same thing, and on a dark ground a light scrollbar reads as a misplaced
     rule. Scrolling itself is untouched. */
  scrollbar-width:none;
  -ms-overflow-style:none;
}
.voice-track::-webkit-scrollbar{display:none;}
.voice-track:focus-visible{outline:2px solid var(--accent);outline-offset:4px;}

.voice{
  /* A fraction of the rail rather than a fixed width, so two cards very
     nearly fill a desktop track instead of huddling at the left with dead
     space beside them. The 520 ceiling keeps the measure readable, and the
     moment a third client is added the row overflows, the peek appears and
     the arrows switch themselves on. */
  flex:0 0 clamp(300px,46%,520px);
  scroll-snap-align:start;
  background:rgba(16,19,26,.66);
  border:1px solid var(--rule-dark);
  padding:clamp(22px,2.6vw,30px);
  /* Column flex plus margin-top:auto on the credit drops every attribution
     to the same baseline whatever the quote length. Ragged credits across a
     row of cards read as a layout accident. */
  display:flex;
  flex-direction:column;
}
.voice .v-q{
  font-family:var(--display);
  font-weight:300;
  font-size:clamp(18px,1.9vw,23px);
  /* Display type normally wants tighter leading, but a quotation runs to
     several lines, so it is a reading block that happens to be set large. */
  line-height:1.36;
  letter-spacing:-.022em;
  color:var(--light);
}
/* Quotation marks are opt-in via `is-quote`, since an entry can carry a
   description of the work instead of a client's words. Hung into the margin
   so the first letter still lines up with the card rather than being pushed
   in by the punctuation. */
.voice.is-quote .v-q::before{content:"\201C";margin-left:-.4em;}
.voice.is-quote .v-q::after{content:"\201D";}

/* Answers "what is this about" for anyone who reads the quote without
   knowing what was built. */
.voice .v-what{
  margin-top:14px;
  font-size:14.5px;
  color:var(--light-soft);
}
.voice .v-by{
  margin-top:auto;
  padding-top:20px;
  display:flex;
  flex-direction:column;
  gap:5px;
  font-family:var(--mono);
  font-size:12.5px;
}
/* Tracking rides on the uppercase name only. Applied to the whole line it
   loosened lowercase mono that did not need it. */
.voice .v-who{color:var(--accent);text-transform:uppercase;letter-spacing:.08em;}
.voice .v-org{color:var(--light-dim);}
/* The link carries the credibility of the whole card, so it is underlined
   rather than left to colour alone: colour on its own is not an affordance. */
.voice .v-link{
  align-self:flex-start;
  margin-top:3px;
  color:var(--light);
  border-bottom:1px solid var(--rule-dark);
  padding-bottom:2px;
  transition:border-color .2s var(--ease),color .2s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .voice .v-link:hover{color:var(--accent);border-bottom-color:var(--accent);}
}

/* ---- the arrows ----
   Square, hairline, the same weight as the rest of the furniture. They go
   quiet rather than vanishing at the ends of the track, so the control never
   changes shape under the cursor. */
.voice-nav{margin-top:22px;display:flex;gap:8px;}
.v-arrow{
  width:46px;height:46px;
  display:grid;place-items:center;
  border:1px solid var(--rule-dark);
  color:var(--light);
  font-size:16px;
  transition:border-color .2s var(--ease),background .2s var(--ease),
             color .2s var(--ease),opacity .2s var(--ease),transform .16s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .v-arrow:not([disabled]):hover{border-color:var(--accent);background:rgba(0,194,168,.08);}
}
.v-arrow:not([disabled]):active{transform:scale(.96);}
.v-arrow[disabled]{opacity:.32;cursor:default;color:var(--light-dim);}
/* The whole control is pointless when everything already fits. */
.voice-nav[hidden]{display:none;}

/* The arc can reach this section on a short viewport, same as every other
   block on a sub page. The cards carry their own dark ground, so their text
   stays light and only the furniture around them flips. */
body.is-light .v-arrow{border-color:var(--rule-light);color:var(--ink);}
body.is-light .v-arrow[disabled]{color:var(--ink-dim);}
@media (hover:hover) and (pointer:fine){
  body.is-light .v-arrow:not([disabled]):hover{border-color:var(--accent-ink);background:rgba(0,194,168,.1);}
}

@media (prefers-reduced-motion:reduce){
  .voice-track{scroll-behavior:auto;}
}
@media (max-width:640px){
  .voice-rail{margin-top:22px;}
  .voice{flex-basis:min(86%,340px);}
}


/* ============================================================
   FAQ  (on the three way-in pages)

   Native <details>, so it works with JavaScript off, is keyboard operable
   without any authored handler, and keeps every answer in the HTML whether
   or not it is open. That last part is the point: a machine reading the page
   for an answer gets all of it, while a person gets a section they can scan
   in a few seconds rather than a wall.

   The marker is drawn from two bars rather than set as a "+" character. A
   glyph would inherit the text font, sit on the baseline, and change shape
   between platforms.
   ============================================================ */
.faq{
  margin-top:26px;
  max-width:820px;
}
/* The rule sits on each row rather than on the wrapper. Identical to look at,
   and it keeps the wrapper from being a bordered box whose first child lands
   flush against its own boundary line. */
.faq details{border-top:1px solid var(--rule-dark);}
.faq details:last-of-type{border-bottom:1px solid var(--rule-dark);}
.faq summary{
  list-style:none;
  cursor:pointer;
  display:flex;
  align-items:flex-start;
  gap:20px;
  padding:18px 0;
}
.faq summary::-webkit-details-marker{display:none;}
.faq summary h3{
  font-family:var(--sans);
  font-weight:600;
  font-size:16.5px;
  letter-spacing:-.012em;
  line-height:1.4;
  color:var(--light);
  transition:color .2s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .faq summary:hover h3{color:var(--accent);}
}
.faq summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px;}

/* two 1px bars, the vertical one collapsing to nothing when the row opens */
.q-mark{
  position:relative;
  flex:none;
  width:13px;height:13px;
  margin-left:auto;
  margin-top:5px;
}
.q-mark::before,.q-mark::after{
  content:"";
  position:absolute;
  background:var(--light-dim);
  transition:transform .18s var(--ease),background .2s var(--ease);
}
.q-mark::before{left:0;right:0;top:6px;height:1px;}
.q-mark::after{top:0;bottom:0;left:6px;width:1px;}
details[open] .q-mark::after{transform:scaleY(0);}
details[open] .q-mark::before{background:var(--accent);}

.faq .a{
  padding:0 0 20px;
  max-width:66ch;
  font-size:15.5px;
  color:var(--light-soft);
}
.faq .a + .a{margin-top:12px;}

/* The arc reaches these pages, so the FAQ flips with everything else. */
body.is-light .faq details{border-color:var(--rule-light);}
body.is-light .faq summary h3{color:var(--ink);}
body.is-light .faq .a{color:var(--ink-soft);}
body.is-light .q-mark::before,
body.is-light .q-mark::after{background:var(--ink-dim);}
body.is-light details[open] .q-mark::before{background:var(--accent-ink);}
@media (hover:hover) and (pointer:fine){
  body.is-light .faq summary:hover h3{color:var(--accent-ink);}
}


/* The current page in the footer. Set by journey.js rather than in the markup,
   so the footer stays byte-identical across every page and a missing link can
   never pass for a design decision. */
.foot nav a[aria-current="page"]{
  color:var(--ink);
  border-bottom-color:var(--accent-ink);
  cursor:default;
}
.foot--void nav a[aria-current="page"]{color:var(--light);border-bottom-color:var(--accent);}


/* ============================================================
   THE OPEN

   No entrance animation on the headline, and that is a decision.

   It was built and then removed on 2026-09-09. Three reasons, in order of
   weight:

   1. No purpose. Motion earns its place through spatial consistency, state
      indication, explanation, feedback, or preventing a jarring change. A
      headline fading up is none of those; the page is not jarring without it.

   2. It is the most placeable move on the internet. It appears on every
      agency template and every generated site, so it works directly against
      the thing this design is trying to be, which is hard to place.

   3. Frequency. It had been applied to .page-open as well, so it fired on all
      six sub pages. Somebody reading four pages saw it four times in a
      minute. Animation is for what is seen once.

   The headline is four words and a full stop. It is stronger arriving than
   being introduced, and this site's whole argument is that it does not waste
   the visitor's time. The hero should behave that way.

   The plate behind it still drifts, because that is material rather than
   decoration: a specular highlight that does not move is a stripe. See
   plateDrift() in js/journey.js.
   ============================================================ */
