/* ============================================================================
   JWS Start — curated block library
   Scope: everything here lives under .jws-preview. Nothing leaks to the chrome.
   Colour + type come ONLY from custom properties set on .jws-preview:
     --bg --surface --ink --accent --accent-ink --font-display --font-body
   Layout DNA comes from ONE vibe class on the same element:
     .v-quarry | .v-atrium | .v-signal | .v-workshop
   ========================================================================= */

/* ---- self-hosted faces (latin) ------------------------------------------ */
/* Funnel chrome faces — the builder uses these outside .jws-preview. */
@font-face{font-family:'Bricolage Grotesque';src:url(../fonts/bricolage-grotesque-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Bricolage Grotesque';src:url(../fonts/bricolage-grotesque-800.woff2) format('woff2');font-weight:800;font-display:swap}
@font-face{font-family:'Space Mono';src:url(../fonts/space-mono-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Space Mono';src:url(../fonts/space-mono-700.woff2) format('woff2');font-weight:700;font-display:swap}
/* Pairing faces. */
@font-face{font-family:'Syne';src:url(../fonts/syne-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Syne';src:url(../fonts/syne-800.woff2) format('woff2');font-weight:800;font-display:swap}
@font-face{font-family:'Public Sans';src:url(../fonts/public-sans-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Public Sans';src:url(../fonts/public-sans-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Fraunces';src:url(../fonts/fraunces-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Work Sans';src:url(../fonts/work-sans-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Work Sans';src:url(../fonts/work-sans-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Big Shoulders Display';src:url(../fonts/big-shoulders-display-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Source Sans 3';src:url(../fonts/source-sans-3-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Source Sans 3';src:url(../fonts/source-sans-3-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Instrument Serif';src:url(../fonts/instrument-serif-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Karla';src:url(../fonts/karla-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Karla';src:url(../fonts/karla-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Space Grotesk';src:url(../fonts/space-grotesk-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'IBM Plex Sans';src:url(../fonts/ibm-plex-sans-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'IBM Plex Sans';src:url(../fonts/ibm-plex-sans-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Zilla Slab';src:url(../fonts/zilla-slab-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Nunito Sans';src:url(../fonts/nunito-sans-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Nunito Sans';src:url(../fonts/nunito-sans-700.woff2) format('woff2');font-weight:700;font-display:swap}

/* ---- root --------------------------------------------------------------- */
.jws-preview{
  /* fallbacks only — the builder overwrites these five from library.json */
  --bg:#F4F5F7; --surface:#fff; --ink:#15181D; --accent:#1B3FBF; --accent-ink:#193AAC;
  --font-display:'Syne','Arial Black',sans-serif;
  --font-body:'Public Sans',system-ui,sans-serif;

  /* structural scale — vibes retune these, blocks never hardcode them */
  --pad:clamp(18px,5vw,64px);
  --maxw:1180px;
  --gap:clamp(16px,3vw,32px);
  --blk-y:clamp(48px,9vw,104px);
  --display:clamp(2.05rem,7.4vw,4.6rem);
  --display-sm:clamp(1.5rem,4.2vw,2.5rem);
  --body:clamp(1rem,1.05vw,1.0625rem);
  --lead:clamp(1.05rem,1.5vw,1.25rem);
  --hair:1px;
  --radius:0px;
  --tight:-0.02em;
  --muted:color-mix(in srgb,var(--ink) 70%,transparent);
  --faint:color-mix(in srgb,var(--ink) 14%,transparent);

  background:var(--bg); color:var(--ink);
  font-family:var(--font-body); font-size:var(--body); line-height:1.55;
  overflow-x:clip;          /* clip, not hidden — keeps position:sticky alive */
  -webkit-text-size-adjust:100%;
}
.jws-preview *,.jws-preview *::before,.jws-preview *::after{box-sizing:border-box}
.jws-preview img{display:block;max-width:100%;height:auto}
.jws-preview p{margin:0}
.jws-preview figure{margin:0}
.jws-preview dl,.jws-preview dd{margin:0}
/* Unclassed links inherit; classed links (.btn, .cta-slab__tel, …) must be able to
   set their own colour, so this reset must not out-specify them. */
.jws-preview a:not([class]){color:inherit}

/* ---- shared block furniture --------------------------------------------- */
.blk{position:relative;padding:var(--blk-y) var(--pad);background:var(--bg)}
.blk--flush{padding-inline:0}
.blk__inner{max-width:var(--maxw);margin-inline:auto;position:relative}
.blk--flush .blk__inner{max-width:none}

.blk__h{
  font-family:var(--font-display);font-weight:700;font-size:var(--display);
  line-height:1.02;letter-spacing:var(--tight);margin:0;
  overflow-wrap:break-word;text-wrap:balance;
}
.blk__h--sm{font-size:var(--display-sm);line-height:1.1}
.blk__lead{font-size:var(--lead);line-height:1.5;max-width:46ch;color:var(--muted)}

.blk__eyebrow{
  font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;
  color:var(--accent-ink);margin:0 0 .9em;display:block;
}
.blk__code{
  font-family:'Space Mono',ui-monospace,monospace;font-size:.6875rem;letter-spacing:.1em;
  color:var(--muted);display:none;                 /* Quarry turns these on */
}
.blk__label{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}

.btn{
  display:inline-block;font-family:var(--font-body);font-weight:700;font-size:1rem;
  padding:.9em 1.5em;background:var(--accent);color:var(--bg);text-decoration:none;
  border:var(--hair) solid var(--accent);border-radius:var(--radius);
  transition:transform .16s ease-out,box-shadow .16s ease-out;
}
.btn--ghost{background:transparent;color:var(--accent-ink);border-color:var(--accent)}
.btn:focus-visible,.jws-preview a:focus-visible{outline:2px solid var(--accent-ink);outline-offset:3px}

.rule{height:var(--hair);background:var(--faint);border:0;margin:0;transform-origin:left center}
.blk__stats{display:flex;flex-wrap:wrap;gap:var(--gap) clamp(24px,5vw,56px);margin-top:2rem}
.stat__v{font-family:var(--font-display);font-weight:700;font-size:clamp(1.6rem,3.6vw,2.4rem);line-height:1;display:block}
.stat__l{font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-top:.5em;display:block}

.frame{position:relative;background:var(--surface);border-radius:var(--radius);overflow:hidden}
.frame img{width:100%;height:100%;object-fit:cover}
.ratio-wide{aspect-ratio:16/9}
.ratio-tall{aspect-ratio:3/4}
.ratio-box{aspect-ratio:4/3}
.ratio-strip{aspect-ratio:21/9}

.marquee{display:none}                              /* Signal turns this on */
.leader{display:none}                               /* Workshop turns this on */

/* ============================================================================
   MOTION — entrances key off DOM insertion, so a block animates the moment the
   builder appends it. No JS, no observers. Builder note: swapping palette or
   type must NOT re-insert nodes (they are pure var swaps), or entrances replay.
   ========================================================================= */
@keyframes blk-rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes blk-drift{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes blk-settle{from{opacity:0;transform:translateY(10px) rotate(.4deg)}to{opacity:1;transform:none}}
@keyframes blk-wipe{from{opacity:0;clip-path:inset(100% 0 0 0)}to{opacity:1;clip-path:inset(0 0 0 0)}}
@keyframes rule-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes img-settle{from{transform:scale(1.04)}to{transform:none}}
@keyframes marquee-run{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* One entrance group. Vibes only swap --enter / --enter-dur / --enter-ease.
   Wrappers that exist purely to position a column are skipped so their
   children animate individually instead of the whole slab moving as one. */
.blk > *:not(.blk__inner):not(.marquee):not(.hero-band__slab),
.blk__inner > *:not(.hero-split__type),
.hero-split__type > *,
.hero-band__slab > *{
  animation-name:var(--enter,blk-rise);
  animation-duration:var(--enter-dur,240ms);
  animation-timing-function:var(--enter-ease,cubic-bezier(.2,0,0,1));
  animation-fill-mode:both;
}
:is(.blk > *,.blk__inner > *,.hero-split__type > *,.hero-band__slab > *):nth-child(2){animation-delay:var(--stag,60ms)}
:is(.blk > *,.blk__inner > *,.hero-split__type > *,.hero-band__slab > *):nth-child(3){animation-delay:calc(var(--stag,60ms) * 2)}
:is(.blk > *,.blk__inner > *,.hero-split__type > *,.hero-band__slab > *):nth-child(4){animation-delay:calc(var(--stag,60ms) * 3)}
:is(.blk > *,.blk__inner > *,.hero-split__type > *,.hero-band__slab > *):nth-child(5){animation-delay:calc(var(--stag,60ms) * 4)}
:is(.blk > *,.blk__inner > *,.hero-split__type > *,.hero-band__slab > *):nth-child(6){animation-delay:calc(var(--stag,60ms) * 5)}

@media (prefers-reduced-motion:reduce){
  .jws-preview *,.jws-preview *::before,.jws-preview *::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;
  }
}

/* ============================================================================
   BLOCK 1 — HERO / Split Plate
   Type column and a full-height image plate that runs off the right edge.
   ========================================================================= */
.hero-split{padding-block:0}
.hero-split .blk__inner{display:grid;gap:0}
.hero-split__type{padding:var(--blk-y) var(--pad) clamp(32px,6vw,56px)}
.hero-split__plate{position:relative;min-height:56vw}
.hero-split__plate img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.hero-split .blk__h{margin-bottom:.6em}
.hero-split .blk__lead{margin-bottom:2rem}
@media (min-width:860px){
  .hero-split .blk__inner{grid-template-columns:minmax(0,1fr) minmax(0,.92fr);align-items:stretch;max-width:none}
  .hero-split__type{padding:clamp(72px,9vw,128px) clamp(40px,5vw,80px);
    max-width:calc(var(--maxw) * .58);margin-left:auto;display:flex;flex-direction:column;justify-content:center}
  .hero-split__plate{min-height:min(88vh,760px)}
}

/* ============================================================================
   BLOCK 2 — HERO / Overlap Band
   Full-bleed image; a solid slab breaks the bottom-left corner and carries the ask.
   ========================================================================= */
.hero-band{padding-inline:0;padding-top:0}
.hero-band__img{position:relative;aspect-ratio:4/3;background:var(--surface)}
.hero-band__img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.hero-band__slab{
  background:var(--surface);position:relative;margin:-14% var(--pad) 0;
  padding:clamp(24px,5vw,44px);max-width:min(640px,100%);
  border:var(--hair) solid var(--faint);border-radius:var(--radius);
}
.hero-band__slab .blk__h{margin-bottom:.5em}
.hero-band__slab .btn{margin-top:1.6rem}
.hero-band .blk__stats{padding-inline:var(--pad);max-width:var(--maxw);margin-inline:auto}
@media (min-width:860px){
  .hero-band__img{aspect-ratio:21/9}
  .hero-band__slab{margin:-9% auto 0;margin-left:max(var(--pad),calc((100% - var(--maxw))/2))}
}

/* ============================================================================
   BLOCK 3 — HERO / Type Index
   No photo above the fold. Giant type, then a ruled index table, then a strip.
   ========================================================================= */
.hero-index__h{font-size:clamp(2.4rem,10.5vw,7rem);line-height:.94;margin-bottom:clamp(28px,5vw,48px)}
.hero-index__table{border-top:var(--hair) solid var(--ink);margin-bottom:clamp(28px,5vw,48px)}
.hero-index__row{
  display:grid;grid-template-columns:minmax(0,1fr);gap:.25rem;
  padding:1.1rem 0;border-bottom:var(--hair) solid var(--faint);
}
.hero-index__row dt{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.hero-index__row dd{margin:0;font-family:var(--font-display);font-size:1.25rem;font-weight:700;overflow-wrap:break-word}
.hero-index__strip{margin-top:clamp(28px,5vw,48px)}
.hero-index__strip.ratio-strip{aspect-ratio:16/9}
@media (min-width:720px){.hero-index__strip.ratio-strip{aspect-ratio:21/9}}
@media (min-width:720px){
  .hero-index__row{grid-template-columns:14rem minmax(0,1fr);gap:var(--gap);align-items:baseline}
  .hero-index__row dd{font-size:1.6rem}
}

/* ============================================================================
   BLOCK 4 — SERVICES / Numbered Ledger
   Full-width ruled rows. Deliberately NOT cards.
   ========================================================================= */
.svc-ledger__head{margin-bottom:clamp(32px,5vw,56px)}
.svc-ledger__list{border-top:var(--hair) solid var(--ink)}
.svc-ledger__row{
  display:grid;grid-template-columns:2.75rem minmax(0,1fr);gap:.35rem var(--gap);
  padding:clamp(20px,3vw,30px) 0;border-bottom:var(--hair) solid var(--faint);
  transition:background .18s ease-out;
}
.svc-ledger__n{font-family:'Space Mono',ui-monospace,monospace;font-size:.8125rem;color:var(--accent-ink);padding-top:.35em;grid-row:span 2}
.svc-ledger__name{font-family:var(--font-display);font-weight:700;font-size:clamp(1.25rem,2.6vw,1.75rem);line-height:1.15;margin:0}
.svc-ledger__desc{color:var(--muted);max-width:60ch;margin:0}
@media (min-width:840px){
  .svc-ledger__row{grid-template-columns:3.5rem minmax(0,15rem) minmax(0,1fr);align-items:baseline}
  .svc-ledger__n{grid-row:auto}
}

/* ============================================================================
   BLOCK 5 — SERVICES / Asymmetric Mosaic
   Bento with unequal spans. No row of identical cards anywhere.
   ========================================================================= */
.svc-mosaic__head{margin-bottom:clamp(32px,5vw,56px);max-width:34ch}
.svc-mosaic__grid{display:grid;gap:var(--hair);background:var(--faint);border:var(--hair) solid var(--faint)}
.svc-mosaic__cell{background:var(--surface);padding:clamp(22px,3.2vw,34px);min-height:0}
.svc-mosaic__cell h3{font-family:var(--font-display);font-weight:700;font-size:1.25rem;line-height:1.15;margin:0 0 .55em}
.svc-mosaic__cell p{color:var(--muted);margin:0}
.svc-mosaic__cell--lead h3{font-size:clamp(1.6rem,4vw,2.4rem)}
.svc-mosaic__cell--lead p{font-size:var(--lead)}
@media (min-width:820px){
  .svc-mosaic__grid{grid-template-columns:repeat(6,minmax(0,1fr))}
  .svc-mosaic__cell:nth-child(1){grid-column:span 3;grid-row:span 2;display:flex;flex-direction:column;justify-content:flex-end}
  .svc-mosaic__cell:nth-child(2){grid-column:span 3}
  .svc-mosaic__cell:nth-child(3){grid-column:span 3}
  .svc-mosaic__cell:nth-child(4){grid-column:span 2}
  .svc-mosaic__cell:nth-child(5){grid-column:span 4}
}

/* ============================================================================
   BLOCK 6 — SERVICES / Sticky Rail
   Heading pins while a horizontal rail of panels scrolls past it.
   ========================================================================= */
.svc-rail .blk__inner{display:grid;gap:clamp(28px,4vw,48px)}
.svc-rail__head{max-width:32ch}
.svc-rail__track{
  display:flex;gap:var(--gap);overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;padding-bottom:1rem;
  scrollbar-width:thin;min-width:0;
}
.svc-rail__panel{
  flex:0 0 min(78%,320px);scroll-snap-align:start;background:var(--surface);
  border:var(--hair) solid var(--faint);border-radius:var(--radius);
  padding:clamp(22px,3vw,30px);display:flex;flex-direction:column;gap:.6rem;
}
.svc-rail__panel h3{font-family:var(--font-display);font-weight:700;font-size:1.3rem;line-height:1.15;margin:0}
.svc-rail__panel p{color:var(--muted);margin:0}
.svc-rail__panel .blk__code{margin-top:auto;padding-top:1.2rem}
@media (min-width:900px){
  .svc-rail .blk__inner{grid-template-columns:minmax(0,20rem) minmax(0,1fr);align-items:start}
  .svc-rail__head{position:sticky;top:clamp(24px,6vh,72px)}
  .svc-rail__panel{flex-basis:340px}
}

/* ============================================================================
   BLOCK 7 — ABOUT / Diptych
   Portrait plate against a text column with a vertical rail label.
   ========================================================================= */
.about-diptych .blk__inner{display:grid;gap:clamp(28px,4vw,56px)}
.about-diptych__body p{color:var(--muted);font-size:var(--lead);max-width:52ch}
.about-diptych .blk__h{margin-bottom:.6em}
.about-diptych__rail{display:block;margin-bottom:1.2rem}
@media (min-width:860px){
  .about-diptych .blk__inner{grid-template-columns:minmax(0,.85fr) minmax(0,1fr);align-items:center}
  .about-diptych__body{display:grid;grid-template-columns:2.5rem minmax(0,1fr);gap:var(--gap)}
  .about-diptych__rail{
    writing-mode:vertical-rl;transform:rotate(180deg);margin:0;
    justify-self:start;align-self:start;white-space:nowrap;
  }
}

/* ============================================================================
   BLOCK 8 — ABOUT / Giant Numeral
   The number is the picture. No photo in this variant at all.
   ========================================================================= */
.about-numeral .blk__inner{display:grid;gap:clamp(24px,4vw,48px)}
.about-numeral__figwrap{margin:0}
.about-numeral__fig{
  font-family:var(--font-display);font-weight:700;line-height:.78;
  font-size:clamp(7rem,26vw,17rem);letter-spacing:-.05em;color:transparent;
  -webkit-text-stroke:2px var(--accent);margin:0;
}
.about-numeral__figlabel{font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-ink);margin-top:.4rem;display:block}
.about-numeral__body p{color:var(--muted);font-size:var(--lead);max-width:54ch;margin-top:1rem}
@media (min-width:820px){
  .about-numeral .blk__inner{grid-template-columns:minmax(0,.7fr) minmax(0,1fr);align-items:end}
  .about-numeral__figwrap{margin:0}
.about-numeral__fig{-webkit-text-stroke-width:3px}
}

/* ============================================================================
   BLOCK 9 — TESTIMONIALS / Oversized Pull-Quote
   One quote at headline scale; the other voices reduce to a credit row.
   ========================================================================= */
.tst-pull__q{margin:0}
.tst-pull__q blockquote{
  font-family:var(--font-display);font-weight:700;letter-spacing:var(--tight);
  font-size:clamp(1.65rem,5.4vw,3.4rem);line-height:1.08;margin:0;text-wrap:balance;
}
.tst-pull__q blockquote::before{content:'\201C';color:var(--accent);margin-right:.06em}
.tst-pull__by{margin-top:1.4rem;font-size:.8125rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.tst-pull__row{
  display:grid;gap:var(--gap);margin-top:clamp(40px,6vw,72px);
  border-top:var(--hair) solid var(--faint);padding-top:clamp(24px,3vw,32px);
}
.tst-pull__row p{color:var(--muted)}
.tst-pull__row cite{display:block;font-style:normal;margin-top:.6rem;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-ink)}
@media (min-width:760px){.tst-pull__row{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(32px,5vw,72px)}}

/* ============================================================================
   BLOCK 10 — TESTIMONIALS / Staggered Offset
   Three quotes at three different widths and indents. Never a tidy 3-up.
   ========================================================================= */
.tst-stagger__head{margin-bottom:clamp(24px,4vw,40px)}
.tst-stagger__list{display:grid;gap:clamp(24px,4vw,40px)}
.tst-stagger__item{
  background:var(--surface);border-left:3px solid var(--accent);
  padding:clamp(20px,3vw,30px);border-radius:var(--radius);
}
.tst-stagger__item p{font-size:var(--lead);line-height:1.45;margin:0}
.tst-stagger__item cite{display:block;font-style:normal;margin-top:1rem;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
@media (min-width:800px){
  .tst-stagger__item:nth-child(1){width:64%;margin-right:auto}
  .tst-stagger__item:nth-child(2){width:52%;margin-left:auto;margin-top:-2.5rem}
  .tst-stagger__item:nth-child(3){width:46%;margin-left:12%}
  .tst-stagger__item:nth-child(1) p{font-size:clamp(1.25rem,2.4vw,1.6rem)}
}

/* ============================================================================
   BLOCK 11 — GALLERY / Bleed Strip
   Two plates of different widths running the full page width, captions ruled.
   ========================================================================= */
.gal-strip__head{padding-inline:var(--pad);max-width:var(--maxw);margin:0 auto clamp(28px,4vw,44px)}
.gal-strip__pair{display:grid;gap:var(--hair);background:var(--faint)}
.gal-strip__cell{background:var(--bg)}
.gal-strip__cell figcaption{
  padding:.9rem var(--pad);font-size:.75rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);
}
@media (min-width:760px){
  .gal-strip__pair{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)}
  .gal-strip__cell figcaption{padding-inline:clamp(16px,2vw,24px)}
  .gal-strip__cell:first-child .ratio-box{aspect-ratio:16/10}
  .gal-strip__cell:last-child .ratio-box{aspect-ratio:4/5}
}

/* ============================================================================
   BLOCK 12 — GALLERY / Irregular Grid
   One tall plate, one wide plate, and a text cell holding the third position.
   ========================================================================= */
.gal-irregular__head{margin-bottom:clamp(28px,4vw,44px);max-width:36ch}
.gal-irregular__grid{display:grid;gap:var(--gap)}
.gal-irregular__note{
  background:var(--surface);padding:clamp(22px,3vw,32px);border-radius:var(--radius);
  display:flex;flex-direction:column;justify-content:space-between;gap:1.4rem;
}
.gal-irregular__note p{color:var(--muted)}
@media (min-width:800px){
  .gal-irregular__grid{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);grid-template-rows:auto auto}
  .gal-irregular__tall{grid-row:span 2}
  .gal-irregular__tall .frame{height:100%}
}

/* ============================================================================
   BLOCK 13 — CTA / Accent Slab
   Full-bleed accent field. Text on accent is var(--bg) — AA-verified pair.
   ========================================================================= */
.cta-slab{background:var(--accent);color:var(--bg)}
.cta-slab .blk__inner{display:grid;gap:clamp(24px,4vw,40px)}
.cta-slab .blk__h{color:var(--bg)}
.cta-slab__body{color:var(--bg);opacity:.86;max-width:44ch;font-size:var(--lead)}
.cta-slab__tel{
  font-family:var(--font-display);font-weight:700;font-size:clamp(1.8rem,6vw,3.2rem);
  line-height:1;color:var(--bg);text-decoration:none;display:inline-block;
  border-bottom:3px solid color-mix(in srgb,var(--bg) 45%,transparent);
  padding-bottom:.1em;transition:border-color .16s ease-out;
}
.cta-slab__tel:hover{border-bottom-color:var(--bg)}
.cta-slab a:focus-visible{outline:2px solid var(--bg);outline-offset:4px}
@media (min-width:820px){
  .cta-slab .blk__inner{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);align-items:end}
}

/* ============================================================================
   BLOCK 14 — CTA / Hairline Band
   No fill at all. Two rules and a line of type doing the work.
   ========================================================================= */
.cta-rule .blk__inner{
  border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);
  padding-block:clamp(32px,5vw,56px);display:grid;gap:1.5rem;
}
.cta-rule__h{font-family:var(--font-display);font-weight:700;font-size:clamp(1.6rem,4.6vw,2.8rem);line-height:1.08;margin:0;letter-spacing:var(--tight)}
.cta-rule__body{color:var(--muted);max-width:48ch}
.cta-rule__tel{
  font-weight:700;font-size:1.125rem;text-decoration:none;color:var(--accent-ink);
  border-bottom:2px solid var(--accent);padding-bottom:.15em;
  transition:padding-bottom .16s ease-out;
}
.cta-rule__tel:hover{padding-bottom:.35em}
@media (min-width:800px){
  .cta-rule .blk__inner{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:var(--gap) clamp(32px,6vw,80px)}
  .cta-rule__body{grid-column:1;grid-row:2}
  .cta-rule__actions{grid-column:2;grid-row:1/span 2;text-align:right}
}

/* ============================================================================
   BLOCK 15 — FOOTER / Index Footer
   Columned index closing on a monospace slug line.
   ========================================================================= */
.ftr-index{border-top:var(--hair) solid var(--faint);padding-block:clamp(40px,6vw,72px) clamp(24px,3vw,32px)}
.ftr-index__cols{display:grid;gap:clamp(24px,4vw,40px)}
.ftr-index__col h4{font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-ink);margin:0 0 1rem;font-weight:700}
.ftr-index__col ul{list-style:none;margin:0;padding:0;display:grid;gap:.55rem}
.ftr-index__col li{color:var(--muted)}
.ftr-index__col a{color:var(--ink);text-decoration:none;border-bottom:var(--hair) solid var(--faint)}
.ftr-index__col a:hover{border-bottom-color:var(--accent)}
.ftr-index__name{font-family:var(--font-display);font-weight:700;font-size:clamp(1.4rem,3vw,2rem);line-height:1.1;margin:0 0 .6rem}
.ftr-index__slug{
  margin-top:clamp(32px,5vw,56px);padding-top:1.2rem;border-top:var(--hair) solid var(--faint);
  font-family:'Space Mono',ui-monospace,monospace;font-size:.6875rem;letter-spacing:.08em;
  color:var(--muted);display:flex;flex-wrap:wrap;gap:.4rem 1.6rem;
}
@media (min-width:760px){.ftr-index__cols{grid-template-columns:minmax(0,1.4fr) repeat(2,minmax(0,1fr))}}

/* ============================================================================
   BLOCK 16 — FOOTER / Wordmark Footer
   Contact first, then the name at maximum scale clipped by the page edge.
   ========================================================================= */
.ftr-wordmark{padding-bottom:0;overflow:hidden}
.ftr-wordmark__rows{display:grid;gap:1rem;margin-bottom:clamp(32px,5vw,56px)}
.ftr-wordmark__row{
  display:flex;flex-wrap:wrap;gap:.4rem 1rem;justify-content:space-between;
  padding-block:.9rem;border-bottom:var(--hair) solid var(--faint);
}
.ftr-wordmark__row dt{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:0}
.ftr-wordmark__row dd{margin:0;font-weight:700}
.ftr-wordmark__row a{color:var(--accent-ink);text-decoration:none;border-bottom:var(--hair) solid var(--accent)}
.ftr-wordmark__mark{
  font-family:var(--font-display);font-weight:700;line-height:.82;letter-spacing:-.04em;
  font-size:clamp(3rem,15.5vw,11rem);margin:0;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:clip;
}
.ftr-wordmark__note{padding-block:1.2rem;font-size:.75rem;color:var(--muted)}

/* ############################################################################
   VIBE — QUARRY
   Squared off, rule-lined, catalog-coded, hard offset shadows.
   ######################################################################### */
.v-quarry{--radius:0px;--tight:-.03em;--hair:1px;--stag:60ms;--blk-y:clamp(52px,9vw,108px);
  --enter:blk-rise;--enter-dur:180ms;--enter-ease:cubic-bezier(.2,0,0,1)}
.v-quarry .blk__code{display:block}
.v-quarry .blk__h{text-transform:none}
.v-quarry .blk__eyebrow{border-left:3px solid var(--accent);padding-left:.7em}
.v-quarry .rule{animation:rule-draw 320ms linear both}
.v-quarry .btn{box-shadow:5px 5px 0 var(--ink)}
.v-quarry .btn:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--ink)}
.v-quarry .frame{border:var(--hair) solid var(--ink)}
.v-quarry .svc-ledger__row:hover{background:var(--surface)}
.v-quarry .svc-mosaic__grid{background:var(--ink);border-color:var(--ink)}
.v-quarry .hero-band__slab{border:2px solid var(--ink);box-shadow:10px 10px 0 var(--accent)}
.v-quarry .tst-stagger__item{border:var(--hair) solid var(--ink);border-left-width:6px}
.v-quarry .about-numeral__figwrap{margin:0}
.about-numeral__fig{-webkit-text-stroke-color:var(--ink)}
.v-quarry .svc-rail__panel{border-color:var(--ink)}

/* ############################################################################
   VIBE — ATRIUM
   Air, a full-height column rule, inset plates, underlines that grow.
   ######################################################################### */
.v-atrium{--enter:blk-drift;--enter-dur:720ms;--enter-ease:cubic-bezier(.22,1,.36,1);
  --radius:0px;--tight:-.015em;--stag:120ms;--pad:clamp(20px,6.5vw,88px);--blk-y:clamp(64px,12vw,152px);--gap:clamp(20px,4vw,44px);--maxw:1080px}
.v-atrium .blk__inner::before{
  content:'';position:absolute;top:calc(var(--blk-y) * -.5);bottom:calc(var(--blk-y) * -.5);
  left:-1.6rem;width:var(--hair);background:var(--faint);pointer-events:none;
}
.v-atrium .blk__eyebrow{text-transform:none;letter-spacing:.06em;font-weight:400;font-style:italic;font-family:var(--font-display);font-size:.95rem}
.v-atrium .frame img{animation:img-settle 1.2s cubic-bezier(.22,1,.36,1) both}
.v-atrium .frame{padding:0}
.v-atrium .about-diptych .frame,.v-atrium .gal-irregular .frame{outline:var(--hair) solid var(--faint);outline-offset:.9rem}
.v-atrium .btn{background:transparent;color:var(--accent-ink);border:0;border-bottom:2px solid var(--accent);padding:.35em 0;border-radius:0}
.v-atrium .btn::after{content:'';display:block;height:2px;background:var(--accent-ink);width:0;transition:width .5s cubic-bezier(.22,1,.36,1);margin-top:2px}
.v-atrium .btn:hover::after{width:100%}
.v-atrium .blk__h{line-height:1.06}
.v-atrium .tst-stagger__item{border-left:0;border-top:var(--hair) solid var(--faint);background:transparent;padding-inline:0}
.v-atrium .svc-mosaic__grid{gap:0;background:transparent;border:0}
.v-atrium .svc-mosaic__cell{background:transparent;border-top:var(--hair) solid var(--faint);padding-inline:0;padding-right:var(--gap)}
.v-atrium .cta-rule .blk__inner{border-width:var(--hair)}
@media (max-width:719px){.v-atrium .blk__inner::before{left:-.7rem}}
.v-atrium .blk--flush .blk__inner::before{content:none}

/* ############################################################################
   VIBE — SIGNAL
   Edge-to-edge colour fields, clipped headline wipes, one running marquee.
   ######################################################################### */
.v-signal{--radius:0px;--tight:-.035em;--hair:2px;--stag:40ms;--display:clamp(2.4rem,9vw,6rem);
  --enter:blk-wipe;--enter-dur:260ms;--enter-ease:cubic-bezier(.34,1.56,.64,1)}
.v-signal .blk__eyebrow{background:var(--accent);color:var(--bg);display:inline-block;padding:.35em .7em;letter-spacing:.2em}
.v-signal .blk__h{text-transform:uppercase;line-height:.94}
.v-signal .btn{border-width:2px;border-radius:0;padding:1em 1.8em;letter-spacing:.04em}
.v-signal .btn:hover{transform:translateY(-3px)}
.v-signal .frame{border:2px solid var(--ink)}
/* alternating full-bleed field: the services + testimonials blocks invert */
.v-signal .svc-mosaic,.v-signal .tst-pull{background:var(--ink);color:var(--bg)}
.v-signal .svc-mosaic .blk__h,.v-signal .tst-pull blockquote{color:var(--bg)}
.v-signal .svc-mosaic .svc-mosaic__grid{background:var(--bg);border-color:var(--bg)}
.v-signal .svc-mosaic .svc-mosaic__cell{background:var(--ink);color:var(--bg)}
.v-signal .svc-mosaic .svc-mosaic__cell p{color:color-mix(in srgb,var(--bg) 78%,transparent)}
.v-signal .tst-pull .tst-pull__by,.v-signal .tst-pull .tst-pull__row p{color:color-mix(in srgb,var(--bg) 78%,transparent)}
.v-signal .tst-pull .tst-pull__row{border-top-color:color-mix(in srgb,var(--bg) 30%,transparent)}
.v-signal .tst-pull .tst-pull__row cite{color:var(--accent)}
.v-signal .tst-pull blockquote::before{color:var(--accent)}
.v-signal .marquee{
  display:block;overflow:hidden;background:var(--accent);color:var(--bg);
  padding-block:.7rem;margin-top:clamp(32px,5vw,56px);border-block:2px solid var(--ink);
}
/* The band is a full-bleed motif. Flush blocks already sit at the page edge;
   padded blocks have to be pulled back out to it (and only them, or it overflows). */
.v-signal .blk:not(.blk--flush) > .marquee{margin-inline:calc(var(--pad) * -1)}
.v-signal .marquee__track{display:flex;width:max-content;animation:marquee-run 28s linear infinite}
.v-signal .marquee__track span{
  font-family:var(--font-display);font-weight:700;text-transform:uppercase;
  letter-spacing:.06em;font-size:clamp(.95rem,2.2vw,1.3rem);padding-inline:1.2rem;white-space:nowrap;
}
.v-signal .hero-index__table{border-top-width:4px}
.v-signal .cta-rule .blk__inner{border-width:4px}

/* ############################################################################
   VIBE — WORKSHOP
   Paper, dotted leaders, taped corners, exactly one crooked thing per section.
   ######################################################################### */
.v-workshop{--radius:2px;--tight:-.01em;--stag:70ms;
  --enter:blk-settle;--enter-dur:420ms;--enter-ease:cubic-bezier(.16,1,.3,1)}
/* Texture only — never re-declare background-color here. `.blk` already sets the
   base, and this selector outranks it, so restating it would clobber any block
   that fills itself (.cta-slab's accent slab) and leave its --bg text invisible. */
.v-workshop .blk{
  background-image:radial-gradient(color-mix(in srgb,var(--ink) 5%,transparent) .7px,transparent .7px);
  background-size:5px 5px;                     /* paper tooth */
}
.v-workshop .blk__eyebrow{font-style:italic;letter-spacing:.08em;text-transform:none;font-size:.9rem}
.v-workshop .leader{
  display:block;flex:1 1 auto;min-width:1.5rem;margin:0 .5rem;align-self:end;
  border-bottom:1.5px dotted var(--faint);transform:translateY(-.35em);
}
.v-workshop .btn{box-shadow:3px 3px 0 color-mix(in srgb,var(--ink) 22%,transparent);border-radius:2px}
.v-workshop .btn:hover{box-shadow:3px 5px 0 color-mix(in srgb,var(--ink) 28%,transparent);transform:translateY(-2px)}
.v-workshop .frame{border:var(--hair) solid var(--faint);overflow:visible}
.v-workshop .frame img{border-radius:2px}
/* taped corner tab — one per framed plate */
.v-workshop .frame::before{
  content:'';position:absolute;top:-9px;left:14%;width:64px;height:19px;
  background:color-mix(in srgb,var(--accent) 26%,var(--surface));
  border:var(--hair) solid color-mix(in srgb,var(--ink) 12%,transparent);
  transform:rotate(-2.5deg);z-index:1;
}
.v-workshop .hero-band__slab{transform:rotate(-.4deg)}   /* the one crooked thing */
.v-workshop .svc-ledger__row{grid-template-columns:2.75rem minmax(0,1fr)}
.v-workshop .svc-ledger__name{display:flex;align-items:baseline}
.v-workshop .tst-stagger__item{border-left-style:dashed;background:var(--surface)}
.v-workshop .tst-stagger__item:nth-child(2){transform:rotate(.4deg)}
.v-workshop .svc-mosaic__grid{background:var(--faint)}
.v-workshop .about-numeral__figwrap{margin:0}
.about-numeral__fig{-webkit-text-stroke-width:2px}
.v-workshop .ftr-index__slug{font-style:normal}
@media (min-width:840px){.v-workshop .svc-ledger__row{grid-template-columns:3.5rem minmax(0,15rem) minmax(0,1fr)}}
