/* Sitewise studio pages: /work/ /services/ /about/ /contact/ and the 404.
   Loaded on every page, Home included (make-deploy.py), after the shared
   styles, because Home's lower half reuses these sections. Home's hero is
   LOCKED (HERO-LOCK.md): scope every rule so it cannot reach #top, and run
   the hero baseline check after any change here. Monochrome, and one sans family for
   headings and text alike (29 Sep, Freddie: no serif, no blue in headings).
   The blue left is the keyboard focus ring, which is for access, not show. */

:root{
  --s-gap:clamp(16px,2.4vw,32px);
  --s-space:clamp(96px,11vw,168px);
  --s-space-m:clamp(80px,8.4vw,120px);  /* the tighter section rhythm: About, the top of Services */
  --s-head-top:clamp(20px,3vw,40px);   /* added under the header before a page's headline */
  --s-stack:clamp(20px,1.8vw,24px);    /* a heading to the text that belongs to it */
  --s-row:clamp(36px,3.4vw,48px);      /* between rows of like items */
  --s-large:clamp(56px,6.4vw,96px);    /* a large statement to what follows it */
  --s-statement:clamp(2rem,1.1rem + 3vw,3.5rem);   /* About's large statements */
  --s-num:clamp(2.25rem,1.5rem + 2.2vw,3.5rem);    /* the step numbers */
  --s-end:clamp(3rem,1.2rem + 6.4vw,7.5rem);       /* About's closing headline */
  --s-font:var(--body);
  --s-title:clamp(2.5rem,1.3rem + 4.6vw,5.25rem);
  --s-h2:clamp(1.875rem,1.4rem + 1.6vw,2.75rem);
  --s-h3:clamp(1.25rem,1.1rem + .6vw,1.625rem);
  --s-stand:clamp(1.125rem,1rem + .45vw,1.375rem);
  --s-ease:cubic-bezier(.16,1,.3,1);
  --s-ease-io:cubic-bezier(.65,0,.35,1);
  /* motion: three durations, three easings, one stagger step, one distance */
  --m-micro:.28s;                          /* hover, underline, buttons */
  --m-std:.8s;                             /* content arriving */
  --m-feat:1.1s;                           /* headlines, images */
  --e-out:cubic-bezier(.215,.61,.355,1);   /* power3.out */
  --e-out4:cubic-bezier(.165,.84,.44,1);   /* power4.out */
  --e-io:cubic-bezier(.65,0,.35,1);
  --m-step:.08s;
  --m-y:34px;
  --m-arrive:.06s;                         /* a fresh load starts at once */
  --s-err:#A3332B;
  --s-on-ink:#B4BAC3;
}

/* ---------------- foundations ---------------- */

.s-sec{padding:var(--s-space) 0 0}
.s-top{padding-top:clamp(28px,4.5vw,64px)}

.s-label{margin:0;font-family:var(--ui);font-size:14px;font-weight:400;line-height:1.4;color:var(--ink-soft)}

.s-head{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);
  padding-top:clamp(36px,5.5vw,84px)}
.s-title{grid-column:1/-1;margin:0;max-width:14ch;font-family:var(--s-font);font-weight:500;
  font-size:var(--s-title);line-height:1.02;letter-spacing:-.035em;color:var(--ink);text-wrap:balance}
.s-title--wide{max-width:17ch}
.s-stand{grid-column:7/-1;margin:clamp(28px,3.4vw,48px) 0 0;max-width:38ch;
  font-size:var(--s-stand);line-height:1.5;color:var(--ink-soft);text-wrap:pretty}
.s-stand--serif{max-width:26ch;font-size:clamp(1.375rem,1.1rem + 1vw,2rem);line-height:1.3;
  letter-spacing:-.015em;color:var(--ink)}

.s-sechead{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);row-gap:20px;
  align-items:end;margin-bottom:clamp(40px,5vw,72px)}
.s-sechead>.s-h2{grid-column:1/7}
.s-sechead>:not(.s-h2){grid-column:8/-1}
.s-sechead>.s-sechead-end{margin:0;justify-self:end}
.s-h2{margin:0;font-family:var(--s-font);font-weight:500;font-size:var(--s-h2);line-height:1.05;
  letter-spacing:-.03em;color:var(--ink)}

.s-nowrap{white-space:nowrap}

/* the header's serif-and-blue signature is Home's; these pages go without */
.nav .mark-sig{display:none}

/* ---------------- links and buttons ---------------- */

.s-link{--ul:color-mix(in srgb,currentColor 38%,transparent);color:inherit;text-decoration:none;
  padding-bottom:.14em;background:linear-gradient(var(--ul),var(--ul)) 0 100%/100% 1px no-repeat;
  transition:color var(--m-micro) var(--e-out)}
.s-link:hover,.s-link:focus-visible{--ul:currentColor}
@media(hover:hover) and (prefers-reduced-motion:no-preference){
  .s-link:hover{animation:mUnder .6s var(--e-io) both}
}
@keyframes mUnder{0%{background-position:100% 100%;background-size:100% 1px}
  45%{background-position:100% 100%;background-size:0 1px}
  46%{background-position:0 100%;background-size:0 1px}
  100%{background-position:0 100%;background-size:100% 1px}}

.s-btn{display:inline-flex;align-items:center;justify-content:center;gap:14px;min-height:50px;padding:0 24px;
  border:1px solid var(--ink);border-radius:4px;background:var(--ink);color:var(--paper);
  font-family:var(--ui);font-size:15px;font-weight:500;line-height:1.2;letter-spacing:.005em;
  text-decoration:none;cursor:pointer;
  transition:background-color var(--m-micro) var(--e-out),border-color var(--m-micro) var(--e-out),
    color var(--m-micro) var(--e-out),transform var(--m-micro) var(--e-out)}
.s-btn:active{transform:scale(.985)}
.s-btn:hover{background:#000;border-color:#000;color:#fff}
.s-btn--line{background:transparent;color:var(--ink);border-color:var(--rule-strong)}
.s-btn--line:hover{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.s-btn--light{background:var(--paper);border-color:var(--paper);color:var(--ink)}
.s-btn--light:hover{background:#fff;border-color:#fff;color:var(--ink)}
.s-btn--xl{min-height:60px;padding:0 30px;font-size:16px}
.s-ar{display:inline-block;transition:transform var(--m-micro) var(--e-out)}
.s-btn:hover .s-ar{transform:translateX(4px)}

/* live or preview: a filled blue dot, or an empty one */
.s-status{display:inline-flex;align-items:center;gap:9px}
.s-status::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;
  border:1px solid var(--ink-faint)}
.s-status.is-live::before{border-color:var(--ink);background:var(--ink)}

/* ---------------- accordion ---------------- */

.s-acc{position:relative;border-bottom:0}
.s-acc::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--rule);
  transform-origin:0 50%}
.s-acc:nth-child(2){--ai:1}.s-acc:nth-child(3){--ai:2}.s-acc:nth-child(4){--ai:3}
.s-acc:nth-child(5){--ai:4}.s-acc:nth-child(6){--ai:5}
.s-acc>summary{list-style:none;display:flex;align-items:center;justify-content:space-between;gap:24px;
  min-height:64px;padding:18px 0;cursor:pointer;font-family:var(--s-font);font-size:clamp(17px,1.3vw,19px);
  font-weight:500;line-height:1.35;letter-spacing:-.01em;color:var(--ink);transition:color .25s var(--ease)}
.s-acc>summary::-webkit-details-marker{display:none}
.s-acc>summary{transition:color var(--m-micro) var(--e-out)}
.s-acc>summary:hover{color:var(--ink-soft)}
.s-acc-ic{position:relative;flex:none;width:14px;height:14px}
.s-acc-ic::before,.s-acc-ic::after{content:"";position:absolute;left:0;right:0;top:50%;height:1.5px;
  margin-top:-.75px;background:currentColor;transition:transform .45s var(--s-ease)}
.s-acc-ic::after{transform:rotate(90deg)}
.s-acc[open]:not(.is-closing) .s-acc-ic::after{transform:rotate(0)}
.s-acc-body{overflow:hidden}
.s-acc-body>p{margin:0;padding:0 0 28px;max-width:60ch;color:var(--ink-soft);line-height:1.65}

.s-faq-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap)}
.s-faq-grid>.s-h2{grid-column:1/5}
.s-faq{grid-column:6/-1;margin-top:-14px}

/* ---------------- the close ---------------- */

.s-close{margin-top:var(--s-space);padding:clamp(80px,10vw,152px) 0;background:var(--ink);color:var(--paper);position:relative}
/* "30-minute call" shines once, a moment after the band appears (services.html): a light sweep through the letters, and a soft glow */
.s-close-hl{border-radius:2px}
@media(prefers-reduced-motion:no-preference){
  .s-close-hl.is-shining{background:linear-gradient(100deg,currentColor 0 40%,#fff 50%,currentColor 60% 100%) 100% 0/300% 100%;
    -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
    animation:hlShine 1.1s cubic-bezier(.3,0,.3,1) both,hlGlow 1.6s ease-out both}
}
@keyframes hlShine{to{background-position:0 0}}   /* the gradient always covers the words; only its bright band moves */
@keyframes hlGlow{0%{text-shadow:none}35%{text-shadow:0 0 14px rgba(255,255,255,.45)}100%{text-shadow:none}}
.s-close-darts{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;fill:var(--paper);color:var(--paper);overflow:visible;opacity:0}
.s-close-darts.is-shown{opacity:1}
@media(prefers-reduced-motion:no-preference){.s-close-darts{transition:opacity .9s cubic-bezier(.2,.7,.3,1) .25s}}
.s-close-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);align-items:center}   /* the heading sits level with the middle of the band (Freddie, 1 Oct) */
.s-close-title{grid-column:2/8;margin:0;max-width:13ch;font-family:var(--s-font);font-weight:500;
  font-size:clamp(2.25rem,1.4rem + 3.2vw,4.25rem);line-height:1.02;letter-spacing:-.035em;text-wrap:balance}
.s-close-side{grid-column:9/-1}
.s-close-side>p{margin:0;max-width:34ch;color:var(--s-on-ink)}
.s-close-side>.s-close-acts{display:flex;flex-wrap:wrap;align-items:center;gap:16px 24px;margin-top:30px;
  color:var(--paper)}
.s-close .s-link:hover{color:#fff}
.s-close-or{color:var(--s-on-ink)}
.s-close :focus-visible{outline-color:var(--paper)}

/* the page canvas matches the paper, so a page arriving without a transition never flashes white (1 Oct) */
html{background:var(--paper)}

/* ---------------- footer ---------------- */

.s-foot{padding:clamp(64px,7vw,96px) 0 32px;border-top:0}
.s-foot .wrap{display:block;justify-items:stretch}   /* the shell's old footer rule sets justify-items:start on narrow screens, which now shrinks block children too */
/* Freddie's sketch (1 Oct): brand, Explore and Get in touch across one row */
.s-foot-cols{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);row-gap:44px;
  padding:0 clamp(0px,3.5vw,48px) clamp(48px,5vw,72px)}
.s-foot-brand{grid-column:1/6}
.s-foot-brand .mark img{display:block;height:clamp(34px,3.3vw,46px);width:auto}
.s-foot-sig{margin:14px 0 0;max-width:13em;font-family:var(--ui);font-size:clamp(16px,1.4vw,19px);line-height:1.35;color:var(--ink-soft)}
.s-foot-col{display:flex;flex-direction:column;align-items:flex-start}
.s-foot-pages{grid-column:6/9}
.s-foot-touch{grid-column:9/-1}
.s-foot-col>.s-label{margin-bottom:14px}
.s-foot-links{display:grid;grid-template-columns:repeat(2,max-content);grid-template-rows:repeat(3,auto);
  grid-auto-flow:column;column-gap:clamp(48px,7vw,104px)}
.s-foot-links>a,.s-foot-col>a{display:inline-flex;align-items:center;justify-self:start;min-height:46px;
  font-size:clamp(17px,1.45vw,20px);color:var(--ink);text-decoration:none;
  background:linear-gradient(currentColor,currentColor) 0 calc(50% + .72em)/0 1px no-repeat;
  transition:background-size var(--m-micro) var(--e-out)}
.s-foot-links>a:hover,.s-foot-links>a:focus-visible,.s-foot-links>a[aria-current="page"],
.s-foot-col>a:hover,.s-foot-col>a:focus-visible{background-size:100% 1px}
.s-foot-col>a.s-foot-mail{background-size:100% 1px}   /* the email reads as a link, underlined, as in the sketch */
.s-foot-out{margin-left:.35em;font-size:.85em}
.s-foot-base{position:relative;display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  padding-top:24px}
.s-foot-base::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;background:var(--rule);
  transform-origin:0 50%}
.s-foot-base small{font-family:var(--ui);font-size:clamp(14px,1.2vw,16px);color:var(--ink-soft)}

/* ================= WORK ================= */

.w-list{padding-top:clamp(40px,6vw,88px)}
.w-head{margin-bottom:clamp(64px,8vw,120px)}
.w-title{margin:0;font-family:var(--s-font);font-weight:500;font-size:var(--s-title);line-height:1.02;
  letter-spacing:-.035em}
.w-sub{margin:clamp(16px,1.8vw,24px) 0 0;max-width:40ch;font-size:var(--s-stand);line-height:1.5;color:var(--ink-soft)}
/* the Work page's own opening (29 Sep): less air above and below, so the
   work starts on the first screen. From 1024px the line sits beside the
   title, on its baseline; below that it sits under it. Home's copy of this
   section has no .w-index and keeps its own spacing. */
.w-index{padding-top:clamp(28px,4.4vw,64px);--m-feat:.9s}
.w-index .w-head{margin-bottom:clamp(40px,5vw,72px)}
.w-index .w-sub{max-width:36ch;text-wrap:balance}
@media(min-width:1024px){
  .w-index .w-head{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);
    align-items:end;align-items:last baseline}
  .w-index .w-title{grid-column:1/8}
  .w-index .w-sub{grid-column:8/-1;margin:0}
}
.w-proj{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));grid-template-rows:auto auto 1fr;column-gap:var(--s-gap);scroll-margin-top:28px}
.w-proj+.w-proj{margin-top:var(--s-space)}

.w-name{margin:0;font-family:var(--s-font);font-weight:500;font-size:clamp(2rem,1.4rem + 2.2vw,3.5rem);
  line-height:1.02;letter-spacing:-.035em}

.w-type{margin:12px 0 0;font-size:17px;color:var(--ink-soft)}
.w-desc{margin:0;max-width:50ch;color:var(--ink)}
.w-foot{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px 28px;margin:26px 0 0;font-size:15px}
.w-foot .s-status{color:var(--ink-soft)}
.w-go{font-weight:500}
.w-go-ar{display:inline-block;margin-left:6px;transition:transform .45s var(--s-ease)}
.w-go:hover .w-go-ar,.w-go:focus-visible .w-go-ar{transform:translate(2px,-2px)}

/* a browser window around the real capture. Once on screen the page inside
   tours itself, slowly, so the whole site can be seen without leaving */
.w-media{position:relative}
/* no ring, fill or shadow on the frame or phone: the jelly edge (index.html)
   moves in, and any of those would leave the old rectangle showing lighter
   than the page where the edge used to be */
.w-frame{position:relative;display:block;overflow:hidden;border-radius:6px;
  color:var(--ink);text-decoration:none}
.w-frame-in{display:block;background:var(--paper-raised)}
.w-chrome{display:flex;align-items:center;gap:6px;height:30px;padding:0 12px;background:var(--paper-raised);
  border-bottom:1px solid var(--rule)}
.w-chrome i{flex:none;width:7px;height:7px;border-radius:50%;background:var(--rule-strong)}
.w-chrome span{flex:1;min-width:0;margin-right:33px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-align:center;font-family:var(--ui);font-size:11.5px;letter-spacing:.01em;color:var(--ink-soft)}
.w-view{--vr:62.5cqw;position:relative;display:block;aspect-ratio:16/10;overflow:hidden;
  container-type:inline-size;background:#fff}
.w-view picture{display:block;transform-origin:50% 0}
.w-view img{display:block;width:100%;height:auto}
/* the site tour: keyframes and timing are shared with Home (index.html) */
@media(prefers-reduced-motion:no-preference){
  .w-view img{animation:siteTour var(--tour,30s) linear infinite paused}
  .w-view.tour-on img{animation-play-state:running}
  .w-frame:hover .w-view img,
  .w-proj:has(.w-go:focus-visible) .w-view img,
  .p-work-item:has(.s-link:focus-visible) .w-view img,
  .wp-shot:hover .w-view img,
  .wp-item:has(.wp-go:focus-visible) .w-view img{animation-play-state:paused}
  /* every site holds on its first screen for 2s before the tour sets off,
     as it does at the end of every lap: the picture has finished arriving,
     and the site can be read at a glance (Work, Home's projects, Services) */
  .w-view img{animation-delay:2s}
}

.w-phone{position:absolute;z-index:2}
.w-phone-in{overflow:hidden;aspect-ratio:390/844;padding:clamp(3px,.4vw,6px);border-radius:clamp(16px,2vw,28px);
  background:var(--ink)}
.w-phone-in picture{display:block;height:100%;overflow:hidden;border-radius:clamp(12px,1.6vw,22px);background:#fff}
.w-phone-in img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 0}

/* A: the live site leads: its name and words above, the capture full width */
.w-proj--a .w-id{grid-column:1/7;grid-row:1;align-self:end}
.w-proj--a .w-body{grid-column:7/-1;grid-row:1;align-self:end}
.w-proj--a .w-media{grid-column:1/-1;grid-row:2;margin-top:clamp(32px,3.6vw,52px);padding-bottom:9%}
.w-proj--a .w-frame{width:84%}
.w-proj--a .w-phone{right:0;bottom:0;width:23%}

/* B: words on the left, the window to the right with the phone in front */
.w-proj--b .w-id{grid-column:1/5;grid-row:1;align-self:start}
.w-proj--b .w-body{grid-column:1/5;grid-row:2;align-self:start;padding-top:32px}
.w-proj--b .w-media{grid-column:6/-1;grid-row:1/4;align-self:start;padding-bottom:10%}
.w-proj--b .w-frame{width:86%;margin-left:auto}
.w-proj--b .w-phone{left:0;bottom:0;width:26%}

/* C: the phone stands high on the right, the window drops in below it */
.w-proj--c .w-id{grid-column:9/-1;grid-row:1;align-self:start}
.w-proj--c .w-body{grid-column:9/-1;grid-row:2;align-self:start;padding-top:32px}
.w-proj--c .w-media{grid-column:1/8;grid-row:1/4;align-self:start}
.w-proj--c .w-frame{width:84%;margin-top:16%}
.w-proj--c .w-phone{right:0;top:0;width:26%}

/* Each project's screenshots rise and settle as they come up the screen, tied
   to the scroll itself so they move with the reader, never on a timer. */
@supports (animation-timeline:view()){
  @media(prefers-reduced-motion:no-preference){
    .w-media{animation:wSettle linear both;animation-timeline:view();animation-range:entry 0% cover 32%}
    @keyframes wSettle{from{transform:translateY(64px) scale(.955)}to{transform:none}}
  }
  @media(max-width:700px) and (prefers-reduced-motion:no-preference){
    @keyframes wSettle{from{transform:translateY(32px) scale(.975)}to{transform:none}}
  }
}

/* the phones drift against the windows as the page moves: small, and only
   where the browser can tie it to the scroll itself */
@supports (animation-timeline:view()){
  @media(min-width:901px) and (prefers-reduced-motion:no-preference){
    .w-phone{animation:wDrift linear both;animation-timeline:view();animation-range:entry 0% exit 100%}
    @keyframes wDrift{from{transform:translateY(44px)}to{transform:translateY(-44px)}}
  }
}

/* ================= SERVICES ================= */

/* The top of Services reads as one piece: the headline, then the plans close
   enough below it to belong to it, "Three plans" paired with the fee note in
   the same right-hand column as the line under the headline. */
.p-hero .s-head{padding-top:var(--s-head-top)}
.p-hero .s-stand{margin-top:clamp(20px,2.2vw,32px)}
.s-sec.p-plans{padding-top:var(--s-space-m)}
.p-plans .s-sechead{margin-bottom:clamp(28px,3.2vw,44px)}
.p-plans .s-sechead>.s-h2{grid-column:1/7}
.p-plans .s-sechead>.p-fees{grid-column:7/-1}
.p-fees-k{margin:0;font-size:var(--s-stand);font-weight:500;line-height:1.4;color:var(--ink)}
.p-fees-lead{margin:4px 0 0;max-width:34ch;font-size:var(--s-stand);line-height:1.45;color:var(--ink-soft)}

/* one sheet, three columns: a proposal, not three cards */
.p-sheet{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:repeat(6,auto);
  background:var(--paper-raised);border:1px solid var(--rule);border-radius:4px}
.p-plan{position:relative;display:grid;grid-row:span 6;grid-template-rows:subgrid;align-content:start;
  padding:clamp(22px,2.4vw,34px) clamp(20px,2.4vw,36px) clamp(24px,2.6vw,36px)}
.p-plan+.p-plan{border-left:1px solid var(--rule)}
.p-plan--pop{background:#fff}
.p-plan--pop::before{content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:3px;background:var(--ink)}
.p-top{margin:0 0 14px;min-height:1.4em}
.p-pop{font-family:var(--ui);font-size:14px;font-weight:500;color:var(--ink)}
.p-name{margin:0;font-family:var(--s-font);font-weight:500;font-size:clamp(24px,2.2vw,30px);line-height:1.1;
  letter-spacing:-.025em}
.p-for{margin:8px 0 0;font-size:15px;color:var(--ink-soft)}
.p-price{margin-top:32px}
.p-month{display:flex;align-items:baseline;gap:10px;margin:0}
.p-amt{font-family:var(--s-font);font-weight:500;font-size:clamp(44px,4vw,60px);line-height:1;letter-spacing:-.045em;
  font-variant-numeric:tabular-nums}
.p-unit{font-family:var(--ui);font-size:14px;color:var(--ink-soft)}
.p-setup{margin:14px 0 0;font-size:15px;color:var(--ink)}
.p-list{margin:30px 0 0;padding:0;list-style:none}
.p-list li{padding:5px 0;font-size:15.5px;line-height:1.45}
.p-foot{margin:14px 0 0;font-size:14px;color:var(--ink-soft)}
.p-foot:empty{margin:0}
.p-cta{align-self:end;justify-content:space-between;width:100%;margin-top:30px}

.p-compare{margin-top:clamp(24px,3vw,40px);border-top:1px solid var(--rule)}
.p-compare>summary{min-height:60px;font-family:var(--ui);font-size:15px;font-weight:500;letter-spacing:.005em}
.p-table-wrap{padding-top:6px}
.p-table{width:100%;border-collapse:collapse;font-size:15px;line-height:1.45}
.p-table th,.p-table td{padding:14px 20px 14px 0;border-top:1px solid var(--rule);text-align:left;vertical-align:top}
.p-table thead th{padding-top:4px;padding-bottom:14px;border-top:0;font-size:16px;font-weight:600;line-height:1.2;
  letter-spacing:-.01em}
.p-table tbody th{width:22%;font-weight:500;color:var(--ink)}
.p-table td{width:26%;color:var(--ink)}
.p-table td.p-no{color:var(--ink-faint)}
.p-yes{display:inline-block;width:13px;height:7px;margin:0 0 3px 1px;border-left:1.5px solid var(--ink);
  border-bottom:1.5px solid var(--ink);transform:rotate(-45deg)}
.p-table-note{margin:20px 0 30px;font-size:14px;color:var(--ink-soft)}

.p-steps-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-gap);margin:0;padding:0;
  list-style:none}
.p-steps-list h3{margin:0;font-family:var(--s-font);font-weight:500;font-size:var(--s-h3);line-height:1.2;
  letter-spacing:-.02em}
.p-steps-list p{margin:12px 0 0;max-width:34ch;color:var(--ink-soft)}

.p-work-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-gap)}
.w-frame--thumb .w-view{--vr:75cqw;aspect-ratio:4/3}
/* a faint edge, inside the capture: Sitewise's own page is the same paper as
   this one and would otherwise have no edge at all. Inside, so the jelly
   outline clips it along with the picture. */
.w-frame--thumb .w-view::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(21,23,27,.09)}
.p-work-meta{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:4px 20px;margin-top:22px}
.p-work-name{margin:0;font-family:var(--s-font);font-weight:500;font-size:clamp(20px,1.7vw,24px);line-height:1.2;
  letter-spacing:-.02em}
.p-work-what{grid-column:1;margin:0;font-size:15px;color:var(--ink-soft)}
.p-work-meta>.s-link{grid-column:2;grid-row:1/3;align-self:center;font-size:15px}

/* ================= ABOUT =================
   One 12-column grid, the header's, with three lines through the whole page:
   - column 1: labels and headings;
   - column 5: where the statements, the steps and the answers start;
   - column 9: the smaller words that sit beside them (the hero statement,
     the About paragraph, each step's text, the close's note).
   Tablet keeps two lines, 1 and 7, and phones are one column.
   The rhythm runs large statement, small detail, large statement, then
   structured information. Spacing: --s-space between sections, --s-large
   from a statement to what follows it, --s-row and --s-stack inside. */

.a-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap)}
.s-sec.a-sec{padding-top:var(--s-space)}

/* the hero: three lines of large type that unfold like Cappen's "Building
   tomorrow for today" (Freddie, 1 Oct): one letter after another (.a-f,
   inside .a-c, inside a word, .a-w) rolls up in 3D from lying flat on its
   baseline (the origin: its left end, at 88%), at one pace through the lines. The inline
   script after the headline (pages/about.html) splits it and runs it, then
   puts the plain text back. With reduced motion, or without the script, it
   is plain text.
   The type is sized so the widest line, "and development" (6.77em), fills
   about 88% of the page width, and three lines always fit the screen. */
.a-h3{padding:0}
.a-h3-stage{display:flex;flex-direction:column;justify-content:flex-end;
  min-height:calc(100svh - 76px);padding:var(--s-large) 0 var(--s-row)}
.a-hl{grid-column:1/-1;margin:0;font-family:var(--s-font);font-weight:500;
  font-size:min(9.25rem,11.7vw,17svh);line-height:.8;letter-spacing:-.045em;color:var(--ink)}
.a-hl-line{display:block;width:max-content}
.a-hl-in{display:inline-block;white-space:nowrap}
.a-w{display:inline-block;white-space:nowrap}
.a-c{display:inline-block}
.a-f{display:inline-block;transform-origin:50% 88%;will-change:transform,opacity;
  backface-visibility:hidden;-webkit-backface-visibility:hidden}
.a-h3-st{grid-column:7/-1;margin:clamp(32px,4vw,56px) 0 0;max-width:23rem;
  font-size:clamp(1.125rem,1rem + .45vw,1.375rem);line-height:1.4;letter-spacing:-.01em;color:var(--ink)}
.a-h3+.a-about{padding-top:var(--s-large)}
@media(prefers-reduced-motion:no-preference){
  .a-h3-st{--m-y:20px;animation:mRise .7s var(--e-out) calc(var(--m-arrive) + var(--a-lead,.1s) + .95s) backwards}
  /* after a page transition, start as the old page is finishing leaving */
  html.vt-arrive .a-h3{--a-lead:.2s}
}

/* About Sitewise: a small label, a large statement, a short paragraph.
   The label's capitals line up with the statement's. */
.a-label{grid-column:1/5;grid-row:1;margin:0;padding-top:calc(var(--s-statement) * .114);font-family:var(--ui);
  font-size:14px;font-weight:400;line-height:1.4;color:var(--ink-soft)}
.a-big{margin:0;font-family:var(--s-font);font-weight:500;font-size:var(--s-statement);line-height:1.08;
  letter-spacing:-.032em;color:var(--ink);text-wrap:balance}
.a-about .a-big{grid-column:5/-1;grid-row:1}
.a-lede{grid-column:9/-1;grid-row:2;margin:var(--s-row) 0 0;max-width:36ch;
  font-size:clamp(16.5px,1.25vw,18px);line-height:1.6;color:var(--ink-soft)}

/* How it works: the heading and promises hold still on the left (large
   screens) while the four steps pass on the right, each under a rule */
.a-how .a-grid{row-gap:var(--s-large);align-items:start}
.a-aside{grid-column:1/5}
.a-h{margin:0;font-family:var(--s-font);font-weight:500;font-size:var(--s-h2);line-height:1.05;
  letter-spacing:-.03em;color:var(--ink)}
.a-promises{margin:var(--s-stack) 0 0;padding:0;list-style:none}
.a-promises li{padding:4px 0;font-size:16px;line-height:1.5;color:var(--ink-soft)}
.a-steps{grid-column:5/-1;display:grid;grid-template-columns:subgrid;margin:0;padding:0;list-style:none}
.a-step{--d:.12s;grid-column:1/-1;display:grid;grid-template-columns:subgrid;align-items:baseline;
  padding:var(--s-stack) 0 var(--s-large)}
.a-step:last-child{padding-bottom:0}
.a-n{--m-ry:12px;grid-column:1/-1;display:block;margin:0 0 var(--s-stack);font-family:var(--s-font);
  font-size:var(--s-num);font-weight:400;line-height:1;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;color:var(--ink-faint)}
.a-n>span{display:block}
.a-step h3{grid-column:1/5;margin:0;padding-right:var(--s-gap);font-family:var(--s-font);font-weight:500;
  font-size:var(--s-h3);line-height:1.2;letter-spacing:-.02em}
.a-step p{grid-column:5/-1;margin:0;max-width:40ch;color:var(--ink-soft)}
@media(min-width:1024px){
  .a-aside{position:sticky;top:calc(76px + var(--s-row))}
}

/* Straightforward by design: a large line, then four short principles */
.a-prin .a-grid{row-gap:var(--s-large)}
.a-prin-h{grid-column:1/-1}
.a-prin-list{grid-column:1/-1;display:grid;grid-template-columns:subgrid;row-gap:var(--s-row);
  margin:0;padding:0;list-style:none}
.a-prin-list>li{grid-column:span 3;padding-top:var(--s-stack)}
.a-prin-list h3{margin:0;font-family:var(--s-font);font-weight:500;font-size:clamp(1.125rem,1rem + .4vw,1.375rem);
  line-height:1.25;letter-spacing:-.015em}
.a-prin-list p{margin:12px 0 0;max-width:30ch;font-size:16px;line-height:1.6;color:var(--ink-soft)}

.a-faq .s-faq-grid{row-gap:var(--s-stack)}
.a-faq .s-faq-grid>.s-h2{grid-column:1/5}
.a-faq .s-faq{grid-column:5/-1}

/* the close: the page's last headline, and the call to book */
.a-end{margin-top:var(--s-space);padding:clamp(96px,12vw,176px) 0 clamp(72px,8vw,120px);
  background:var(--ink);color:var(--paper)}
.a-end .a-grid{--a-act:clamp(1.75rem,1.1rem + 2.2vw,3rem);row-gap:var(--s-large);align-items:end}
.a-end-h{grid-column:1/-1;margin:0;max-width:11ch;font-family:var(--s-font);font-weight:500;
  font-size:var(--s-end);line-height:.98;letter-spacing:-.045em;text-wrap:balance}
.a-end-act{grid-column:1/9;margin:0}
.a-end-link{display:inline-flex;align-items:baseline;gap:.32em;color:var(--paper);text-decoration:none;
  font-family:var(--s-font);font-weight:500;font-size:var(--a-act);line-height:1.1;
  letter-spacing:-.03em}
.a-end-t{--ul:color-mix(in srgb,currentColor 38%,transparent);padding-bottom:.08em;
  background:linear-gradient(var(--ul),var(--ul)) 0 100%/100% 1px no-repeat}
.a-end-link:hover .a-end-t,.a-end-link:focus-visible .a-end-t{--ul:currentColor}
.a-end-link:hover .s-ar,.a-end-link:focus-visible .s-ar{transform:translateX(6px)}
@media(hover:hover) and (prefers-reduced-motion:no-preference){
  .a-end-link:hover .a-end-t{animation:mUnder .6s var(--e-io) both}
}
/* the note's last line sits on the link's baseline */
.a-end-note{grid-column:9/-1;margin:0;max-width:30ch;padding-bottom:max(0px,calc(var(--a-act) * .215 - 5.3px));font-size:16px;
  line-height:1.6;color:var(--s-on-ink)}
.a-end .s-link{color:var(--paper)}
.a-end :focus-visible{outline-color:var(--paper)}

/* tablet: two lines, 1 and 7; nothing sticks */
@media(max-width:1023px){
  .a-label{grid-column:1/-1;padding-top:0}
  .a-about .a-big{grid-column:1/-1;grid-row:2;margin-top:var(--s-stack)}
  .a-lede{grid-column:7/-1;grid-row:3}
  .a-aside,.a-steps{grid-column:1/-1}
  .a-step h3{grid-column:1/7}
  .a-step p{grid-column:7/-1}
  .a-prin-list>li{grid-column:span 6}
  .a-faq .s-faq-grid>.s-h2,.a-faq .s-faq{grid-column:1/-1}
  .a-faq .s-faq{margin-top:0}
  .a-end-act{grid-column:1/7}
  .a-end-note{grid-column:7/-1}
}

/* phones: one column, the numbers kept, the gaps brought in */
@media(max-width:640px){
  .a-h3-stage{min-height:calc(88svh - 76px)}
  .a-hl{font-size:min(12.4vw,17svh)}
  .a-h3-st{grid-column:1/-1;max-width:30ch}
  .a-lede{grid-column:1/-1;margin-top:var(--s-stack)}
  .a-how .a-grid{row-gap:var(--s-row)}
  .a-steps,.a-step{display:block}
  .a-step{padding-bottom:var(--s-row)}
  .a-step h3{padding-right:0}
  .a-step p{margin-top:10px}
  .a-prin .a-grid{row-gap:var(--s-row)}
  .a-prin-list>li{grid-column:1/-1}
  .a-end .a-grid{row-gap:var(--s-row)}
  .a-end-act,.a-end-note{grid-column:1/-1}
  .a-end-note{padding-bottom:0}
}

/* ================= CONTACT ================= */

.c-main{padding-top:clamp(48px,6vw,88px);padding-bottom:var(--s-space)}
.c-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);row-gap:64px;
  align-items:start}
.c-call{grid-column:1/6}
.c-form{grid-column:7/-1;grid-row:1}
.c-call{grid-row:1}
.c-h{margin:0;font-family:var(--s-font);font-weight:500;font-size:clamp(20px,1.7vw,24px);line-height:1.2;
  letter-spacing:-.02em}
.c-book-note{margin:12px 0 26px;max-width:36ch;color:var(--ink-soft)}
.c-next,.c-direct{margin-top:64px}
.c-next-list{margin:16px 0 0;padding:0;list-style:none}
.c-next-list li{padding:4px 0;font-size:16px;color:var(--ink-soft)}
.c-direct-list{margin:18px 0 0;padding:0;list-style:none}
.c-direct-list li{padding:4px 0}
.c-direct-list .s-link{justify-self:start;font-size:16px;overflow-wrap:anywhere}

.c-form{padding:clamp(24px,3.4vw,48px);background:var(--paper-raised);border:1px solid var(--rule);border-radius:4px}
.c-form-plan{margin:14px 0 0;padding-left:14px;border-left:2px solid var(--ink);font-size:15px;color:var(--ink)}
.c-field{margin-top:28px}
.c-field label{display:block;margin-bottom:6px;font-family:var(--ui);font-size:14px;font-weight:500;
  letter-spacing:.005em;text-transform:none;color:var(--ink);transition:color .25s var(--ease)}
.c-field input,.c-field textarea,.c-field select{display:block;width:100%;margin:0;padding:10px 0 12px;
  font:inherit;font-size:17px;line-height:1.4;color:var(--ink);background:transparent;
  border:0;border-bottom:1px solid var(--rule-strong);border-radius:0;box-shadow:none;
  -webkit-appearance:none;appearance:none;
  transition:border-color .25s var(--ease),box-shadow .25s var(--ease)}
.c-field textarea{min-height:140px;resize:vertical;line-height:1.55}
.c-field textarea::placeholder{color:var(--ink-soft);opacity:1}
.c-field input:hover,.c-field textarea:hover,.c-field select:hover{border-bottom-color:var(--ink-soft)}
.c-field input:focus,.c-field textarea:focus,.c-field select:focus{outline:none;border-bottom-color:var(--ink);
  box-shadow:0 1px 0 0 var(--ink)}
/* the budget: a plain chooser with a small chevron, underlined like the rest */
.c-field select{padding-right:28px;cursor:pointer;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%2315171B' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 4px center}
.c-opt{font-weight:400;color:var(--ink-soft)}
/* how they would like to hear back: three choices, each a full tap high */
.c-set{margin:28px 0 0;padding:0;border:0;min-width:0}
.c-set legend{padding:0;margin-bottom:4px;font-family:var(--ui);font-size:14px;font-weight:500;color:var(--ink)}
.c-choices{display:flex;flex-wrap:wrap;gap:0 28px}
/* (the shared styles also set every label small, spaced and upper case, for
   the old dark form; these are written in plain sentence case) */
.c-choice{display:inline-flex;align-items:center;gap:10px;min-height:44px;margin:0;font-family:var(--ui);font-size:16px;
  font-weight:400;letter-spacing:normal;text-transform:none;color:var(--ink);cursor:pointer}
.c-choice input{flex:none;width:18px;height:18px;margin:0;accent-color:var(--ink);cursor:pointer}
/* the shared styles take the outline off every input (for the old dark form);
   the choices need it back to show keyboard focus */
.c-choice input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
/* the spam trap: off screen, out of the tab order, hidden from screen readers */
.c-hp{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}
.c-form{position:relative}
.c-field.is-err input,.c-field.is-err textarea{border-bottom-color:var(--s-err);box-shadow:0 1px 0 0 var(--s-err)}
.c-err{margin:8px 0 0;font-size:14px;color:var(--s-err)}
.c-err:empty{display:none}
.c-send{width:100%;justify-content:space-between;min-height:56px;margin-top:34px}
.c-send[aria-disabled="true"]{opacity:.7;cursor:progress}
.c-note{margin:14px 0 0;font-size:14px;line-height:1.55;color:var(--ink-soft)}

/* ================= 404 ================= */

.s-404{padding-bottom:var(--s-space)}
.s-404-links{display:flex;flex-wrap:wrap;gap:14px 32px;margin:clamp(40px,5vw,72px) 0 0;padding:0;list-style:none}
.s-404-links .s-link{font-size:17px}
/* the thanks page (after the Contact form): the call as the next step, then two ways on */
.s-thanks .s-stand{grid-column:1/-1;display:flex;align-items:flex-start;gap:12px;max-width:42ch}
.s-thanks-check{flex:0 0 24px;margin-top:.2em;color:#28734b}
.s-thanks-acts{display:flex;flex-wrap:wrap;align-items:center;gap:18px 32px;margin:clamp(40px,5vw,72px) 0 0}
.s-thanks-acts .s-link{font-size:17px}

/* ================= WORK: the portfolio (29 Sep, Step 4) =================
   Art-directed, not a grid of equals. The live client site leads, full
   width and first; the two previews follow as a pair; Sitewise's own site
   closes it, smaller, with its words beside it. Every project has the same
   five lines in the same order: name, status, the business and where, what
   Sitewise did, one link. The detail column starts at column 7, the line
   the pair and Sitewise's words also start on.
   The pictures link out too, but are not .w-frame: that class brings the
   jelly edge (index.html), and this page has no elastic motion. */

.wp{--wp-gap:clamp(80px,9.4vw,136px);display:grid;row-gap:var(--wp-gap)}
.wp-shot{position:relative;display:block;overflow:hidden;border-radius:6px;color:var(--ink);text-decoration:none}
/* a hairline inside the picture, so a white site still has an edge on the paper */
.wp-view::after{content:"";position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 0 1px rgba(21,23,27,.09)}
.wp-lead .wp-view{--vr:56.25cqw;aspect-ratio:16/9}
.wp-duo .wp-view{--vr:62.5cqw;aspect-ratio:16/10}
.wp-own .wp-view{--vr:75cqw;aspect-ratio:4/3}
/* Sitewise's own card plays its home page intro instead of a still */
.g-video{display:block;width:100%;height:100%;object-fit:cover;background:var(--paper)}

.wp-cap{margin-top:clamp(18px,1.8vw,26px)}
.wp-cap>*{margin:0}
.wp-name{font-family:var(--s-font);font-weight:500;font-size:clamp(1.5rem,1.2rem + .9vw,2rem);line-height:1.12;
  letter-spacing:-.02em}
.wp-lead .wp-name{font-size:var(--s-h2);line-height:1.05;letter-spacing:-.03em}
.wp-status{margin-top:10px;font-size:15px;color:var(--ink-soft)}
.wp-sector{margin-top:16px;font-size:16px;color:var(--ink);text-wrap:pretty}
.wp-did{margin-top:2px;font-size:16px;color:var(--ink-soft);text-wrap:pretty}
.wp-act{margin-top:14px;font-size:16px}
/* a larger target than the words, without moving them */
.wp-go{position:relative}
.wp-go::after{content:"";position:absolute;inset:-12px -8px}
.wp-go .wp-in{margin-left:8px}
.wp-go:hover .wp-in,.wp-go:focus-visible .wp-in{transform:translateX(3px)}
/* the picture and its link are one thing: pointing at either marks the link */
@media(hover:hover) and (pointer:fine){.wp-item:has(.wp-shot:hover) .wp-go{--ul:currentColor}}

@media(min-width:641px){
  /* the lead's words in two columns: who it is, and what was done */
  .wp-lead .wp-cap{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);
    align-items:baseline}
  .wp-lead .wp-name{grid-column:1/7;grid-row:1}
  .wp-lead .wp-status{grid-column:1/7;grid-row:2;margin-top:12px}
  .wp-lead .wp-sector{grid-column:7/-1;grid-row:1;margin:0}
  .wp-lead .wp-did{grid-column:7/-1;grid-row:2;margin-top:12px}
  .wp-lead .wp-act{grid-column:7/-1;grid-row:3}
  .wp-pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s-gap)}
  /* Sitewise: the picture on the left, its words beside it at the foot */
  .wp-own{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--s-gap);align-items:end}
  .wp-own .wp-shot{grid-column:1/6}
  .wp-own .wp-cap{grid-column:7/-1;margin:0}
}
/* below 1024px the pair shows each client's phone capture, square, so its
   words are not shrunk to nothing; the lead keeps its desktop capture to 641px */
@media(max-width:1023px){
  .wp-duo .wp-view{--vr:100cqw;aspect-ratio:1/1}
  .wp-own .wp-shot{grid-column:1/7}
}
@media(max-width:640px){
  .wp-lead .wp-view{--vr:125cqw;aspect-ratio:4/5}
  .wp-pair{display:grid;row-gap:var(--wp-gap)}
}

/* ================= HOME, below the hero =================
   The Work page's projects, reused (make-deploy.py home_main), then the two
   pages a visitor goes to next. #work beats the old home's own #work rule. */

#work.w-home{padding:clamp(88px,11vw,168px) 0 0}
.h-next{padding-top:var(--s-space)}
.h-next-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:56px var(--s-gap)}
.h-next-link{display:flex;flex-direction:column;align-items:flex-start;gap:14px;color:var(--ink);
  text-decoration:none}
.h-next-k{font-size:15px;color:var(--ink-soft)}
.h-next-t{max-width:15ch;font-family:var(--s-font);font-weight:500;font-size:var(--s-h2);line-height:1.08;
  letter-spacing:-.03em;transition:color .3s var(--ease)}
.h-next-go{margin-top:8px;font-size:15px;font-weight:500;text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.28em;text-decoration-color:color-mix(in srgb,currentColor 38%,transparent)}
.h-next-go span{display:inline-block;margin-left:8px;transition:transform .45s var(--s-ease)}
.h-next-link:hover .h-next-t,.h-next-link:focus-visible .h-next-t{color:var(--ink-soft)}
.h-next-link:hover .h-next-go span,.h-next-link:focus-visible .h-next-go span{transform:translateX(4px)}

/* ================= motion =================
   One system, three kinds of arrival:
   data-load  the first screen of a page, choreographed from the first frame in
              CSS alone: headline lines, then the line under it, then the rest.
              Nothing waits on the script, so nothing flashes, and if the script
              never runs the page still arrives. After a page transition the
              whole sequence starts a beat later, as the old page clears.
   data-r     everything further down, revealed as it reaches the screen
              (studio.js adds .is-wait only below the fold, then .is-in).
   lines      headlines, split into lines by studio.js and raised through a
              mask one after another, then put back as plain text.
   Reduced motion: none of it; the page is simply there. */

.ln{display:block;overflow:hidden;padding:0 .04em .16em;margin:0 -.04em -.16em}
.ln>span{display:block}

@keyframes mRise{from{opacity:0;transform:translate3d(0,var(--m-y),0)}}
@keyframes mFade{from{opacity:0}}
@keyframes mLine{from{transform:translate3d(0,108%,0)}to{transform:none}}
@keyframes mShow{to{opacity:1}}
/* lift: a picture arriving. Every picture on the site (the Work page, and
   Home's projects with their phones) comes in this way. It fades
   in from nothing, rising 24px and settling from 99% to full size, on one
   smooth ease-out with no overshoot. Only opacity, position and an even
   scale: never clipped, squashed, blurred or bent, so the picture is a clean
   rectangle on every frame. */
@keyframes mLift{from{opacity:0;transform:translate3d(0,var(--lift-y),0) scale(.99)}}
:root{--lift-y:24px;--m-lift:.9s}

html.vt-arrive{--m-arrive:.24s}

@media(prefers-reduced-motion:no-preference){
  [data-load="rise"]{animation:mRise var(--m-std) var(--e-out) calc(var(--m-arrive) + var(--d,0s)) backwards}
  [data-load="fade"]{animation:mFade var(--m-std) var(--e-out) calc(var(--m-arrive) + var(--d,0s)) backwards}
  [data-load="lift"]{animation:mLift var(--m-lift) var(--e-out4) calc(var(--m-arrive) + var(--d,0s)) backwards}
  /* the headline waits for its lines; if they never come it shows at 1.2s */
  .js [data-load="lines"]:not(.is-split):not(.is-done){opacity:0;animation:mShow 0s 1.2s forwards}
  [data-load="lines"].is-split .ln>span{
    animation:mLine var(--m-feat) var(--e-out4) calc(var(--m-arrive) + var(--d,0s) + var(--li,0) * var(--m-step)) both}
  .p-plan--pop[data-load]{--m-y:46px}

  /* the header settles in on a fresh load; after a page transition it is already there */
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .mark,
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a,
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-actions{animation:mNav .7s var(--e-out) backwards}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a:nth-child(2){animation-delay:.04s}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a:nth-child(3){animation-delay:.08s}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a:nth-child(4){animation-delay:.12s}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a:nth-child(5){animation-delay:.16s}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-actions{animation-delay:.2s}
  html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav-ink{animation:mFade .7s var(--e-out) .3s backwards}
}
@keyframes mNav{from{opacity:0;transform:translate3d(0,-8px,0)}}

[data-r="rise"].is-wait:not(.is-in){opacity:0;transform:translate3d(0,var(--m-y),0)}
[data-r="rise"].is-wait.is-in{transition:opacity var(--m-std) var(--e-out) var(--d,0s),
  transform var(--m-std) var(--e-out) var(--d,0s)}

[data-r="lines"].is-wait:not(.is-in) .ln>span{transform:translate3d(0,108%,0)}
[data-r="lines"].is-wait.is-in .ln>span{transition:transform var(--m-feat) var(--e-out4)
  calc(var(--d,0s) + var(--li,0) * var(--m-step))}


/* the portfolio's order when it arrives by scrolling (studio.js drops the
   inline delays of anything that starts below the fold) */
.wp-cap[data-r]{--d:.12s}
.wp-duo+.wp-duo .wp-shot[data-r]{--d:.1s}
.wp-duo+.wp-duo .wp-cap[data-r]{--d:.22s}
/* a picture waiting to arrive is already on its own layer, so its first
   frame is not spent preparing it (only pictures: text is cheap to draw) */
[data-r="lift"].is-wait:not(.is-in){opacity:0;transform:translate3d(0,var(--lift-y),0) scale(.99);will-change:transform,opacity}
/* Home's phones rise a little further than the screen behind them, and a
   beat later, so they read as sitting in front of it */
.w-phone-in[data-r="lift"]{--lift-y:34px}
[data-r="lift"].is-wait.is-in{transition:opacity var(--m-lift) var(--e-out4) var(--d,0s),
  transform var(--m-lift) var(--e-out4) var(--d,0s)}

/* revealed by keyboard focus: at once, no transition */
.is-now,.is-now *,.is-now ::before,.is-now ::after,.is-now::before{transition:none!important}

/* drawn lines: the FAQ rules and the footer's base rule run in from the left */
.s-faq.is-wait:not(.is-in) .s-acc::after,[data-r="rule"].is-wait:not(.is-in)::before{transform:scaleX(0)}
.s-faq.is-wait.is-in .s-acc::after{transition:transform 1s var(--e-io) calc(var(--d,0s) + .1s + var(--ai,0) * .07s)}
[data-r="rule"].is-wait:not(.is-in)>*{opacity:0}
[data-r="rule"].is-wait.is-in::before{transition:transform 1.1s var(--e-io) var(--d,0s)}
[data-r="rule"].is-wait.is-in>*{transition:opacity var(--m-std) var(--e-out) calc(var(--d,0s) + .3s)}

/* rows: a rule drawn in from the left, then what sits under it, one piece
   after another (About's steps and principles). Rows arriving together are
   staggered by studio.js through --bd. Without the script the rules are
   simply there. */
[data-r="row"]{position:relative}
[data-r="row"]::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:var(--rule-strong);transform-origin:0 50%}
[data-r="row"]>:nth-child(2){--ci:1}
[data-r="row"]>:nth-child(3){--ci:2}
[data-r="row"].is-wait:not(.is-in)::before{transform:scaleX(0)}
[data-r="row"].is-wait:not(.is-in)>*{opacity:0;transform:translate3d(0,var(--m-ry,18px),0)}
[data-r="row"].is-wait.is-in::before{transition:transform 1.1s var(--e-io) calc(var(--d,0s) + var(--bd,0s))}
[data-r="row"].is-wait.is-in>*{--t:calc(var(--d,0s) + var(--bd,0s) + .22s + var(--ci,0) * var(--m-step));
  transition:opacity var(--m-std) var(--e-out) var(--t),transform var(--m-feat) var(--e-out4) var(--t)}

/* the line under the current page's name (placed by make-deploy's inline script) */
.nav-ink{position:absolute;left:0;top:0;height:1px;background:var(--ink);pointer-events:none;
  view-transition-name:nav-ink}
html.has-ink .nav nav a:not(.nav-cta)[aria-current="page"]::after{transform:scaleX(0)}

/* project pictures lean in a touch under the pointer */
.w-frame .w-view picture,.w-frame .g-video{transition:transform .9s var(--e-out)}
@media(hover:hover) and (pointer:fine){
  .w-frame:hover .w-view picture,.w-frame:hover .g-video{transform:scale(1.03)}
}
/* the Work page's pictures: under a mouse, the site inside the frame grows
   by 1.2% over .7s and eases back the same way. The frame itself never
   moves or changes shape, and the growth stays clipped inside it. No hover
   on touch screens, and none with reduced motion. */
.wp-shot .w-view picture,.wp-shot .g-video{transition:transform .7s var(--e-out)}
@media(hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .wp-shot:hover .w-view picture,.wp-shot:hover .g-video{transform:scale(1.012)}
}
.p-plan .s-btn--line{transition:background-color var(--m-micro) var(--e-out),border-color var(--m-micro) var(--e-out),
  color var(--m-micro) var(--e-out)}
.p-plan:hover .s-btn--line{border-color:var(--ink)}

/* sections carry into one another: the page's opening block eases up and back
   as it leaves; the closing statement drifts a little against the scroll.
   Tied to the scroll itself, larger screens only, never with reduced motion. */
@supports (animation-timeline:view()){
  @media(min-width:761px) and (prefers-reduced-motion:no-preference){
    .s-top .s-head,.w-head{animation:mLeave linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
    @keyframes mLeave{to{transform:translate3d(0,-56px,0)}}   /* drifts up as it leaves; stays full colour (Freddie, 1 Oct: it read as grey) */
    .s-close-title{animation:mDrift linear both;animation-timeline:view();animation-range:cover 0% cover 100%}
    @keyframes mDrift{from{transform:translate3d(0,26px,0)}to{transform:translate3d(0,-26px,0)}}
    /* About: the large statements and step numbers drift a few pixels
       against the scroll. Never the paragraphs. (The hero has its own
       scroll sequence in studio.js.) */
    .a-drift{animation:aDrift linear both;animation-timeline:view();animation-range:cover 0% cover 100%}
    .a-n>span{animation:aNum linear both;animation-timeline:view();animation-range:cover 0% cover 100%}
    @keyframes aDrift{from{transform:translate3d(0,16px,0)}to{transform:translate3d(0,-16px,0)}}
    @keyframes aNum{from{transform:translate3d(0,10px,0)}to{transform:translate3d(0,-10px,0)}}
  }
}

/* smooth scrolling (Lenis) takes over from the browser's own smooth scroll */
html.lenis,html.lenis body{height:auto}
html.lenis{scroll-behavior:auto!important}
.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}

/* ================= smaller screens ================= */

@media(max-width:1000px){
  .s-foot-brand{grid-column:1/-1}
  .s-foot-pages{grid-column:1/7}
  .s-foot-touch{grid-column:7/-1}
}

@media(max-width:900px){
  .s-stand{grid-column:1/-1}
  .s-sechead>.s-h2,.s-sechead>:not(.s-h2){grid-column:1/-1}
  .s-sechead>.s-sechead-end{justify-self:start}
  .s-faq-grid>.s-h2,.s-faq{grid-column:1/-1}
  .s-faq{margin-top:20px}
  .s-close-title,.s-close-side{grid-column:1/-1}
  .s-close-side{margin-top:36px}

  .w-proj{grid-template-columns:minmax(0,1fr)}
  .w-proj .w-id,.w-proj .w-media,.w-proj .w-body{grid-column:1/-1;grid-row:auto;margin-top:0;padding-top:0}
  .w-proj .w-media{margin-top:28px;padding:0 0 12%}
  .w-proj .w-frame{width:86%;margin:0}
  .w-proj .w-phone{left:auto;right:0;top:auto;bottom:0;width:28%}
  .w-proj .w-body{margin-top:36px}

  .p-steps-list{grid-template-columns:minmax(0,1fr);row-gap:36px}

  .p-plans .s-sechead>.s-h2,.p-plans .s-sechead>.p-fees{grid-column:1/-1}

  .c-call,.c-form{grid-column:1/-1;grid-row:auto}
}

@media(max-width:900px) and (min-width:721px){
  .p-plan{padding-inline:18px}
  .p-amt{font-size:52px}
  .p-list li{font-size:14.5px}
  .p-cta{padding:0 16px}
}

@media(max-width:720px){
  .p-sheet{grid-template-columns:minmax(0,1fr);grid-template-rows:none}
  .p-plan{display:block;grid-row:auto}
  .p-plan+.p-plan{border-left:0;border-top:1px solid var(--rule)}
  .p-plan--pop::before{left:0;right:0}
  .p-top:empty{display:none}
}

@media(max-width:760px){
  .h-next-grid{grid-template-columns:minmax(0,1fr)}
  .p-work-row{grid-template-columns:minmax(0,1fr);row-gap:56px}

  /* the comparison: one block per feature, each plan named in its line */
  .p-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  .p-table,.p-table tbody,.p-table tr{display:block}
  .p-table tr{padding:14px 0 12px;border-top:1px solid var(--rule)}
  .p-table tbody th{display:block;width:auto;padding:0 0 8px;border:0}
  .p-table td{display:grid;grid-template-columns:104px minmax(0,1fr);gap:12px;width:auto;padding:4px 0;border:0}
  .p-table td::before{content:attr(data-plan);font-family:var(--ui);font-size:13px;color:var(--ink-soft)}
}

@media(max-width:1024px){:root{--m-y:26px}}
@media(max-width:900px){.nav-ink{display:none}}

@media(max-width:640px){
  :root{--m-y:18px}
  .s-foot-cols{padding-left:0;padding-right:0;row-gap:36px}
  .s-foot-pages,.s-foot-touch{grid-column:1/-1}
  .s-foot-col>a.s-foot-mail{word-break:break-all}
  .s-foot-base{flex-direction:column;gap:6px}
}

@media(pointer:coarse){
  .s-foot-col>a{min-height:44px}
}

/* Home project previews on phones: one entrance, without a second scroll-linked transform. */
@media(max-width:700px){
  #work.w-home .w-media{animation:none;transform:none}
}

/* About opening: the title itself is centred in the viewport below the nav. */
.a-h3 .a-h3-stage{display:grid;place-items:center;justify-content:center;min-height:calc(100svh - 76px);padding:48px 0}
.a-h3 .a-grid{display:block;position:relative}
.a-h3 .a-hl{text-align:center;width:100%}
.a-h3 .a-hl-line{width:100%}
.a-h3 .a-hl-in{text-align:left}
.a-h3 .a-h3-st{position:absolute;top:100%;left:50%;transform:translateX(-50%);width:min(34rem,90%);max-width:none;text-align:center;margin:36px 0 0;animation:none}
@media(max-width:640px){.a-h3 .a-h3-st{margin-top:28px;font-size:16px}}
@media(max-height:500px){.a-h3 .a-h3-stage{padding:32px 0 96px}.a-h3 .a-h3-st{margin-top:18px}}

/* The studio pages' opening (Freddie, 1 Oct): on Work, Services, Contact,
   Thanks and the 404 the heading and the line beneath are centred. While the
   heading rolls in, assets/heading-roll.js holds this block a screen tall so
   the writing sits mid-screen, then docks it to its own height. Without the
   script it is simply centred at the top. */
.s-sec .sw-open{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
.s-sec .sw-open>*{margin-left:auto;margin-right:auto}
.s-sec .sw-open>.w-sub,.s-sec .sw-open>.s-stand{margin-top:clamp(20px,2.6vw,36px)}
.s-sec .sw-open .a-hl-line{display:block;width:auto}
.s-sec .sw-open .a-hl-in{text-align:left}
.s-thanks .sw-open .s-stand{justify-content:center;text-align:left}
.s-thanks .s-thanks-acts,.s-404 .s-404-links{justify-content:center}
/* While a heading rolls in, the line beneath it waits, then fades up as the
   last letter settles (--sub-at, set by the heading's script), as Cappen's
   does: the letters stand up low before climbing into the line, and would
   otherwise meet it. Without the script it is simply there. */
@keyframes swSubIn{from{opacity:0;transform:translate3d(0,14px,0)}to{opacity:1;transform:none}}
@keyframes aSubIn{from{opacity:0;transform:translate(-50%,14px)}to{opacity:1;transform:translate(-50%,0)}}
@media(prefers-reduced-motion:no-preference){
  .sw-rolling>.w-sub,.sw-rolling>.s-stand{animation:swSubIn .5s cubic-bezier(.215,.61,.355,1) var(--sub-at,0ms) both}
  .a-h3-stage.a-rolling .a-h3-st{animation:aSubIn .5s cubic-bezier(.215,.61,.355,1) var(--sub-at,0ms) both}
}

/* Work portfolio: approved desktop feature and compact mobile previews.
   All changes are scoped to Work; Home's locked hero is unaffected. */
html[data-page="work"] .wp{--wp-gap:clamp(44px,5.5vw,80px)}
html[data-page="work"] .wp-own{align-items:center}
html[data-page="work"] .wp-own .wp-view{--vr:62.5cqw;aspect-ratio:16/10}
html[data-page="work"] .wp-own .wp-cap{max-width:38ch}
html[data-page="work"] .w-index+.s-close{margin-top:clamp(56px,6vw,88px)}
@media(min-width:1024px){
 html[data-page="work"] .w-index .w-head{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);align-items:center;column-gap:64px;text-align:left;min-height:0}
 html[data-page="work"] .w-index .w-head>*{grid-column:auto;margin-left:0;margin-right:0}
 html[data-page="work"] .w-index .w-title{font-size:clamp(64px,6vw,86px);max-width:none;text-align:left}
 html[data-page="work"] .w-index .w-sub{margin-top:0;max-width:34ch;text-align:left;font-size:20px}
 html[data-page="work"] .wp-lead{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.7fr);column-gap:clamp(40px,4.4vw,64px);align-items:center}
 html[data-page="work"] .wp-lead .wp-shot{grid-column:2;grid-row:1}
 html[data-page="work"] .wp-lead .wp-cap{grid-column:1;grid-row:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:0;max-width:32ch}
 html[data-page="work"] .wp-lead .wp-name{font-size:clamp(40px,4.4vw,60px);max-width:8ch}
 html[data-page="work"] .wp-lead .wp-status{margin-top:14px}
 html[data-page="work"] .wp-lead .wp-sector{margin-top:24px}
 html[data-page="work"] .wp-lead .wp-did{margin-top:18px;font-size:18px}
 html[data-page="work"] .wp-lead .wp-act{margin-top:28px}
 html[data-page="work"] .wp-lead .wp-view{--vr:50cqw;aspect-ratio:2/1}
 html[data-page="work"] .wp-pair{column-gap:clamp(40px,4.4vw,64px);align-items:start;padding-top:32px;border-top:1px solid var(--rule)}
 html[data-page="work"] .wp-duo+.wp-duo{margin-top:48px}
 html[data-page="work"] .wp-duo .wp-view{--vr:50cqw;aspect-ratio:2/1}
 html[data-page="work"] .wp-own{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:40px;max-width:1000px}
 html[data-page="work"] .wp-own .wp-shot{grid-column:1}
 html[data-page="work"] .wp-own .wp-cap{grid-column:2}
}
@media(max-width:1023px){
 html[data-page="work"] .wp-lead .wp-view,html[data-page="work"] .wp-duo .wp-view{--vr:62.5cqw;aspect-ratio:16/10}
}
@media(max-width:640px){
 html[data-page="work"] .w-index .w-head{margin-bottom:32px}
 html[data-page="work"] .w-index .w-title{font-size:38px}
 html[data-page="work"] .w-index .w-sub{font-size:16px;margin-top:18px}
 html[data-page="work"] .wp-lead .wp-cap{margin-top:20px}
 html[data-page="work"] .wp-lead .wp-name{font-size:30px}
 html[data-page="work"] .wp-status{font-size:14px}
 html[data-page="work"] .wp-sector{margin-top:14px}
 html[data-page="work"] .wp-did{margin-top:8px}
 html[data-page="work"] .wp-act{margin-top:18px}
}
@media(hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
 html[data-page="work"] .wp-shot{transition:translate .45s var(--e-out)}
 html[data-page="work"] .wp-shot:hover{translate:0 -4px}
 html[data-page="work"] .wp-go .w-go-ar{transition:transform .3s var(--e-out)}
 html[data-page="work"] .wp-go:hover .w-go-ar,html[data-page="work"] .wp-go:focus-visible .w-go-ar{transform:translate(3px,-3px)}
}

/* On phones, the project pictures on every page move as if a light breeze
   catches them (Freddie, 1 Oct: "just like the wind's blowing them around just
   a tad"): a drift of a few pixels and a third of a degree of tilt, on two
   cycles of different lengths so it never reads as a loop. It uses the
   separate translate and rotate properties, so it adds to the pictures' own
   reveal instead of replacing it. Still with reduced motion. */
@media(max-width:700px) and (prefers-reduced-motion:no-preference){
  .w-frame,.w-phone,.wp-shot{animation:bzDrift 6.8s ease-in-out infinite alternate,bzTilt 9.4s ease-in-out infinite alternate}
  .w-frame--thumb{animation-delay:-2.3s,-4.1s}
}
@keyframes bzDrift{from{translate:-2px 1.5px}to{translate:2.5px -2px}}
@keyframes bzTilt{from{rotate:-.35deg}to{rotate:.3deg}}

/* Services plans on phones, where they stack (Freddie, 1 Oct: Wise Three
   "just kind of pops in"): each card fades in as it arrives, with no wait,
   slowly and from only a little lower. The waits are for the desktop row. */
@media(max-width:900px){
  .p-plan[data-r="rise"]{--d:0s;--m-y:14px}
  .p-plan[data-r="rise"].is-wait.is-in{transition:opacity 1.1s cubic-bezier(.25,.6,.3,1),transform 1.2s cubic-bezier(.2,.7,.25,1)}
}


/* Contact: compact paired fields and a balanced information column.
   Scoped to Contact to preserve the homepage and other studio pages. */
html[data-page="contact"] .c-main{padding-top:clamp(40px,4.5vw,64px);padding-bottom:clamp(64px,7vw,96px)}
html[data-page="contact"] .c-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 24px;padding:clamp(24px,2.8vw,36px);align-content:start}
html[data-page="contact"] .c-form>*{grid-column:1/-1;min-width:0}
html[data-page="contact"] .c-form>.c-field--half{grid-column:span 1}
html[data-page="contact"] .c-field,html[data-page="contact"] .c-set,html[data-page="contact"] .c-send,html[data-page="contact"] .c-note{margin-top:0}
html[data-page="contact"] .c-form-plan{margin:0}
html[data-page="contact"] .c-field input,html[data-page="contact"] .c-field select{min-height:46px;font-size:16px}
html[data-page="contact"] .c-field textarea{min-height:110px;font-size:16px}
html[data-page="contact"] .c-send{min-height:52px}
html[data-page="contact"] .c-note{font-size:13px}
@media(min-width:901px){
 html[data-page="contact"] .c-grid{align-items:stretch;column-gap:clamp(36px,4vw,56px)}
 html[data-page="contact"] .c-call{grid-column:1/6;display:flex;flex-direction:column;justify-content:space-between;padding:20px 0;gap:40px}
 html[data-page="contact"] .c-form{grid-column:6/-1}
 html[data-page="contact"] .c-next,html[data-page="contact"] .c-direct{margin-top:0}
 html[data-page="contact"] .c-call .c-h{font-size:24px}
}
@media(max-width:900px){
 html[data-page="contact"] .c-grid{row-gap:48px}
 html[data-page="contact"] .c-next,html[data-page="contact"] .c-direct{margin-top:36px}
}
@media(max-width:640px){
 html[data-page="contact"] .c-form{grid-template-columns:minmax(0,1fr);gap:24px;padding:24px}
 html[data-page="contact"] .c-form>.c-field--half{grid-column:1/-1}
 html[data-page="contact"] .c-choices{gap:0 20px}
}

/* Contact sketch refinement: left-aligned opening and compact two columns. */
html[data-page="contact"] .c-top{padding-top:clamp(32px,4vw,56px)}
html[data-page="contact"] .c-top .s-head{padding-top:0;align-items:flex-start;justify-content:flex-start;text-align:left;min-height:0}
html[data-page="contact"] .c-top .s-head>*{margin-left:0;margin-right:0}
html[data-page="contact"] .c-top .s-title{max-width:none;font-size:clamp(38px,4.3vw,62px);font-weight:600;text-align:left}
html[data-page="contact"] .c-top .s-stand{max-width:none;margin-top:14px;font-size:clamp(16px,1.6vw,21px);text-align:left}
html[data-page="contact"] .c-main{padding-top:40px;padding-bottom:56px}
html[data-page="contact"] .c-form{gap:20px 24px;padding:28px}
html[data-page="contact"] .c-form-h{font-size:28px;font-weight:600}
html[data-page="contact"] .c-field textarea{min-height:104px;padding:10px 12px;border:1px solid var(--rule-strong);border-radius:2px}
html[data-page="contact"] .c-field select{padding-left:12px;border:1px solid var(--rule-strong);border-radius:2px}
html[data-page="contact"] .c-send{justify-content:center;gap:12px;min-height:48px}
@media(min-width:901px){
 html[data-page="contact"] .c-grid{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);column-gap:56px}
 html[data-page="contact"] .c-form{grid-column:2;grid-row:1}
 html[data-page="contact"] .c-call{grid-column:1;grid-row:1;padding:16px 0 24px;gap:36px}
 html[data-page="contact"] .c-call .c-h{font-size:28px;font-weight:600}
}
@media(max-width:640px){
 html[data-page="contact"] .c-form{padding:24px;gap:24px}
 html[data-page="contact"] .c-form-h{font-size:24px}
 html[data-page="contact"] .c-main{padding-top:32px}
}

/* Compact shared footer: closer alignment and smaller visual footprint. */
.s-foot{padding:28px 0 22px}
.s-foot .wrap::before{content:"";display:block;height:1px;background:var(--rule);margin-bottom:28px}
.s-foot-cols{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) minmax(0,1.2fr);gap:28px 40px;padding:0 0 28px;align-items:start}
.s-foot-brand,.s-foot-pages,.s-foot-touch{grid-column:auto;min-width:0}
.s-foot-brand .mark img{height:32px;width:auto}
.s-foot-sig{font-size:14px;max-width:25ch;margin-top:10px;line-height:1.45}
.s-foot-col>.s-label{font-size:13px;margin-bottom:8px}
.s-foot-links{column-gap:32px}
.s-foot-links>a,.s-foot-col>a{font-size:15px;min-height:36px}
.s-foot-col>a.s-foot-mail{word-break:normal;overflow-wrap:anywhere}
.s-foot-base{padding-top:16px}
.s-foot-base small{font-size:12px}
@media(max-width:900px){
 .s-foot-cols{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 32px}
 .s-foot-brand{grid-column:1/-1}
 .s-foot-pages{grid-column:1}
 .s-foot-touch{grid-column:2}
}
@media(max-width:640px){
 .s-foot{padding-top:20px}
 .s-foot-cols{grid-template-columns:minmax(0,1fr);row-gap:24px;padding-bottom:24px}
 .s-foot-brand,.s-foot-pages,.s-foot-touch{grid-column:1/-1}
 .s-foot-sig{max-width:none}
 .s-foot .wrap::before{margin-bottom:24px}
}
@media(pointer:coarse){.s-foot-links>a,.s-foot-col>a{min-height:44px}}

/* Footer sketch arrangement: brand left, small link groups at the right. */
@media(min-width:901px){
 .s-foot{padding-top:20px;padding-bottom:20px}
 .s-foot .wrap::before{margin-bottom:22px}
 .s-foot-cols{grid-template-columns:minmax(0,2fr) minmax(0,.65fr) minmax(0,1fr);gap:32px;padding-bottom:22px}
 .s-foot-brand .mark img{height:26px}
 .s-foot-sig{font-size:13px;max-width:32ch;margin-top:10px}
 .s-foot-pages .s-foot-links{display:flex;flex-direction:column;align-items:flex-start;gap:0}
 .s-foot-col>.s-label{font-size:13px;color:var(--ink);margin-bottom:6px}
 .s-foot-links>a,.s-foot-col>a{font-size:14px;min-height:28px}
 .s-foot-base{padding-top:12px}
}
@media(min-width:901px) and (pointer:coarse){.s-foot-links>a,.s-foot-col>a{min-height:44px}}

/* Contact opening: roll in near the top, settle, then reveal the page below. */
html[data-page="contact"] #contact-title{transform-origin:left top}
@media(prefers-reduced-motion:no-preference){
 html[data-page="contact"] .c-main,html[data-page="contact"] .s-foot{transition:opacity .65s ease,transform .65s var(--e-out)}
 html[data-page="contact"].c-intro-pending .c-main,html[data-page="contact"].c-intro-pending .s-foot{opacity:0;visibility:hidden;transform:translateY(18px)}
 html[data-page="contact"].c-intro-pending .c-top .s-stand{opacity:0!important;visibility:hidden}
}

/* =====================================================================
   3 Oct 2026 edits (Ellis). Everything below is additive and scoped, so
   it can be lifted into the source as one block.
   ===================================================================== */

/* ---- 1. the navigation's type ----
   The links were 12.5px uppercase in the system font, which on Windows is
   Segoe UI: it read as the operating system rather than the studio. Host
   Grotesk (variable, self-hosted, latin only, 20 KB) in sentence case, and
   a pill for Book a call whose arrow steps forward on hover. Monochrome, as
   the rest of the page: the hover darkens rather than turning blue. */
@font-face{font-family:'Host Grotesk';font-style:normal;font-weight:300 800;font-display:swap;
  src:url(/assets/fonts/host-grotesk.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
.nav nav{font-family:'Host Grotesk',var(--ui);font-size:15px;font-weight:500;letter-spacing:-.01em;text-transform:none;gap:30px}
.nav nav a:not(.nav-cta){color:#45484f}
.nav nav a:not(.nav-cta):hover,.nav nav a[aria-current="page"]{color:var(--ink)}
.nav-cta{display:inline-flex;align-items:center;gap:9px;
  font-family:'Host Grotesk',var(--ui);font-size:14.5px;font-weight:500;letter-spacing:-.005em;
  border-radius:999px;padding:11px 19px 11px 22px}
.nav-cta::before{content:"\2192";order:2;display:inline-block;transition:transform .35s var(--e-out)}
.nav-cta:hover{background:#2c2f35}
.nav-cta:hover::before,.nav-cta:focus-visible::before{transform:translateX(3px)}
@media(max-width:760px){.nav-cta{padding:10px 15px 10px 18px;font-size:13.5px;gap:7px}}
@media(prefers-reduced-motion:reduce){.nav-cta::before{transition:none}}
html:not([data-page="home"]):not(.vt-arrive):not(.nav-still) .nav .nav-links a:nth-child(6){animation-delay:.2s}
/* the phone menu in the same voice: it was 30px Instrument Serif with the
   current page in blue */
@media(max-width:900px){
  .nav.menu-open .nav-links{font-family:'Host Grotesk',var(--ui);font-size:26px;font-weight:500;letter-spacing:-.02em}
  .nav.menu-open .nav-links a:not(.nav-cta){color:#45484f}
  .nav.menu-open .nav-links a:not(.nav-cta):hover{color:var(--ink)}
  .nav.menu-open .nav-links a:not(.nav-cta)[aria-current="page"]{color:var(--ink);font-weight:650}
}

/* ---- 2. the laptop, smoother ----
   The screen's SVG loops repaint every frame. Inside the tilting stage they
   were repainting the stage's whole layer, under a 3D transform, alongside a
   60fps video. Each now has a layer of its own, so a repaint costs only the
   screen, and the loops rest whenever the laptop is off screen. */
.lap-stage{will-change:transform}
.lap-film{transform:translateZ(0);backface-visibility:hidden}
.lap-screen{will-change:transform;transform:translateZ(0);backface-visibility:hidden;contain:paint}
.js .lap:not(.in-view) .demo-svg *{animation-play-state:paused!important}

/* ---- 5. Home's projects: all three laid out like Ryan Fencing ----
   (4 Oct) Ellis likes Ryan's proportions for both pieces: a big, full-width
   browser and a phone 23% wide over its corner. Purely Pointing and Espiene
   had the words beside a narrower window, so either the phone had to be small
   or it stood as tall as the browser. Now all three share Ryan's arrangement:
   name and words in a row above, the capture full width below. Purely is
   mirrored (browser right, phone bottom-left) so the three alternate. */
@media(min-width:901px){
  .w-proj--b .w-id,.w-proj--c .w-id{grid-column:1/7;grid-row:1;align-self:end}
  .w-proj--b .w-body,.w-proj--c .w-body{grid-column:7/-1;grid-row:1;align-self:end;padding-top:0}
  .w-proj--b .w-media,.w-proj--c .w-media{grid-column:1/-1;grid-row:2;align-self:start;
    margin-top:clamp(32px,3.6vw,52px);padding-bottom:9%}
  .w-proj--b .w-frame{width:84%;margin-left:auto;margin-top:0}
  .w-proj--b .w-phone{left:0;right:auto;top:auto;bottom:0;width:23%}
  .w-proj--c .w-frame{width:84%;margin-left:0;margin-top:0}
  .w-proj--c .w-phone{left:auto;right:0;top:auto;bottom:0;width:23%}
}

/* ---- 6. Work: one even grid ----
   The four projects were a wide lead, a staggered pair and a smaller card
   pinned left, which read as placed at random. Now two by two, every card
   the same: a 16:10 capture, then name, status, business, what we did and
   one link, all on the same lines. The pair's wrapper steps aside
   (display:contents) so the markup is unchanged. */
html[data-page="work"] .wp{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:clamp(32px,4.4vw,64px);row-gap:clamp(64px,7vw,104px);align-items:start}
html[data-page="work"] .wp-pair{display:contents}
html[data-page="work"] .wp .wp-item{display:block;max-width:none;margin:0}
html[data-page="work"] .wp .wp-view{--vr:62.5cqw;aspect-ratio:16/10}
html[data-page="work"] .wp .wp-cap{display:block;margin-top:clamp(20px,2vw,28px);max-width:none}
html[data-page="work"] .wp .wp-name{font-size:clamp(26px,2.4vw,34px);line-height:1.1;letter-spacing:-.025em;max-width:none}
html[data-page="work"] .wp .wp-status{margin-top:10px}
html[data-page="work"] .wp .wp-sector{margin-top:16px;font-size:16px}
html[data-page="work"] .wp .wp-did{margin-top:2px;font-size:16px}
html[data-page="work"] .wp .wp-act{margin-top:16px}
@media(max-width:760px){html[data-page="work"] .wp{grid-template-columns:minmax(0,1fr)}}

/* ---- 2b. the cursor on the laptop's screen, as one movement ----
   Its route was six short keyframe legs, each easing to a near stop, so it
   moved stop-start: glide, stall, lurch, stall. That reads as a choppy, low
   frame rate cursor. Now it travels in a single leg. Horizontal and vertical
   ease on slightly different curves, which bends the path into a natural arc.
   It lands as the button lifts (40-42%) and clicks on the press (47-48%), so
   the rest of the choreography is unchanged. */
.d-cursor-y{transform-box:view-box}
@media(prefers-reduced-motion:no-preference){
  .d-cursor-g{animation:dCurX 7.2s infinite}
  .d-cursor-y{animation:dCurY 7.2s infinite}
}
@keyframes dCurX{
  0%,23% {opacity:0;transform:translateX(462px);animation-timing-function:cubic-bezier(.5,.02,.2,1)}
  27%    {opacity:1}
  42%    {transform:translateX(112px)}
  47.2%  {transform:translateX(112px);animation-timing-function:cubic-bezier(.45,0,1,1)}
  48.3%  {transform:translateX(112.6px);animation-timing-function:cubic-bezier(0,0,.25,1)}
  49.9%  {transform:translateX(112px)}
  78%    {opacity:1;transform:translateX(112px);animation-timing-function:cubic-bezier(.4,0,.7,1)}
  86%    {opacity:0;transform:translateX(116.5px)}
  100%   {opacity:0;transform:translateX(462px)}}
@keyframes dCurY{
  0%,23% {transform:translateY(338px);animation-timing-function:cubic-bezier(.3,.1,.15,1)}
  42%    {transform:translateY(222px)}
  47.2%  {transform:translateY(222px);animation-timing-function:cubic-bezier(.45,0,1,1)}
  48.3%  {transform:translateY(223.4px);animation-timing-function:cubic-bezier(0,0,.25,1)}
  49.9%  {transform:translateY(222px)}
  78%    {transform:translateY(222px);animation-timing-function:cubic-bezier(.4,0,.7,1)}
  86%    {transform:translateY(226.5px)}
  100%   {transform:translateY(338px)}}

/* ---- phones: easier tapping (4 Oct) ----
   Several text links were 23-30px tall, under the ~44px a thumb needs. Each
   gets an invisible, larger touch area from a pseudo-element, so the text and
   its underline (a background at the foot of the link) do not move at all.
   Touch screens only; the mouse layout is untouched. */
@media(pointer:coarse){
  .s-link{position:relative}
  .s-link::before{content:"";position:absolute;inset:-11px -6px}
  .nav .mark{position:relative}
  .nav .mark::before{content:"";position:absolute;inset:-7px -6px}
}
@media(max-width:700px){
  .hero-more .kick{font-size:12px}
}
