/*
Theme Name: Squareposh
Theme URI: https://www.squareposh.com
Author: Squareposh
Description: Editorial monochrome theme for Squareposh — Squarespace and WordPress websites for brands that mean business.
Version: 2.0.0
License: GNU General Public License v2 or later
Text Domain: squareposh
*/

/* =========================================================================
   1. TOKENS — warm monochrome. No saturated accent; restraint is the luxury.
   ========================================================================= */
/* =========================================================================
   BRAND TYPEFACE — NeulisAlt, from the Squareposh brand kit.
   OTF is served directly: the kit ships .otf and there is no font compiler on
   this host. ~68KB a weight, so only the five in use are loaded.
   ========================================================================= */
@font-face{font-family:'NeulisAlt';src:url('assets/fonts/neulisalt-light.otf') format('opentype');
  font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'NeulisAlt';src:url('assets/fonts/neulisalt-regular.otf') format('opentype');
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'NeulisAlt';src:url('assets/fonts/neulisalt-italic.otf') format('opentype');
  font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'NeulisAlt';src:url('assets/fonts/neulisalt-medium.otf') format('opentype');
  font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'NeulisAlt';src:url('assets/fonts/neulisalt-semibold.otf') format('opentype');
  font-weight:600;font-style:normal;font-display:swap}

:root{
  /* Sampled from the brand assets themselves, not guessed. */
  --cream:    #F8F4F4;   /* cream_Pattern       */
  --lightbrn: #E0D4CC;   /* light brown         */
  --brown:    #BCA898;   /* brown               */
  --green:    #4C4C44;   /* "green" deep olive  */
  --black:    #040404;   /* black               */

  --bone:   #F8F4F4;
  --shell:  #FFFFFF;
  --greige: #E0D4CC;
  --stone:  #BCA898;
  --ink:    #040404;
  --char:   #4C4C44;
  --cocoa:  #382C24;   /* deep espresso — the brand brown at low lightness */
  --mute:   #8C7F73;

  --line:      rgba(4,4,4,.14);
  --line-soft: rgba(4,4,4,.08);
  --line-dark: rgba(248,244,244,.20);

  /* NeulisAlt is the brand typeface and carries the whole site. --display is
     the specialty face, used only for italic accent words inside a headline
     (see inc/fonts.php). --serif is aliased so legacy references follow suit. */
  --sans:    "NeulisAlt", "Jost", "Helvetica Neue", Arial, sans-serif;
  --serif:   "NeulisAlt", "Jost", "Helvetica Neue", Arial, sans-serif;
  --display: "Bodoni Moda", Georgia, serif;
  --sand:  var(--brown);   /* accent over imagery — real brand brown */

  --container: 1340px;
  --wide: 1660px;
  --gutter: clamp(20px, 4.4vw, 64px);
  --pill: 100px;

  --ease: cubic-bezier(.22,.61,.36,1);
  --slow: cubic-bezier(.16,1,.3,1);
}

/* =========================================================================
   2. BASE
   ========================================================================= */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;background:var(--bone);color:var(--ink);
  /* 300 at 16px read as grey mush on screen; editorial body copy wants a real
     regular weight and a slightly larger size. */
  font-family:var(--sans);font-size:17px;font-weight:400;line-height:1.7;
  /* clip, NOT hidden: `hidden` makes body a scroll container and silently
     kills every position:sticky on the page. `clip` contains overflow the
     same way without establishing one. */
  overflow-x:clip;-webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
ul{margin:0;padding:0;list-style:none}
h1,h2,h3,h4{margin:0;font-family:var(--sans);font-weight:500;line-height:1.14;letter-spacing:-.02em}
p{margin:0 0 1.1em}
p:last-child{margin-bottom:0}
::selection{background:var(--ink);color:var(--shell)}

.container{max-width:var(--container);margin:0 auto;padding-inline:var(--gutter)}
.container--wide{max-width:var(--wide)}
.section{padding-block:clamp(70px,9vw,140px)}
.section--tight{padding-block:clamp(44px,5vw,80px)}

.bg-bone{background:var(--bone)}
.bg-shell{background:var(--shell)}
.bg-greige{background:var(--greige)}
.bg-ink{background:var(--ink);color:var(--shell)}
.bg-char{background:var(--char);color:var(--shell)}
/* Espresso — the brand brown taken all the way down. Used with .bg-ink rather
   than instead of it, so every `.bg-ink .field / .lead / .eyebrow` rule that
   styles dark sections keeps applying to it. */
.bg-ink.bg-cocoa{background:var(--cocoa)}

/* film grain — stops flat colour reading as cheap */
body::after{
  content:"";position:fixed;inset:0;z-index:400;pointer-events:none;opacity:.035;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

/* =========================================================================
   3. TYPE
   ========================================================================= */
.eyebrow{
  /* was .62rem (9.9px) with .34em tracking — legible only if you already knew
     what it said. Bigger, tighter, darker. */
  font-family:var(--sans);font-weight:500;text-transform:uppercase;
  letter-spacing:.2em;font-size:.78rem;color:var(--ink);opacity:.75;
  margin:0 0 1.6rem;display:block;
}
.bg-ink .eyebrow,.bg-char .eyebrow{color:rgba(248,244,244,.55)}

/* Sized for NeulisAlt, which sets smaller on the em than the old Bodoni. */
.d-hero{font-size:clamp(2.1rem,4.8vw,4.5rem);line-height:1.1;letter-spacing:-.025em;text-transform:none}
.d-xl{font-size:clamp(1.8rem,3.8vw,3.3rem);line-height:1.14;letter-spacing:-.022em}
.d-lg{font-size:clamp(1.55rem,3vw,2.5rem);line-height:1.18;letter-spacing:-.018em}
.d-md{font-size:clamp(1.2rem,1.9vw,1.7rem);line-height:1.22;letter-spacing:-.012em}
.it{font-family:var(--display);font-style:normal}

.lead{font-size:clamp(.95rem,1.1vw,1.05rem);color:var(--mute);max-width:56ch;line-height:1.85}
.bg-ink .lead,.bg-char .lead{color:rgba(248,244,244,.62)}
.tc{text-align:center}
.mx{margin-inline:auto}

.rule{height:1px;background:var(--line);border:0;margin:0}
.bg-ink .rule,.bg-char .rule{background:var(--line-dark)}

/* =========================================================================
   4. BUTTONS
   ========================================================================= */
.btn{
  --fg:var(--ink); --bd:var(--ink);
  display:inline-flex;align-items:center;gap:.9em;
  font-family:var(--sans);font-weight:400;text-transform:uppercase;
  letter-spacing:.16em;font-size:.76rem;
  padding:1.15em 2.1em;border:1px solid var(--bd);border-radius:var(--pill);
  color:var(--fg);background:transparent;cursor:pointer;line-height:1;white-space:nowrap;
  position:relative;overflow:hidden;transition:color .5s var(--ease),border-color .5s var(--ease);
}
.btn::before{
  content:"";position:absolute;inset:0;background:var(--ink);z-index:0;
  transform:scaleX(0);transform-origin:left;transition:transform .55s var(--slow);
}
.btn:hover::before{transform:scaleX(1)}
.btn:hover{color:var(--shell)}
.btn > *{position:relative;z-index:1}
.btn svg{width:14px;height:14px;transition:transform .5s var(--ease)}
.btn:hover svg{transform:translateX(4px)}
.btn--solid{--fg:var(--shell);--bd:var(--ink);background:var(--ink)}
.btn--solid::before{background:var(--shell)}
.btn--solid:hover{color:var(--ink)}
.btn--light{--fg:var(--shell);--bd:rgba(248,244,244,.42)}
.btn--light::before{background:var(--shell)}
.btn--light:hover{color:var(--ink);border-color:var(--shell)}
.btn--sm{padding:.95em 1.6em;font-size:.72rem}

.ulink{
  font-family:var(--sans);font-weight:500;text-transform:uppercase;letter-spacing:.16em;
  font-size:.76rem;display:inline-flex;align-items:center;gap:.7em;
  padding-bottom:.5em;position:relative;
}
.ulink::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;
  transform-origin:right;transition:transform .5s var(--slow)}
.ulink:hover::after{transform:scaleX(0);transform-origin:left}
.ulink svg{width:13px;height:13px}

/* =========================================================================
   5. HEADER — bordered cells, not floating links
   ========================================================================= */
.site-header{
  position:fixed;inset:0 0 auto 0;z-index:120;background:transparent;
  transition:background .5s var(--ease),border-color .5s var(--ease);
  border-bottom:1px solid transparent;
}
.site-header.scrolled{background:var(--shell);border-bottom-color:var(--line)}
.hbar{display:flex;align-items:stretch;justify-content:space-between;gap:0}
.brand{display:flex;flex-direction:column;justify-content:center;padding:18px 0;line-height:1}
.brand__name{font-family:var(--serif);font-size:1.4rem;letter-spacing:.02em;text-transform:uppercase}
.brand__name i{font-style:italic;text-transform:none;letter-spacing:-.01em}
.brand__sub{font-family:var(--sans);font-size:.66rem;font-weight:500;letter-spacing:.22em;text-transform:uppercase;color:var(--mute);margin-top:.5em}

/* Brand logo. Two colourways stacked; only one is shown at a time. */
.brand{position:relative}
.brand__logo{height:38px;width:auto;display:block;transition:opacity .4s var(--ease)}
.brand__logo--light{position:absolute;left:0;top:50%;transform:translateY(-50%);opacity:0;pointer-events:none}
/* The white mark is for headers floating over a photograph — project pages.
   The homepage hero is cream now, so it keeps the dark mark throughout. */
@media(max-width:820px){ .brand__logo{height:30px} }

.nav{display:flex;align-items:stretch}
.nav a{
  display:flex;align-items:center;padding:0 clamp(14px,1.7vw,26px);
  font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.17em;
  border-left:1px solid var(--line);position:relative;transition:color .4s var(--ease);
}
.nav a:last-child{border-right:1px solid var(--line)}
.nav a::before{content:"";position:absolute;inset:auto 0 0 0;height:1px;background:currentColor;
  transform:scaleX(0);transition:transform .45s var(--slow)}
/* nav underline removed — hover softens instead (see motion block) */
.site-header:not(.scrolled) .nav a{border-color:var(--line-soft)}

.hcta{display:flex;align-items:center;gap:12px;padding-left:clamp(10px,1.4vw,20px)}
.burger{display:none;width:42px;height:42px;border:0;background:none;cursor:pointer;padding:11px;z-index:130}
.burger span{display:block;height:1px;background:var(--ink);transition:.4s var(--ease)}
.burger span+span{margin-top:6px}
.burger[aria-expanded="true"] span{background:var(--shell)}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* =========================================================================
   6. HERO
   ========================================================================= */
/* The hero must fit one screen. It was running to 1088px against a 639px
   viewport, so the headline and CTA sat below the fold on open. */
/* The hero must fit one screen. It was running to 1088px against a 639px
   viewport, so the headline and CTA sat below the fold on open. */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;
  padding-top:clamp(96px,7.6vw,118px);padding-bottom:clamp(28px,2.6vw,38px);overflow:hidden}
/* .hero is a flex container, so its .container child is a flex item and was
   shrink-to-fit (1069px inside a 1521px section) — which squeezed the headline
   column and forced the display type to wrap. Make it fill the row. */
.hero > .container{flex:1 1 auto;width:100%}

/* =========================================================================
   6b. SPLIT HERO — words on the left, one photograph bleeding off the right
   ========================================================================= */
.hero.hero--split{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.88fr);
  /* Capped: a full 100svh on a tall screen left the column floating in space.
     The hero should fill the screen, not exceed what the words need. */
  align-items:stretch;min-height:min(100svh,820px);padding:0;
  /* The espresso from the closing CTA — it picks up the wood and leather in
     the photograph and lets the picture run to the top behind the header. */
  background:var(--cocoa);color:var(--cream);overflow:hidden;
}
/* The left column carries the site gutter itself, so the headline lines up
   with every .container below it while the photograph still reaches the edge
   of the screen. max() does the job a container would have done. */
.hero__col{
  display:flex;flex-direction:column;justify-content:center;
  padding-top:clamp(112px,11vw,148px);padding-bottom:clamp(40px,4.6vw,70px);
  padding-left:max(var(--gutter),calc((100vw - var(--wide)) / 2 + var(--gutter)));
  padding-right:clamp(26px,4vw,78px);
}
/* Runs to all four edges of its column, including up behind the header. */
.hero__figure{
  position:relative;margin:0;overflow:hidden;background:var(--greige);
}
/* The nav crosses this column, so the top of the photograph is deepened back
   towards the espresso beside it — the cream nav stays readable without a band
   of flat colour cutting the image off. */
.hero__figure::after{
  content:"";position:absolute;left:0;right:0;top:0;z-index:1;pointer-events:none;
  height:clamp(96px,11vw,158px);
  background:linear-gradient(180deg,rgba(56,44,36,.88) 0%,rgba(56,44,36,.52) 52%,rgba(56,44,36,0) 100%);
}
.hero__figure img,.hero__figure .sqp-ph{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 52%;
}
/* A hairline of the brand brown down the seam between words and image. */
.hero__figure::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:1px;background:var(--line);z-index:2;
}
/* Sized under .d-hero's cap: at 4.5rem "Worth Remembering" overran the column
   and dropped the Bodoni accent word onto a third line of its own. */
.hero--split h1{font-size:clamp(2rem,4.05vw,4rem);text-wrap:balance;
  margin-bottom:clamp(12px,1.5vw,20px);color:var(--cream)}
.hero--split h1 .it{color:var(--brown)}
.hero--split .eyebrow{color:var(--brown);opacity:1;margin-bottom:clamp(.9rem,1.3vw,1.25rem)}
.hero--split .lead{margin-top:0;max-width:44ch;color:rgba(248,244,244,.7)}
.hero--split .hero__cta{margin-top:clamp(20px,2.2vw,30px)}
.hero--split .hero__meta{
  display:flex;justify-content:flex-start;gap:clamp(20px,3vw,44px);
  margin:clamp(22px,2.6vw,38px) 0 0;padding:1rem 0 0;
  border-bottom:0;border-top:1px solid var(--line-dark);
  font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:rgba(248,244,244,.6);
}
/* Header floats over the espresso panel, so it takes the light colourway until
   it goes solid on scroll. */
/* A hairline of white under the whole bar while it floats over the dark hero,
   so the logo, nav and CTA read as one ruled band. */
body.home .site-header:not(.scrolled){color:var(--cream);border-bottom-color:rgba(248,244,244,.9)}
body.single-project .site-header:not(.scrolled){border-bottom-color:rgba(248,244,244,.9)}
body.home .site-header:not(.scrolled) .nav a{color:var(--cream)}
body.home .site-header:not(.scrolled) .brand__logo--dark{opacity:0}
body.home .site-header:not(.scrolled) .brand__logo--light{opacity:1}
body.home .site-header:not(.scrolled) .btn--solid{
  background:transparent;border-color:rgba(248,244,244,.55);color:var(--cream)}
body.home .site-header:not(.scrolled) .btn--solid:hover{
  background:var(--cream);border-color:var(--cream);color:var(--ink)}
body.home .site-header:not(.scrolled) .burger span{background:var(--cream)}

/* Straddles the hero / second-section boundary on the right. Lives inside
   .sec--float, which allows overflow — .hero clips its own children. Cream,
   because the bottom-right of the hero is the photograph. */
.seal--straddle{
  position:absolute;top:0;right:clamp(18px,5vw,90px);bottom:auto;
  /* Sits mostly up in the hero rather than half-and-half on the seam. */
  transform:translateY(-78%);z-index:6;color:var(--cream);
}

/* Solid cream pill for use ON a photograph — the project-page "Visit site". */
.btn--cream{background:var(--shell);border-color:var(--shell);color:var(--ink)}
.btn--cream::before{background:transparent}
.btn--cream:hover{background:transparent;color:var(--shell);border-color:var(--shell)}

/* The header no longer floats over a dark photograph on the homepage, so the
   white colourway that used to be forced here would be invisible on cream.
   Project pages still open on a full-bleed image and do want it. */
body.single-project .site-header:not(.scrolled){color:var(--shell)}
body.single-project .site-header:not(.scrolled) .brand__name,
body.single-project .site-header:not(.scrolled) .brand__sub,
body.single-project .site-header:not(.scrolled) .nav a{color:var(--shell)}
body.single-project .site-header:not(.scrolled) .brand__sub{color:rgba(248,244,244,.7)}
body.single-project .site-header:not(.scrolled) .btn--solid{
  background:transparent;border-color:rgba(248,244,244,.55);color:var(--shell)}
body.single-project .site-header:not(.scrolled) .btn--solid:hover{
  background:var(--shell);border-color:var(--shell);color:var(--ink)}
body.single-project .site-header:not(.scrolled) .burger span{background:var(--shell)}
body.single-project .site-header:not(.scrolled) .brand__logo--dark{opacity:0}
body.single-project .site-header:not(.scrolled) .brand__logo--light{opacity:1}

@media(max-width:900px){
  /* Stacked: the words come first, then the photograph fills whatever is left
     of the first screen. The hero is exactly one viewport tall, so the image
     is part of the opening view instead of hiding below the fold. */
  .hero.hero--split{grid-template-columns:1fr;grid-template-rows:auto 1fr;min-height:100vh;min-height:100svh}
  .hero__col{
    padding-top:clamp(96px,22vw,132px);padding-bottom:clamp(24px,5vw,40px);
    padding-inline:var(--gutter);
  }
  .hero--split .hero__meta{margin-top:clamp(16px,2vw,24px)}
  .hero__figure{margin-top:0;min-height:clamp(230px,36svh,430px)}
  /* The header never crosses the photograph down here, so the espresso fade
     only has to soften the seam, not carry the nav. Full strength buried the
     visible slice of the image and the hero read as a plain brown panel. */
  .hero__figure::after{
    height:64px;
    background:linear-gradient(180deg,rgba(56,44,36,.55) 0%,rgba(56,44,36,0) 100%);
  }
  .hero__figure::before{display:none}
  .seal--straddle{display:none}
}
@media(max-width:640px){
  .hero--split .hero__meta{flex-direction:column;gap:8px}
  .hero--split .hero__cta .btn{width:100%;justify-content:center}
}
.hero h1{margin-bottom:clamp(20px,2.6vw,34px)}
/* inline, not block: the headline is two balanced lines now, so the italic
   word must sit beside its partner rather than claiming a line of its own. */
.hero h1 .it{display:inline;text-transform:none;letter-spacing:-.01em}
.hero__meta{display:flex;justify-content:space-between;gap:20px}
.hero__cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:1.5rem}

/* rotating seal */
.seal{position:absolute;right:0;top:clamp(10px,3vw,40px);z-index:3;width:clamp(88px,9vw,124px);aspect-ratio:1}
.seal svg.seal__ring{width:100%;height:100%;animation:spin 26s linear infinite}
.seal__dot{position:absolute;inset:0;display:grid;place-items:center}
.seal__dot svg{width:15px;height:15px}
@keyframes spin{to{transform:rotate(360deg)}}
.seal text{font-family:var(--sans);font-size:9.2px;letter-spacing:.22em;text-transform:uppercase;fill:currentColor}

/* =========================================================================
   7. LOGO BAR
   ========================================================================= */
.logobar{display:grid;grid-template-columns:repeat(5,1fr);align-items:center;border-block:1px solid var(--line)}
.logobar span{
  padding:clamp(22px,2.6vw,34px) 10px;text-align:center;
  font-family:var(--serif);font-size:clamp(.85rem,1.25vw,1.1rem);letter-spacing:.12em;
  text-transform:uppercase;color:var(--mute);border-left:1px solid var(--line);
  transition:color .4s var(--ease);
}
.logobar span:first-child{border-left:0}
.logobar span:hover{color:var(--ink)}

/* =========================================================================
   8. SPLIT
   ========================================================================= */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,5vw,84px);align-items:center}
.split--text{grid-template-columns:1.06fr .94fr}
.frame{position:relative;overflow:hidden;aspect-ratio:4/5}
.frame img,.frame .sqp-ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.06)}
.frame--wide{aspect-ratio:3/2}
.frame--sq{aspect-ratio:1}

/* Section header with a photograph beside it — the copy sets the width, the
   image fills whatever is left. Used on the dark services section. */
.sechead{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.82fr);
  gap:clamp(28px,4vw,72px);align-items:end;margin-bottom:clamp(40px,5vw,72px);
}
.sechead > div{max-width:660px}
.sechead__media{position:relative;margin:0;aspect-ratio:3/2;overflow:hidden;background:var(--char)}
.sechead__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
@media(max-width:900px){
  .sechead{grid-template-columns:1fr;gap:clamp(22px,4vw,34px)}
  .sechead__media{aspect-ratio:16/10}
}

/* =========================================================================
   9. SERVICE COLUMNS
   ========================================================================= */
.cols3{display:grid;grid-template-columns:repeat(3,1fr)}
.col3{padding:clamp(30px,3.4vw,54px) clamp(22px,2.4vw,44px);border-left:1px solid var(--line-dark)}
.col3:first-child{border-left:0;padding-left:0}
.col3:last-child{padding-right:0}
.col3__n{font-family:var(--serif);font-size:.8rem;letter-spacing:.16em;opacity:.5;display:block;margin-bottom:1.6rem}
.col3 h3{font-size:clamp(1.2rem,1.8vw,1.5rem);margin-bottom:.9rem}
.col3 p{font-size:.9rem;opacity:.62;margin-bottom:1.6rem}

/* =========================================================================
   10. WORK
   ========================================================================= */
/* Four projects in a 2x2 — three across left an odd gap on every breakpoint,
   and the bigger cards show the artwork properly. */
.works{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(18px,2.4vw,34px)}
.work{display:block;position:relative}
.work__n{font-family:var(--serif);font-size:.78rem;letter-spacing:.18em;color:var(--mute);display:block;margin-bottom:.9rem}
/* 2/1 matches the supplied card artwork, and the cards stay in full colour —
   the theme's grayscale treatment would flatten the very branding they show. */
.work__media{position:relative;overflow:hidden;aspect-ratio:2/1;background:var(--greige);
  border:1px solid var(--black)}
.work__media img,.work__media .sqp-ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform 1.1s var(--slow)}
.work:hover .work__media img{transform:scale(1.04)}
.work__body{padding-top:1.1rem;border-top:1px solid var(--line);margin-top:1.1rem;
  display:flex;justify-content:space-between;align-items:baseline;gap:16px}
.work h3{font-size:clamp(1.05rem,1.5vw,1.3rem);text-transform:uppercase;letter-spacing:.03em}
.work__meta{font-size:.7rem;text-transform:uppercase;letter-spacing:.14em;color:var(--mute);white-space:nowrap}

/* ---- Work page + single project ---- */
.works--all{grid-template-columns:repeat(2,1fr);gap:clamp(24px,3vw,48px)}
.page-head{padding-bottom:clamp(28px,3vw,44px)}

/* Project hero: the card artwork fills the screen, the title sits on it. */
.proj__hero{
  position:relative;min-height:clamp(420px,72svh,700px);display:grid;place-items:center;
  padding-top:clamp(110px,12vw,170px);padding-bottom:clamp(38px,5vw,72px);
  overflow:hidden;isolation:isolate;color:var(--cream);text-align:center;
}
.proj__heroimg{position:absolute;inset:0;z-index:0}
.proj__heroimg img{width:100%;height:100%;object-fit:cover;display:block}
.proj__hero::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,4,4,.42) 0%,rgba(4,4,4,.18) 40%,rgba(4,4,4,.78) 100%);
}
/* Flat espresso, no photograph and no scrim — the artwork already has a
   wordmark on it, so the project title sat on top of a second title. */
.proj__hero--flat{background:var(--cocoa);min-height:clamp(320px,52svh,480px)}
.proj__hero--flat::after{display:none}
.proj__heroinner{position:relative;z-index:2;width:100%}
.proj__back{
  display:inline-flex;align-items:center;gap:.6em;margin-bottom:1.4rem;
  font-size:.74rem;letter-spacing:.18em;text-transform:uppercase;color:rgba(248,244,244,.8);
}
.proj__back svg{width:13px;height:13px;transform:rotate(180deg)}
.proj__hero h1{color:var(--cream);max-width:16ch;margin-inline:auto}
.proj__service{
  margin:.9rem 0 0;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--brown);
}
.proj__visit{margin-top:2rem}

/* Facts strip under the hero */
.proj__facts{background:var(--ink);color:var(--cream);padding-block:clamp(22px,2.6vw,34px)}
.proj__facts{text-align:center}
.proj__facts dl{display:flex;flex-wrap:wrap;gap:clamp(28px,6vw,86px);margin:0;justify-content:center}
.proj__facts dt{
  font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(248,244,244,.5);margin-bottom:.35rem;
}
.proj__facts dd{margin:0;font-size:.98rem;font-weight:500}
.proj__facts a{border-bottom:1px solid var(--brown);padding-bottom:2px}

.proj__body{padding-top:clamp(48px,6vw,90px)}
.proj__body .rich{max-width:none;text-align:left}

/* Write-up sticks on the left, screenshots scroll past on the right. */
.projlayout{
  display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.5fr);
  gap:clamp(28px,4vw,72px);align-items:start;
}
.projlayout__text{position:sticky;top:clamp(96px,12vh,150px)}
/* Three selectors deep on purpose: `.rich .brief` further down sets the
   auto-fit grid, which inside this narrow sticky column collapsed to two
   cramped 230px tracks. In the column the brief reads as a ruled list. */
.rich .projlayout__text .brief{
  display:block;width:auto;max-width:none;margin:0 0 2.4rem;padding:0;
  border-top:1px solid var(--line);border-bottom:0;
}
.projlayout__text .brief__row{
  display:grid;grid-template-columns:minmax(0,7.5rem) minmax(0,1fr);
  gap:clamp(12px,1.4vw,26px);align-items:baseline;
  padding:clamp(14px,1.5vw,20px) 0;border-bottom:1px solid var(--line);
}
.projlayout__text .brief__row + .brief__row{margin-top:0}
.projlayout__text .brief__row h3{margin:0}
.projlayout__text .brief__row p{font-size:.98rem;line-height:1.7}
@media(max-width:1200px){
  .projlayout__text .brief__row{grid-template-columns:1fr;gap:.5rem}
}
.projlayout__text h2{margin:0 0 .8em;font-size:clamp(1.2rem,1.8vw,1.55rem)}
/* `ul{list-style:none}` is set globally, so these items had no marker at all —
   just an indent. A ruled dash in ink, rather than a disc. */
.projlayout__text ul{margin:0;padding-left:0;list-style:none}
.projlayout__text li{position:relative;margin:.55em 0;padding-left:1.5em}
.projlayout__text li::before{
  content:"";position:absolute;left:0;top:.72em;width:9px;height:1px;
  background:var(--ink);opacity:.45;
}

/* Screenshots stack full width in their column. */
.projlayout__media{display:grid;gap:clamp(20px,2.6vw,40px);max-width:none}
.projlayout__media .shot{margin:0}
.projlayout__media .shot__frame img{width:100%;height:auto}
.projlayout__media .shot-scroll{height:min(78svh,760px);margin:0}

@media(max-width:900px){
  .projlayout{grid-template-columns:1fr;gap:34px}
  .projlayout__text{position:static}
}
.proj__cta{display:flex;align-items:center;justify-content:center;gap:24px;flex-wrap:wrap;text-align:center}
.proj__cta h2{color:var(--cream);margin:0}

@media(max-width:820px){
  .proj__facts dl{gap:22px 34px}
  .proj__hero{min-height:clamp(340px,58svh,520px)}
}
.rich{max-width:68ch}
.rich p{margin:0 0 1.2em}
.rich h2,.rich h3{margin:2em 0 .6em}
.rich ul{margin:0 0 1.4em;padding-left:1.1em}
.rich li{margin:.35em 0}

/* =========================================================================
   CENTRED SECTIONS + FULL-BLEED IMAGE BANDS
   The reference layout alternates centred type with edge-to-edge photography
   rather than running everything in left-aligned columns.
   ========================================================================= */
/* =========================================================================
   FLOATING-IMAGE SECTION — two photographs flanking centred type
   ========================================================================= */
.sec--float{position:relative;background:var(--char);color:var(--cream);overflow:visible}
/* align-items:start, not center — centring re-levelled the two photographs and
   cancelled out the stagger below. */
.floatrow{
  display:grid;grid-template-columns:minmax(170px,.92fr) minmax(0,1.6fr) minmax(170px,1.05fr);
  gap:clamp(20px,3vw,56px);align-items:start;
}
.floatrow__mid{text-align:center;padding-block:clamp(20px,4vw,60px)}
.floatrow__mid h2{color:var(--cream)}
.floatrow__mid .lead{color:rgba(248,244,244,.72);margin-inline:auto;max-width:46ch}
.floatrow__mid .lead + .lead{margin-top:1.1rem}
.floatrow__mid .ulink{margin-top:2rem;color:var(--cream)}

/* the script line under the heading */
.script{
  font-family:var(--display);font-style:normal;color:var(--brown);
  font-size:clamp(1.6rem,3.6vw,3rem);line-height:1.15;margin:.35rem 0 0;
  /* balance, or the line breaks as "and look superb doing / it" */
  text-wrap:balance;
}
/* thin vertical divider, as in the reference */
.vrule{display:block;width:1px;height:clamp(48px,7vw,104px);background:rgba(248,244,244,.4);margin:clamp(24px,3vw,44px) auto}

/* Photographs float: offset vertically from one another, in FULL COLOUR. */
.floatimg{margin:0}
.floatimg img{
  display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;
  box-shadow:0 26px 60px rgba(4,4,4,.34);
}
/* Hard stagger: the right photograph sits near the top of the section, the
   left one drops well below it. Different aspect ratios too, so they never
   read as a matched pair. */
/* margin, NOT transform: the motion-off block sets transform:none!important on
   every .rv element, and these figures are .rv — a transform offset here gets
   silently wiped. */
.floatimg--l{margin-top:clamp(130px,21vw,360px)}
.floatimg--r{margin-top:0}
.floatimg--l img{aspect-ratio:3/4.3}
.floatimg--r img{aspect-ratio:4/4.6}

/* A label that straddles the boundary between this section and the one above. */
.straddle{
  position:absolute;top:0;left:50%;transform:translate(-50%,-50%);z-index:5;
  background:var(--cream);color:var(--ink);white-space:nowrap;
  font-family:var(--sans);font-weight:500;font-size:.72rem;letter-spacing:.24em;
  text-transform:uppercase;padding:.85em 1.9em;border-radius:var(--pill);
  box-shadow:0 10px 30px rgba(4,4,4,.22);
}

@media(max-width:900px){
  .floatrow{grid-template-columns:1fr 1fr;gap:18px}
  .floatrow__mid{grid-column:1 / -1;order:-1}
  .floatimg--l,.floatimg--r{transform:none}
}

/* =========================================================================
   OVERSIZED SCRIPT WORD behind a section (portfolio)
   ========================================================================= */
.bigword{
  position:relative;z-index:0;text-align:center;pointer-events:none;
  margin-bottom:clamp(-70px,-6vw,-24px);
}
.bigword span{
  font-family:var(--display);font-style:normal;display:inline-block;
  font-size:clamp(3.4rem,13vw,11rem);line-height:.9;letter-spacing:-.01em;
  color:var(--ink);white-space:nowrap;
}
.bg-ink .bigword span,.bg-char .bigword span{color:var(--cream)}
/* the cards ride over the word */
.bigword + .works,.bigword + * .works{position:relative;z-index:1}

.sec--centred{text-align:center}
.sec--centred .eyebrow{margin-inline:auto}
.sec--centred h2{max-width:18ch;margin-inline:auto}
.sec--centred__body{max-width:60ch;margin:2.2rem auto 0}
.sec--centred__body .lead{margin-inline:auto}
.sec--centred__body .lead + .lead{margin-top:1.2rem}
.sec--centred__body .ulink{margin-top:2.2rem}

/* Full-bleed band. Sits outside any container, edge to edge. */
/* Taller than it was: the band is the only place the photography gets to be
   the whole point, and at 58svh most of each frame was cropped away. */
.imgband{
  position:relative;width:100%;height:clamp(420px,84svh,880px);
  overflow:hidden;background:var(--greige);display:grid;place-items:center;
}
/* Weighted low in the frame: centred, the crop sliced the base off every
   laptop and tablet in these photographs. */
.imgband img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 64%;
  filter:contrast(1.03) brightness(.92);
}
/* Weighted to the left, where the line now sits, so the right-hand side of the
   photograph stays open instead of the whole frame being flattened by a wash. */
.imgband--text::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(4,4,4,.66) 0%,rgba(4,4,4,.46) 38%,rgba(4,4,4,.16) 70%,rgba(4,4,4,.06) 100%);
}
/* width:100% is load-bearing. .imgband is a grid with place-items:center, which
   sizes children to min-content — with only a max-width set, the line collapsed
   to the longest word and broke one word per row. */
/* Left-aligned on the site container, so the line starts where every other
   headline on the page starts rather than floating in the middle of a photo. */
.imgband__inner{
  position:relative;z-index:2;width:100%;max-width:var(--wide);
  padding-inline:var(--gutter);text-align:left;margin-inline:auto;
}
.imgband__line{
  margin:0;font-family:var(--serif);color:var(--cream);
  font-size:clamp(1.5rem,3.4vw,2.9rem);line-height:1.2;letter-spacing:-.01em;
  max-width:16ch;text-shadow:0 2px 30px rgba(4,4,4,.45);
}
.imgband__line .it{color:var(--brown);display:inline}

@media(max-width:820px){
  .imgband{height:clamp(240px,42svh,380px)}
  .sec--centred h2{max-width:none}
}

/* ---- Testimonials ---- */
/* One feature quote, then three ruled columns. The boxed 2x2 grid fought with
   the display word behind it and left ragged, half-empty cards. */
.reviewhead{max-width:640px;margin-bottom:clamp(26px,3vw,44px)}
.reviewhead h2{color:var(--cream)}

/* Infinite marquee of quotes. The set is printed twice and the row animates to
   -50%, so the second copy is exactly where the first started when it loops.
   Each set carries its own trailing gap (padding-right, not `gap`) — a flex gap
   between the two sets would put one extra gap in half the distance and the
   loop would jump. */
.revmarquee{
  position:relative;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
}
/* Duration is tuned to the number of cards, not to a "nice" number: fourteen
   quotes at the old 64s flew past too fast to read. ~35px a second. */
.revmarquee__row{display:flex;width:max-content;animation:revscroll 150s linear infinite}
/* Pause on hover only where hover is a real state. On touch screens a tap set
   a sticky :hover and froze the marquee for good — it looked like the reviews
   simply ended. Touch gets an uninterrupted loop instead. */
@media(hover:hover) and (pointer:fine){
  .revmarquee:hover .revmarquee__row{animation-play-state:paused}
}
.revmarquee__set{display:flex;gap:clamp(16px,1.8vw,28px);padding-right:clamp(16px,1.8vw,28px)}
@keyframes revscroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* Phones get more time per card: the same fourteen quotes over a narrower
   screen flew past too fast to actually read. Double the desktop duration —
   about 21 seconds per card. */
@media(max-width:900px){
  .revmarquee__row{animation-duration:300s}
}

.revcard{
  flex:0 0 clamp(270px,25vw,390px);margin:0;
  padding:clamp(22px,2.2vw,34px);
  background:rgba(248,244,244,.055);border:1px solid var(--line-dark);
  display:flex;flex-direction:column;
}
.revcard blockquote{
  margin:0;font-size:clamp(.9rem,1vw,.98rem);line-height:1.75;
  color:rgba(248,244,244,.86);
}
.revcard figcaption{
  margin-top:auto;padding-top:1.3rem;
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap;
}
.revcard__who{font-weight:600;color:var(--cream);font-size:.95rem;letter-spacing:.02em}
.revcard__site{
  font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brown);border-bottom:1px solid transparent;transition:border-color .3s ease;
}
a.revcard__site:hover{border-bottom-color:var(--brown)}
/* The marquee is the section's own full-bleed element, so it sits outside the
   container and the head keeps the container's gutter. */
#reviews .reviewhead{margin-bottom:clamp(28px,3.2vw,48px)}
/* column, not the inherited row: the head and the full-bleed marquee are two
   stacked children, and they still need centring inside the pinned panel. */
#reviews.stack-sec{display:flex;flex-direction:column;justify-content:center;padding-block:clamp(56px,6vw,96px)}
#reviews .container{margin-bottom:clamp(24px,3vw,44px)}

@media(prefers-reduced-motion:reduce){
  /* No animation: let it be swiped instead of standing still half-cropped. */
  .revmarquee{overflow-x:auto;scrollbar-width:thin}
  .revmarquee__set:last-child{display:none}
}

/* ---- Project brief ---- */
.rich .brief{max-width:none;width:min(100%,1180px);display:grid;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:clamp(20px,2.4vw,36px);
  margin:0 0 2.8em;padding:clamp(22px,2.4vw,34px) 0;border-block:1px solid var(--line)}
.brief__row h3{font-family:var(--sans);font-weight:600;font-size:.74rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--mute);margin:0 0 .6rem}
.brief__row p{margin:0;font-size:1rem;line-height:1.6}

/* ---- Project screenshots ---- */
/* Break the shot grid out of the .rich measure — screenshots need width. */
.rich .shots,.rich .shot-scroll{max-width:none;width:min(100%,1180px)}
.shots{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2vw,28px);margin:0 0 2.4em}
.shot{margin:0}
.shot__frame{display:block;overflow:hidden;border:1px solid var(--line);background:var(--greige);
  box-shadow:0 18px 40px rgba(18,17,16,.10)}
.shot__frame img{display:block;width:100%;height:auto}
.shot figcaption{margin-top:.7rem;font-size:.72rem;text-transform:uppercase;letter-spacing:.16em;color:var(--mute)}
/* A tall full-page capture scrolls inside a fixed frame rather than running
   for thousands of pixels down the page. */
.shot-scroll{height:min(74svh,660px);overflow-y:auto;overflow-x:hidden;margin:0 0 2.4em;
  border:1px solid var(--line);background:var(--greige);box-shadow:0 18px 40px rgba(18,17,16,.10);
  scrollbar-width:thin}
.shot-scroll img{display:block;width:100%;height:auto}
@media(max-width:820px){
  .shots{grid-template-columns:1fr}
}
@media(max-width:820px){
  .works--all{grid-template-columns:1fr}
}

/* =========================================================================
   11. STATS
   ========================================================================= */
.stats{display:grid;grid-template-columns:repeat(4,1fr)}
.stat{padding:clamp(24px,2.6vw,40px) clamp(14px,1.6vw,28px);border-left:1px solid var(--line)}
.stat:first-child{border-left:0;padding-left:0}
.bg-ink .stat,.bg-char .stat{border-color:var(--line-dark)}
.stat__n{font-family:var(--serif);font-size:clamp(2.6rem,5.4vw,4.4rem);line-height:.9;display:block}
.stat__l{font-size:.58rem;text-transform:uppercase;letter-spacing:.24em;margin-top:1rem;display:block;color:var(--mute)}
.bg-ink .stat__l,.bg-char .stat__l{color:rgba(248,244,244,.5)}

/* =========================================================================
   12. PROCESS
   ========================================================================= */
.steps{display:grid;grid-template-columns:repeat(4,1fr)}
.step{padding:clamp(26px,2.6vw,40px) clamp(16px,1.8vw,30px);border-left:1px solid var(--line)}
.step:first-child{border-left:0;padding-left:0}
.step__n{font-family:var(--serif);font-style:normal;font-size:1.5rem;display:block;margin-bottom:1.4rem;color:var(--mute)}
.step h3{font-size:1.08rem;margin-bottom:.7rem;text-transform:uppercase;letter-spacing:.04em}
.step p{font-size:.87rem;color:var(--mute);margin:0}

/* =========================================================================
   13. QUOTE
   ========================================================================= */
.quote{max-width:940px;margin-inline:auto;text-align:center}
.quote blockquote{margin:0;font-family:var(--serif);font-size:clamp(1.5rem,3.4vw,2.9rem);line-height:1.18;letter-spacing:-.02em}
.quote__who{margin-top:2.4rem;font-size:.6rem;text-transform:uppercase;letter-spacing:.26em;color:var(--mute)}
.quote__who span{display:block;margin-top:.6rem;opacity:.7}

/* =========================================================================
   14. PRICING
   ========================================================================= */
.plans{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--line)}
.plan{padding:clamp(30px,3vw,48px);border-left:1px solid var(--line);display:flex;flex-direction:column}
.plan:first-child{border-left:0}
.plan--dark{background:var(--ink);color:var(--shell);border-color:var(--ink)}
.plan__flag{font-size:.55rem;text-transform:uppercase;letter-spacing:.24em;color:var(--mute);display:block;margin-bottom:1.4rem;min-height:1em}
.plan--dark .plan__flag{color:rgba(248,244,244,.6)}
.plan h3{font-size:clamp(1.3rem,2vw,1.7rem);text-transform:uppercase;letter-spacing:.02em}
.plan__price{font-family:var(--serif);font-size:clamp(1.8rem,2.6vw,2.4rem);line-height:1;margin:1.4rem 0 .4rem}
.plan__term{font-size:.58rem;text-transform:uppercase;letter-spacing:.22em;color:var(--mute);display:block;margin-bottom:1.8rem}
.plan--dark .plan__term{color:rgba(248,244,244,.5)}
.plan ul{display:grid;gap:.85rem;margin-bottom:2.4rem;padding-top:1.6rem;border-top:1px solid var(--line)}
.plan--dark ul{border-color:var(--line-dark)}
.plan li{font-size:.87rem;color:var(--mute)}
.plan--dark li{color:rgba(248,244,244,.7)}
.plan .btn{margin-top:auto;justify-content:center}

/* =========================================================================
   15. FAQ
   ========================================================================= */
.faq{max-width:900px;margin-inline:auto}
/* Questions on the right; the title, a line of copy and one link hold the left.
   A photograph lived here and never lined up with the accordion rows — it is a
   full-bleed band above this section now instead. */
.faqsplit{
  display:grid;grid-template-columns:minmax(0,.58fr) minmax(0,1fr);
  gap:clamp(28px,5vw,90px);align-items:start;
}
.faqsplit__aside{position:sticky;top:clamp(96px,13vh,150px)}
.faqsplit__aside .lead{max-width:34ch}
.faqsplit .faq{max-width:none;margin:0}
@media(max-width:900px){
  .faqsplit{grid-template-columns:1fr;gap:clamp(22px,4vw,32px)}
  .faqsplit__aside{position:relative;top:auto}
}
.faq details{border-bottom:1px solid var(--line)}
.faq details:first-child{border-top:1px solid var(--line)}
.faq summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;
  gap:24px;padding:1.7em 0;font-family:var(--serif);font-size:clamp(1.05rem,1.7vw,1.35rem)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";width:11px;height:11px;flex:none;
  border-right:1px solid currentColor;border-bottom:1px solid currentColor;
  transform:rotate(45deg) translate(-3px,-3px);transition:transform .45s var(--slow)}
.faq details[open] summary::after{transform:rotate(-135deg) translate(-3px,-3px)}
.faq details p{padding-bottom:1.8em;color:var(--mute);font-size:.93rem;max-width:68ch}

/* =========================================================================
   15b. START A PROJECT PAGE
   ========================================================================= */
/* Light panel: this is a form page, so it reads on cream with ink type rather
   than cream-on-espresso like the closing CTA. Padding clears the fixed header
   and no more — at 210px the headline floated away from the rule above it. */
.startpage{padding-top:clamp(104px,9vw,132px)}
/* A hard rule under the bar, since there is no photograph to separate them. */
body.page-start .site-header{border-bottom:1px solid var(--ink)}
body.page-start .site-header.scrolled{border-bottom-color:var(--ink)}
.startpage h1{color:var(--ink)}
.nextsteps{
  margin:clamp(34px,4vw,56px) 0 0;padding:0;list-style:none;
  display:grid;gap:0;max-width:44ch;
}
.nextsteps li{
  padding:clamp(16px,1.8vw,22px) 0;border-top:1px solid var(--line);
  display:grid;grid-template-columns:3.2rem 1fr;column-gap:clamp(12px,1.4vw,20px);
}
.nextsteps li:last-child{border-bottom:1px solid var(--line)}
.nextsteps__n{
  grid-row:span 2;font-family:var(--serif);font-size:.78rem;letter-spacing:.16em;
  color:var(--mute);padding-top:.35em;
}
.nextsteps h3{font-size:1rem;color:var(--ink);margin:0 0 .3rem;letter-spacing:0}
.nextsteps p{margin:0;font-size:.9rem;color:var(--mute);line-height:1.7}
/* The human check sits between the last field and the button. */
.humancheck{
  display:flex;align-items:center;gap:.8em;margin:0 0 1.8rem;
  font-size:.9rem;color:var(--char);cursor:pointer;
}
.humancheck input{
  appearance:none;-webkit-appearance:none;width:22px;height:22px;flex:none;margin:0;
  border:1px solid var(--ink);border-radius:3px;background:transparent;cursor:pointer;
  display:grid;place-content:center;transition:background .25s ease;
}
.humancheck input::before{
  content:"";width:11px;height:6px;border-left:2px solid var(--shell);
  border-bottom:2px solid var(--shell);transform:rotate(-45deg) scale(0);
  transition:transform .2s ease;margin-top:-3px;
}
.humancheck input:checked{background:var(--ink)}
.humancheck input:checked::before{transform:rotate(-45deg) scale(1)}
.humancheck input:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.bg-ink .humancheck{color:rgba(248,244,244,.75)}
.bg-ink .humancheck input{border-color:var(--line-dark)}
.bg-ink .humancheck input:checked{background:var(--shell)}
.bg-ink .humancheck input::before{border-color:var(--ink)}
@media(max-width:900px){
  .startpage__split{gap:clamp(34px,6vw,56px)}
  .nextsteps{max-width:none}
}

/* =========================================================================
   16. FORM
   ========================================================================= */
.field{margin-bottom:1.6rem}
.field label{display:block;font-size:.56rem;text-transform:uppercase;letter-spacing:.24em;color:var(--mute);margin-bottom:.7rem}
.field input,.field textarea,.field select{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--line);
  padding:.9em 0;font-family:var(--sans);font-weight:300;font-size:1rem;color:inherit;border-radius:0;
}
.bg-ink .field input,.bg-ink .field textarea,.bg-ink .field select{border-color:var(--line-dark);color:var(--shell)}
/* The native dropdown list draws on its own surface: without these the options
   were white text on white. color-scheme covers the platforms that ignore the
   option colours. */
.bg-ink .field select{color-scheme:dark}
.bg-ink .field select option{background-color:var(--cocoa);color:var(--cream)}
.bg-ink .field label{color:rgba(248,244,244,.5)}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:currentColor}
.field textarea{min-height:120px;resize:vertical}
.form-ok{font-size:.75rem;text-transform:uppercase;letter-spacing:.2em}
.hp{position:absolute!important;left:-9999px!important;opacity:0;height:0;width:0}

/* =========================================================================
   17. FOOTER
   ========================================================================= */
.site-footer{background:var(--ink);color:var(--shell);padding-top:clamp(56px,7vw,100px)}
.fgrid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.2fr;gap:clamp(26px,3.4vw,52px);padding-bottom:clamp(38px,5vw,68px)}
/* Four columns squeeze to unreadable well before the single-column breakpoint,
   so the footer goes two-up in between. */
@media(max-width:1100px){
  .fgrid{grid-template-columns:1fr 1fr;gap:clamp(26px,4vw,40px)}
  .fgrid > :first-child{grid-column:1 / -1}
}
.site-footer h4{font-family:var(--sans);font-weight:400;text-transform:uppercase;letter-spacing:.26em;
  font-size:.56rem;color:rgba(248,244,244,.45);margin-bottom:1.5rem}
.flinks a{display:block;padding:.42rem 0;font-size:.92rem;color:rgba(248,244,244,.75);
  transition:color .35s var(--ease),padding-left .35s var(--ease)}
.flinks a:hover{color:var(--shell);padding-left:6px}
.foot-logo{width:min(280px,64vw);height:auto;display:block;margin-bottom:.4rem}
.fnote{font-size:.9rem;color:rgba(248,244,244,.55);max-width:32ch;margin-top:1.2rem}
.fmail{font-family:var(--serif);font-size:clamp(1.1rem,2vw,1.6rem);display:inline-block;
  border-bottom:1px solid rgba(248,244,244,.28);padding-bottom:.12em}
.fmail:hover{border-color:var(--shell)}
.socials{display:flex;gap:9px;margin-top:1.6rem}
.socials a{width:38px;height:38px;border-radius:50%;border:1px solid rgba(248,244,244,.22);
  display:grid;place-items:center;transition:.35s var(--ease)}
.socials a:hover{background:var(--shell);color:var(--ink);border-color:var(--shell)}
.socials svg{width:15px;height:15px}
.fbottom{border-top:1px solid var(--line-dark);padding-block:22px;display:flex;
  justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:.62rem;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(248,244,244,.42)}

/* =========================================================================
   18. PLACEHOLDERS
   ========================================================================= */
.sqp-ph{width:100%;height:100%;display:grid;place-items:center;position:relative;
  background:linear-gradient(150deg,#B9B2A6 0%,#8C857A 45%,#4A453E 100%)}
.sqp-ph::after{content:"";position:absolute;inset:0;opacity:.5;
  background:radial-gradient(120% 90% at 30% 15%,rgba(255,255,255,.28),transparent 55%)}
.sqp-ph span{position:relative;z-index:2;font-family:var(--sans);font-size:.55rem;
  text-transform:uppercase;letter-spacing:.28em;color:rgba(255,255,255,.82);padding:0 1.6em;text-align:center}

/* =========================================================================
   19. REVEAL
   ========================================================================= */
/* Scoped to .js: without it a blocked or slow script leaves the hero headline
   at opacity 0 forever, so the page renders empty. No JS, no hiding. */
/* =========================================================================
   MOTION OFF
   Everything is static except the rotating seal. Reveals, wipes, marquee and
   parallax are all disabled — content renders in its final state immediately.
   To bring the reveals back, delete this block.
   ========================================================================= */
.rv,.js .rv{opacity:1!important;transform:none!important;transition:none!important}
.ln > span,.rv.in .ln > span{transform:none!important;transition:none!important}
.wipe::after{display:none!important}
.wipe img,.wipe .sqp-ph,.wipe.in img{transform:none!important;transition:none!important}
.band__row{animation:none!important;width:auto!important}
[data-par]{transform:none!important}
.work__media img,.work:hover .work__media img{transform:none!important;transition:none!important}
.btn::before{display:none}
.btn{transition:color .25s ease,background-color .25s ease,border-color .25s ease}
/* The wipe pseudo-element is what used to paint the hover state. With it off,
   `color` flipped but nothing filled behind it — white text on a white plan,
   ink text on an ink one. Hover has to change the background itself. */
.btn:hover{background:var(--ink);color:var(--shell);border-color:var(--ink)}
.btn--solid:hover{background:transparent;color:var(--ink);border-color:var(--ink)}
.btn--light:hover{background:var(--shell);color:var(--ink);border-color:var(--shell)}
.btn--cream:hover{background:transparent;color:var(--shell);border-color:var(--shell)}
.plan--dark .btn:hover{background:var(--shell);color:var(--ink);border-color:var(--shell)}

/* No underline on the nav: hover and the current section just soften instead. */
.nav a::before{display:none}
.nav a{transition:opacity .3s var(--ease)}
.nav a:hover{opacity:.58}

/* The one exception: the seal keeps turning. */
.seal svg.seal__ring{animation:spin 26s linear infinite!important}

.js .rv--legacy{opacity:0;transform:translateY(22px);transition:opacity 1.1s var(--slow),transform 1.1s var(--slow)}
.rv.in{opacity:1;transform:none}
.rv.d1{transition-delay:.1s}.rv.d2{transition-delay:.2s}.rv.d3{transition-delay:.3s}.rv.d4{transition-delay:.4s}
@media(prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none;transition:none}
  *{animation:none!important;scroll-behavior:auto!important}
}

/* =========================================================================
   20. ARTICLE
   ========================================================================= */
.entry{font-size:1.02rem;line-height:1.85;color:var(--char)}
.entry h2{font-size:clamp(1.5rem,2.6vw,2.1rem);margin:2.4rem 0 .9rem}
.entry h3{font-size:clamp(1.2rem,2vw,1.5rem);margin:2rem 0 .7rem}
.entry a{border-bottom:1px solid var(--line)}
.entry blockquote{margin:2.2rem 0;padding-left:1.6rem;border-left:1px solid var(--ink);
  font-family:var(--serif);font-size:1.35rem;font-style:normal}
.entry ul,.entry ol{margin:1.2rem 0;padding-left:1.3rem}
.entry ul li{list-style:disc;margin-bottom:.5rem}
.entry ol li{list-style:decimal;margin-bottom:.5rem}
.navigation.pagination{display:flex;gap:8px;font-size:.6rem;letter-spacing:.2em;text-transform:uppercase}
.navigation.pagination .page-numbers{padding:.85em 1.2em;border:1px solid var(--line);border-radius:var(--pill)}
.navigation.pagination .current{background:var(--ink);color:var(--shell);border-color:var(--ink)}

/* =========================================================================
   21. RESPONSIVE
   ========================================================================= */
@media(max-width:1100px){
  .works{grid-template-columns:repeat(2,1fr)}
  .stats,.steps{grid-template-columns:repeat(2,1fr)}
  .stat:nth-child(3),.step:nth-child(3){border-left:0;padding-left:0}
  .cols3{grid-template-columns:1fr}
  .col3{border-left:0;border-top:1px solid var(--line-dark);padding-left:0;padding-right:0}
  .col3:first-child{border-top:0;padding-top:0}
  .plans{grid-template-columns:1fr}
  .plan{border-left:0;border-top:1px solid var(--line)}
  .plan:first-child{border-top:0}
  .logobar{grid-template-columns:repeat(3,1fr)}
  .logobar span:nth-child(4){border-left:0}
}
@media(max-width:900px){
  .burger{display:block}
  .nav{position:fixed;inset:0;background:var(--ink);color:var(--shell);
    flex-direction:column;align-items:stretch;justify-content:center;
    transform:translateX(100%);transition:transform .55s var(--slow);z-index:125}
  .nav.open{transform:none}
  .nav a{border-left:0;border-bottom:1px solid var(--line-dark);padding:1.2em var(--gutter);
    font-family:var(--serif);font-size:1.6rem;letter-spacing:.02em;text-transform:uppercase}
  .nav a:last-child{border-right:0}
  .hcta .btn{display:none}
  .split,.split--text{grid-template-columns:1fr}
  .split .frame{order:-1}
  .seal{width:76px;top:auto;bottom:14px;right:14px}
}
@media(max-width:640px){
  .works,.stats,.steps{grid-template-columns:1fr}
  .stat,.step{border-left:0;padding-left:0;border-top:1px solid var(--line)}
  .stat:first-child,.step:first-child{border-top:0}
  .logobar{grid-template-columns:repeat(2,1fr)}
  .logobar span:nth-child(odd){border-left:0}
  .fgrid{grid-template-columns:1fr}
  .hero__cta .btn{width:100%;justify-content:center}
  .hero__meta{flex-direction:column;gap:8px}
}

/* =========================================================================
   22. ONE-PAGE NAV — no dividing lines
   ========================================================================= */
.nav a{border-left:0!important;border-right:0!important;padding:0 clamp(12px,1.5vw,22px)}
.nav a::before{bottom:-2px}


/* thin scroll progress under the header */
.scrollbar{position:absolute;left:0;bottom:0;height:1px;width:0;background:var(--ink);
  transform-origin:left;transition:width .1s linear;opacity:0}
.site-header.scrolled .scrollbar{opacity:.5}

/* =========================================================================
   23. FOOTER REVEAL — page scrolls away, footer sits beneath
   ========================================================================= */
.page-wrap{position:relative;z-index:2;background:var(--bone)}
.site-footer{position:fixed;left:0;right:0;bottom:0;z-index:1;
  display:flex;flex-direction:column;justify-content:flex-end}
body.no-reveal .site-footer{position:relative}
body.no-reveal .page-wrap{padding-bottom:0!important;margin-bottom:0!important}

/* =========================================================================
   24. STICKY STACK — panels pin, the next one scrolls up over them

   The wrapper is what bounds the pinning. Without it a sticky section stays
   pinned to the bottom of .page-wrap, i.e. the entire rest of the page,
   including the footer-reveal gap. Every panel must carry an opaque
   background or the one beneath shows through as it slides up.
   ========================================================================= */
.stack{position:relative;z-index:1}
/* A pinned panel taller than the viewport gets its bottom clipped, so stack
   panels run tighter padding than a normal .section. */
.stack-sec{position:sticky;top:0;min-height:100svh;display:flex;align-items:center;
  padding-block:clamp(48px,5vw,88px)}
.stack-sec .container{width:100%}
/* trailing room so the final panel gets a real pinned beat of its own
   before the stack releases it */
.stack::after{content:"";display:block;height:55svh}

/* anything after the stack rides above it and must be opaque */
.stack-lift{position:relative;z-index:2}

/* pinned media beside scrolling copy */
.split--pin{align-items:start}
/* About: Meg's own portrait (the attachment is named border.webp — it is not a
   border). It is 500x844 and already black and white, so the frame matches its
   ratio and the grayscale filter is left off rather than applied twice. */
#about .split--pin{grid-template-columns:minmax(0,.62fr) minmax(0,1fr)}
#about .frame{max-width:340px;aspect-ratio:500/844}
#about .frame img{filter:none}
/* Collage: a second photograph hangs off the lower right of the portrait. The
   wrapper carries the sticky and the width, because .frame clips its overflow. */
.aboutstack{position:relative;max-width:340px}
.aboutstack__inset{
  position:absolute;right:-26%;bottom:-11%;width:84%;margin:0;
  aspect-ratio:4/3;overflow:hidden;background:var(--greige);
  /* No frame — the shadow alone lifts it off the portrait. */
  box-shadow:0 26px 52px rgba(4,4,4,.26);
}
.aboutstack__inset img{width:100%;height:100%;object-fit:cover;display:block}
@media(max-width:900px){
  #about .split--pin{grid-template-columns:1fr}
  /* The inset hangs ~11% below the stack box. Without this margin the
     "Meet the founder" copy that stacks beneath slides straight under the
     photograph — clearance has to cover the overhang plus a real breath. */
  .aboutstack{max-width:270px;margin-bottom:clamp(64px,16vw,96px)}
  .aboutstack__inset{right:-32%;width:88%}
}
.split--pin .pin{position:sticky;top:clamp(90px,12vh,140px)}

/* =========================================================================
   25. MOTION
   ========================================================================= */
/* line-by-line heading reveal */
.ln{display:block;overflow:hidden}
.ln > span{display:block;transform:translateY(105%);
  transition:transform 1.05s var(--slow)}
.rv.in .ln > span,.ln.in > span{transform:none}
.ln:nth-child(1) > span{transition-delay:.02s}
.ln:nth-child(2) > span{transition-delay:.1s}
.ln:nth-child(3) > span{transition-delay:.18s}
.ln:nth-child(4) > span{transition-delay:.26s}

/* image curtain wipe */
.wipe{position:relative;overflow:hidden}
.wipe::after{content:"";position:absolute;inset:0;background:var(--bone);z-index:4;
  transform-origin:top;transition:transform 1.2s var(--slow)}
.bg-ink .wipe::after,.bg-char .wipe::after{background:var(--ink)}
.wipe.in::after{transform:scaleY(0)}
.wipe img,.wipe .sqp-ph{transform:scale(1.12);transition:transform 1.6s var(--slow)}
.wipe.in img,.wipe.in .sqp-ph{transform:scale(1)}

/* parallax drift */
[data-par]{will-change:transform}

/* hover cursor cue on work */
.work__media::after{content:"";position:absolute;inset:0;background:rgba(18,17,16,.18);
  opacity:0;transition:opacity .5s var(--ease);z-index:2}
.work:hover .work__media::after{opacity:1}
.work__view{position:absolute;left:50%;top:50%;z-index:3;transform:translate(-50%,-50%) scale(.86);
  width:92px;height:92px;border-radius:50%;border:1px solid rgba(248,244,244,.7);color:var(--shell);
  display:grid;place-items:center;font-size:.54rem;letter-spacing:.2em;text-transform:uppercase;
  opacity:0;transition:opacity .5s var(--ease),transform .6s var(--slow);pointer-events:none}
.work:hover .work__view{opacity:1;transform:translate(-50%,-50%) scale(1)}

/* marquee band */
.band{overflow:hidden;padding-block:clamp(16px,2vw,26px);border-block:1px solid var(--line)}
.bg-ink .band,.bg-char .band{border-color:var(--line-dark)}
.band__row{display:flex;width:max-content;animation:band 42s linear infinite}
.band:hover .band__row{animation-play-state:paused}
@keyframes band{to{transform:translateX(-50%)}}
.band__i{font-family:var(--serif);font-size:clamp(1.4rem,3.4vw,3rem);line-height:1.1;
  padding-inline:clamp(18px,2.4vw,40px);white-space:nowrap;display:inline-flex;align-items:center;gap:clamp(18px,2.4vw,40px)}
.band__i::after{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.45}

/* Unpinning uses position:relative, NEVER static. `.pin` is the same element as
   `.frame`, whose image is position:absolute;inset:0 — drop the containing block
   and that image escapes to .page-wrap and covers the entire page. `top` has to
   be reset too, or the sticky offset becomes a relative nudge. */
@media(max-width:900px){
  .stack-sec{position:static;min-height:0}
  .stack::after{display:none}
  .split--pin .pin{position:relative;top:auto}
  .site-footer{position:relative}
  .page-wrap{padding-bottom:0!important;margin-bottom:0!important}
}
@media(prefers-reduced-motion:reduce){
  .ln > span{transform:none}
  .wipe::after{display:none}
  .wipe img,.wipe .sqp-ph{transform:none}
  .stack-sec{position:static;min-height:0}
  .stack::after{display:none}
  .split--pin .pin{position:relative;top:auto}
  .site-footer{position:relative}
}
