/* ==========================================================================
   Ported blocks — "We are great at" and "Our process, your advantage".
   Lifted from the studio's second homepage build and kept at its exact
   appearance. Everything is scoped to .zf-block so none of it reaches the
   rest of the site, and the few global rules in studio.css that would
   otherwise bleed in (img filter, display font on headings, body colour)
   are neutralised at the top of the scope.
   ========================================================================== */

.zf-block {
  /* Palette is self-contained: these names exist only inside a ported block. */
  --zf-primary: #F3FE00;
  --zf-white: #FFFFFF;
  --zf-cream: #FAF9F4;
  --zf-ink: #0B0B0B;
  --zf-gray-02: #1B1818;
  --zf-gray-03: #2A2727;
  --zf-muted-dark: #463F3F;
  --zf-muted-light: #5B5252;
  --zf-gray-200: #8F8F8F;
  --zf-gray-495: #D5D5D5;
  --zf-rail: linear-gradient(270deg, rgba(255,255,255,.20) 86.27%, rgba(255,255,255,0) 88.15%);

  position: relative;
  font-family: 'Inter Tight', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  letter-spacing: normal;
}

.zf-block--cream { background-color: var(--zf-cream); color: var(--zf-ink); }

/* ── Undo the site-wide rules that would otherwise reach in ─────────── */
.zf-block img { filter: none; transition: none; }
.zf-block h1, .zf-block h2, .zf-block h3, .zf-block h4 {
  font-family: inherit; letter-spacing: normal; font-weight: 400; margin: 0;
}
.zf-block p, .zf-block ul, .zf-block li { margin: 0; padding: 0; }
.zf-block ul { list-style: none; }
.zf-block a { color: inherit; text-decoration: none; }

/* ── Layout utilities (scoped) ──────────────────────────────────────── */
.zf-block .container { max-width: 1400px; margin: 0 auto; padding: 0 80px; }
.zf-block .flex { display: flex; }
.zf-block .grid { display: grid; }
.zf-block .flex-col { flex-direction: column; }
.zf-block .items-center { align-items: center; }
.zf-block .justify-between { justify-content: space-between; }
.zf-block .justify-center { justify-content: center; }
.zf-block .shrink-0 { flex-shrink: 0; }
.zf-block .relative { position: relative; }
.zf-block .overflow-hidden { overflow: hidden; }
.zf-block .list-unstyled { list-style: none; }
.zf-block .w-full { width: 100%; }
.zf-block .h-full { height: 100%; }
.zf-block .object-cover { object-fit: cover; }
.zf-block .mx-auto { margin-left: auto; margin-right: auto; }
.zf-block .text-center { text-align: center; }
.zf-block .uppercase { text-transform: uppercase; }
.zf-block .hidden { display: none; }
.zf-block .gap-80 { gap: 80px; }
.zf-block .mt_64 { margin-top: 64px; }
.zf-block .py_80 { padding-top: 80px; padding-bottom: 80px; }
.zf-block .section-heading { margin-top: 16px; margin-bottom: 16px; }

.zf-block .ff_inter { font-family: Inter, sans-serif !important; }
.zf-block .fs_14 { font-size: 14px; }
.zf-block .fs_16 { font-size: 16px; }
.zf-block .fs_18 { font-size: 18px; }
.zf-block .fs_28 { font-size: 28px; }
.zf-block .fs_36 { font-size: 36px; }
.zf-block .lh_21 { line-height: 21px; }
.zf-block .lh_24 { line-height: 24px; }
.zf-block .lh_27 { line-height: 27px; }
.zf-block .lh_40 { line-height: 40px; }
.zf-block .lh_normal { line-height: normal; }
.zf-block .fw_500 { font-weight: 500; }
.zf-block .fw_600 { font-weight: 600; }

.zf-block.zf-block .text_white { color: var(--zf-white); }
.zf-block.zf-block .text_black { color: #000; }
.zf-block.zf-block .text_primary { color: var(--zf-primary); }
.zf-block.zf-block .text_gray_02 { color: var(--zf-gray-02); }
.zf-block.zf-block .text_gray_03 { color: var(--zf-gray-03); }
.zf-block.zf-block .text_gray_495 { color: var(--zf-gray-495); }
.zf-block.zf-block .text_gray_muted_dark { color: var(--zf-muted-dark); }
.zf-block.zf-block .text_gray_muted_light { color: var(--zf-muted-light); }

/* ── "We are great at" — six cards that open on hover ───────────────── */
.zf-block .services-wraper { column-gap: 32px; }
.zf-block .service-card {
  display: block; padding: 40px 0; position: relative; z-index: 0;
  border-top: 1px solid #d7d8d4; border-bottom: 1px solid #d7d8d4;
  backdrop-filter: blur(6px);
  transition: padding-left 1s, padding-right 1s;
}
.zf-block .service-card::before {
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background-image: radial-gradient(circle at 78% 50%, rgba(243,254,0,.32) 0%, transparent 42%),
                    linear-gradient(90deg, #2d2d2d 0%, #1c1c1c 100%);
  background-position: center right 40%; background-repeat: no-repeat;
  transition: background-position 1s, opacity 1s;
}
.zf-block .service-card:hover {
  padding-left: 40px; padding-right: 40px;
  border-left: 1px solid #2d2d2d; background-color: #2d2d2d;
}
.zf-block .service-card:hover::before { background-position: center right 46px; opacity: 1; }
.zf-block .service-card:hover .servic-text,
.zf-block .service-card:hover .servic-title { color: var(--zf-white) !important; }
.zf-block .service-card:hover .arrow-box { background-color: var(--zf-white); }
.zf-block .service-card:hover .arrow-box svg path { stroke: #0D0D0D; }
.zf-block .arrow-box {
  width: 48px; height: 48px; border-radius: 50%;
  border: 1.5px solid #d7d8d4; transition: background-color 1s;
}
.zf-block .servic-title { margin-top: 20px; }

/* ── Responsive ─────────────────────────────────────────────────────── */
@media (min-width: 769px) {
  .zf-block .md_grid-cols-2 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 1204px) {
  .zf-block .container { padding: 0 60px; }
}
@media (max-width: 991px) {
  .zf-block .container { padding: 0 40px; }
  .zf-block .gap-80 { gap: 40px; }
}
@media (max-width: 768px) {
  .zf-block .md_hidden { display: none; }
  .zf-block .md_block { display: block !important; }
  .zf-block .service-card { padding-top: 24px; padding-bottom: 24px; }
}
@media (max-width: 575px) {
  .zf-block .container { padding: 0 24px; }
  .zf-block .sm_block { display: block; }
  .zf-block .sm_py_32 { padding-top: 32px; padding-bottom: 32px; }
  .zf-block .sm_mt_32 { margin-top: 32px !important; }
  .zf-block .sm_fs_14 { font-size: 14px; }
  .zf-block .sm_fs_16 { font-size: 16px; }
  .zf-block .sm_fs_20 { font-size: 20px; }
  .zf-block .sm_fs_22 { font-size: 22px; }
  .zf-block .sm_fs_28 { font-size: 28px; }
  .zf-block .sm_lh_21 { line-height: 21px; }
  .zf-block .sm_fw_700 { font-weight: 700; }
  .zf-block .servic-title { margin-top: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  .zf-block *, .zf-block *::before, .zf-block *::after {
    transition-duration: .001ms !important; animation-duration: .001ms !important;
  }
}

/* ==========================================================================
   Hero figures
   The four studio figures used to hold a section of their own, most of it
   empty: `.statement` pads to 12rem and `.statement--stats` asks for 72vh
   on top, so the numbers floated in a tall black gap. They now close the
   hero as a band under the plate and the title block.
   ========================================================================== */
.hero {
  /* Named so the two absolutely-positioned hero overlays can clear the
     band without guessing at its height. */
  --hero-stats: clamp(7rem, 9.5vw, 9rem);
  grid-template-rows: minmax(0, 1fr) var(--hero-stats);
}
.hero__plate { grid-column: 1; grid-row: 1; }
.hero__block { grid-column: 2; grid-row: 1; }
.hero__stats { grid-column: 1 / -1; grid-row: 2; min-width: 0; }

.hero__stats .statement-stats {
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  border-left: 0;
  border-bottom: 0;
}
.hero__stats .statement-stat {
  min-height: 0;
  align-content: center;
  gap: .2rem;
  padding: clamp(.7rem, 1.5vw, 1.05rem) clamp(.9rem, 2vw, 1.5rem);
  border-bottom: 0;
}
.hero__stats .statement-stat:last-child { border-right: 0; }
.hero__stats .statement-stat__figure strong { font-size: clamp(1.7rem, 3.1vw, 2.6rem); }
.hero__stats .statement-stat h2 { max-width: 20ch; font-size: clamp(.72rem, .95vw, .85rem); }

/* Both overlays are anchored to the hero's bottom edge, which is now the
   band rather than the plate. */
.hero__scroll { bottom: calc(var(--hero-stats) + 1.4rem); }
.hero__reveal { bottom: calc(var(--hero-stats) + clamp(2rem, 6vh, 4rem)); }

@media (max-width: 860px) {
  .hero { --hero-stats: auto; }
  /* The figures are a desktop flourish. On a phone they pushed the hero to
     nearly two screens before a single room was in view, so they stand down
     and the about block below carries the same ground in words. */
  .hero__stats { display: none; }
  .hero__stats .statement-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero__stats .statement-stat:nth-child(2n) { border-right: 0; }
  .hero__stats .statement-stat:nth-child(-n+2) { border-bottom: 1px solid var(--hair-soft); }
}
@media (max-width: 760px) {
  /* studio.css stacks the hero here; the band takes a third row. */
  .hero { grid-template-columns: 1fr; grid-template-rows: 44svh auto auto; }
  .hero__block { grid-column: 1; grid-row: 2; }
  .hero__stats { grid-column: 1; grid-row: 3; }
  .hero__reveal { bottom: clamp(2rem, 6vh, 4rem); }
}

/* ==========================================================================
   Breathing room in the two ported blocks
   They arrived on a flat 80px with a 100px gap between process stages —
   spacing drawn for a page whose type ran much longer. Against this sheet
   they read as cropped and stuck together, so both now scale with the
   viewport the way the rest of the site does.
   ========================================================================== */
.zf-block.py_80 {
  padding-top: clamp(3.5rem, 7vw, 6.5rem);
  padding-bottom: clamp(3.5rem, 7vw, 6.5rem);
}
.zf-block .mt_64 { margin-top: clamp(2.5rem, 5vw, 4rem); }


@media (max-width: 991px) {
  .zf-block.py_80 { padding-top: clamp(2.75rem, 6vw, 4rem); padding-bottom: clamp(2.75rem, 6vw, 4rem); }
}

/* ==========================================================================
   Studio map
   The Google iframe was a framed, rounded card sitting on the page. This is
   a full-bleed band on its own dark ground, with the map's edges dissolved
   into that ground so there is no boundary to read as a box. It stays dark
   in both themes, the way the process block does.
   ========================================================================== */
/* superseded by .deck below */
.map__band {
  position: relative;
  min-height: clamp(22rem, 40vw, 34rem);
  overflow: hidden;
}
.map__band > .map__canvas {
  /* Specific enough to beat maplibre-gl.css, which sets .maplibregl-map to
     position:relative once the map initialises. Losing that fight collapses
     this box to zero height and MapLibre falls back to a 300px canvas. */
  position: absolute;
  inset: 0;
  background: #0B0B0B;
  /* Deliberately not hidden until the map reports itself loaded. Tiles can
     take seconds on a slow connection, and gating on that event leaves a
     black band on screen until it fires. It paints progressively onto the
     same colour as the ground behind it, so there is nothing to hide. */
  /* The dissolve: the map has no edge of its own, it just stops being
     opaque before it reaches the ground colour. */
  -webkit-mask-image: radial-gradient(130% 125% at 50% 46%, #000 62%, transparent 100%);
          mask-image: radial-gradient(130% 125% at 50% 46%, #000 62%, transparent 100%);
}
.map__canvas.is-ready { --map-state: ready; }
/* If the tiles never arrive, say so and leave the directions link doing
   the work, rather than showing an unexplained black rectangle. */
.map__canvas.is-failed::after {
  content: 'Map unavailable 4 use Directions below';
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1rem;
  text-align: center;
  font-family: var(--sans);
  font-size: .78rem;
  letter-spacing: .04em;
  color: rgba(255, 255, 255, .45);
}

/* MapLibre's own furniture, dressed down to suit the band. */
.map__canvas .maplibregl-ctrl-attrib {
  background: rgba(0, 0, 0, .55);
  color: rgba(255, 255, 255, .55);
  font-size: 10px;
}
.map__canvas .maplibregl-ctrl-attrib a { color: rgba(255, 255, 255, .75); }
.map__canvas .maplibregl-ctrl-group {
  background: rgba(12, 12, 12, .82);
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: none;
}
.map__canvas .maplibregl-ctrl-group button + button { border-top-color: rgba(255, 255, 255, .12); }
.map__canvas .maplibregl-ctrl-group button span { filter: invert(1); }

/* ── The studio marker ─────────────────────────────────────────────────── */
/* 37px against the old 22 — seventy per cent larger, with the dot and its
   halo scaled by the same factor so the proportions hold. Gold rather than
   the road blue: #e3c05b is the gold the studio figures are already set in,
   and it lifts the studio off a map whose roads are blue. */
.map__marker { position: relative; width: 37px; height: 37px; }
.map__marker-dot {
  position: absolute; inset: 10px;
  border-radius: 50%;
  background: #e3c05b;
  box-shadow: 0 0 0 4px rgba(11, 11, 11, .9), 0 0 26px 7px rgba(227, 192, 91, .75);
}
/* Two rings on the same loop, half a cycle apart, so one is always
   travelling — the pulse never lands on an empty beat. */
.map__marker-ring,
.map__marker::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(227, 192, 91, .85);
  animation: mapPing 2.6s cubic-bezier(.22, 1, .36, 1) infinite;
  pointer-events: none;
}
.map__marker::after { animation-delay: -1.3s; }
@keyframes mapPing {
  0%   { transform: scale(.5); opacity: 1; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* ── Floating cards ────────────────────────────────────────────────────── */
.map__hud {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  pointer-events: none;
  font-family: var(--sans);
}
.map__hud--top {
  top: clamp(1rem, 3vw, 1.9rem);
  left: 50%;
  transform: translateX(-50%);
  gap: clamp(.7rem, 2vw, 1.2rem);
  padding: .5rem 1rem;
  border-radius: 999px;
  background: rgba(10, 12, 16, .72);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  white-space: nowrap;
}
.map__place, .map__weather {
  display: flex; align-items: center; gap: .45rem;
  margin: 0;
  font-size: clamp(.74rem, 1.05vw, .88rem);
  color: #fff;
}
.map__weather { padding-left: clamp(.7rem, 2vw, 1.2rem); border-left: 1px solid rgba(255, 255, 255, .16); }
.map__weather[hidden] { display: none; }
.map__hud--top svg { width: 15px; height: 15px; fill: none; stroke: #3FA9FF; stroke-width: 1.6; }

.map__hud--pin {
  top: clamp(4.6rem, 11vw, 7rem);
  left: 50%;
  transform: translateX(-50%);
  gap: .8rem;
  padding: .7rem 1.1rem;
  border-radius: 12px;
  background: rgba(10, 12, 16, .78);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.map__pin-arrow svg { display: block; width: 22px; height: 22px; fill: none; stroke: #3FA9FF; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.map__pin-text { display: grid; gap: .15rem; line-height: 1.25; }
.map__pin-text b { font-size: clamp(.9rem, 1.3vw, 1.05rem); font-weight: 600; color: #fff; }
.map__pin-text { font-size: clamp(.68rem, .95vw, .78rem); color: rgba(255, 255, 255, .6); }

.map__hud--foot {
  left: clamp(1rem, 2.5vw, 1.6rem);
  right: clamp(1rem, 2.5vw, 1.6rem);
  bottom: clamp(1rem, 3vw, 1.8rem);
  gap: clamp(.8rem, 2.5vw, 1.8rem);
  flex-wrap: wrap;
}
.map__stat {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: clamp(.66rem, .92vw, .76rem);
  letter-spacing: .04em;
  color: rgba(255, 255, 255, .72);
}
.map__stat i {
  font-style: normal; font-size: .58rem; font-weight: 700; letter-spacing: .12em;
  padding: .2rem .4rem; border-radius: 4px;
  background: rgba(63, 169, 255, .16); color: #3FA9FF;
}
.map__stat--go {
  pointer-events: auto;
  margin-left: auto;
  color: #fff;
  transition: color .3s var(--ease);
}
.map__stat--go:hover { color: #3FA9FF; }
.map__stat--go em { font-style: normal; }

@media (max-width: 760px) {
  .map__band { min-height: clamp(20rem, 74vw, 26rem); }
  .map__hud--pin { display: none; }
  /* Lifted clear of the CARTO / OpenStreetMap credit, which sits along the
     bottom edge and was being written straight through. */
  .map__hud--foot { bottom: 2.5rem; justify-content: center; row-gap: .5rem; }
  .map__stat--go { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .map__marker-ring,
  .map__marker::after { animation: none; opacity: .45; }
}

/* ==========================================================================
   Enquiry & location
   The standalone "Do you have a project?" panel and the location header were
   two blocks saying the same thing in sequence. They are now one dark spread:
   the form on one side, the map on the other, on a single ground.
   ========================================================================== */
.deck {
  position: relative;
  background: #0B0B0B;
  color: #fff;
  padding: clamp(3.5rem, 8vw, 7rem) var(--page-x);
  overflow: hidden;
}
/* A slow wash of light behind the spread so the ground is not flat black. */
.deck::before {
  content: '';
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 130%;
  pointer-events: none;
  background:
    radial-gradient(46% 52% at 18% 18%, rgba(63, 169, 255, .12), transparent 70%),
    radial-gradient(40% 46% at 84% 72%, rgba(189, 122, 28, .14), transparent 72%);
  animation: deckDrift 22s var(--ease-io) infinite alternate;
}
@keyframes deckDrift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.08); }
}
.deck__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4.5vw, 4rem);
  /* Stretch, not start: the map takes the height of the form beside it so
     the two columns read as one pair rather than two loose panels. */
  align-items: stretch;
}
.deck .tag { color: rgba(255, 255, 255, .8); }
.deck .tag::before, .deck .tag::after,
.deck .tag > i::before, .deck .tag > i::after { border-color: currentColor; }
.deck__title {
  margin-top: 1.1rem;
  font-size: clamp(1.7rem, 3.4vw, 2.8rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -.02em;
  color: #fff;
}
.deck__lead {
  max-width: 46ch;
  margin-top: .9rem;
  color: rgba(255, 255, 255, .58);
  font-size: clamp(.9rem, 1.1vw, 1rem);
  line-height: 1.65;
}
.deck__address {
  margin-top: 1.6rem;
  max-width: 52ch;
  font-style: normal;
  font-size: .78rem;
  line-height: 1.7;
  color: rgba(255, 255, 255, .38);
}

/* ── The form ──────────────────────────────────────────────────────────── */
.enq { display: grid; gap: clamp(1.1rem, 2vw, 1.5rem); margin-top: clamp(1.8rem, 3.5vw, 2.6rem); }
.enq__row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.1rem, 2vw, 1.5rem); }
.enq__trap { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.enq__field { position: relative; margin: 0; }
.enq__field input,
.enq__field select,
.enq__field textarea {
  width: 100%;
  padding: 1.7rem 1.1rem .75rem;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 14px;
  background: rgba(255, 255, 255, .035);
  color: #fff;
  font: inherit;
  font-size: .95rem;
  outline: none;
  transition: border-color .45s var(--ease), background-color .45s var(--ease),
              box-shadow .45s var(--ease), transform .45s var(--ease);
}
.enq__field textarea { resize: vertical; min-height: 11rem; line-height: 1.6; }
.enq__field select { appearance: none; cursor: pointer; }
.enq__field select option { background: #141414; color: #fff; }

/* Hover lifts the field a hair out of the ground and warms its edge. */
.enq__field:hover input,
.enq__field:hover select,
.enq__field:hover textarea {
  border-color: rgba(255, 255, 255, .2);
  background: rgba(255, 255, 255, .06);
  transform: translateY(-1px);
}
.enq__field input:focus,
.enq__field select:focus,
.enq__field textarea:focus {
  border-color: rgba(63, 169, 255, .55);
  background: rgba(255, 255, 255, .07);
  box-shadow: 0 0 0 3px rgba(63, 169, 255, .12), 0 12px 34px -18px rgba(0, 0, 0, .9);
}

.enq__field--select::after {
  content: '';
  position: absolute; right: 1.15rem; top: 50%;
  width: 8px; height: 8px;
  margin-top: -6px;
  border-right: 1.5px solid rgba(255, 255, 255, .45);
  border-bottom: 1.5px solid rgba(255, 255, 255, .45);
  transform: rotate(45deg);
  pointer-events: none;
  transition: border-color .4s var(--ease);
}
.enq__field--select:hover::after { border-color: rgba(255, 255, 255, .8); }

/* The label starts where the value will sit, then rides up out of the way. */
.enq__field label {
  position: absolute;
  left: 1.15rem;
  top: 1.28rem;
  color: rgba(255, 255, 255, .5);
  font-size: .95rem;
  pointer-events: none;
  transform-origin: left top;
  transition: transform .38s var(--ease), color .38s var(--ease);
}
.enq__field--area label { top: 1.28rem; }
.enq__field label em { font-style: normal; color: var(--amber); padding-left: .15rem; }
.enq__field input:focus + label,
.enq__field input:not(:placeholder-shown) + label,
.enq__field textarea:focus + label,
.enq__field textarea:not(:placeholder-shown) + label,
.enq__field select:focus + label,
.enq__field select:valid + label {
  transform: translateY(-.78rem) scale(.72);
  color: rgba(255, 255, 255, .58);
}

/* A hairline that draws across the foot of the field on focus. */
.enq__field i {
  position: absolute;
  left: 1rem; right: 1rem; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, #3FA9FF, var(--amber));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease);
  pointer-events: none;
}
.enq__field input:focus ~ i,
.enq__field select:focus ~ i,
.enq__field textarea:focus ~ i { transform: scaleX(1); }
.enq__field.is-bad input,
.enq__field.is-bad select,
.enq__field.is-bad textarea { border-color: rgba(255, 143, 143, .7); }

/* Submit: the photo's full-width white bar, with the fill wiping across. */
.enq__send {
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: .7rem;
  width: 100%;
  margin-top: .3rem;
  padding: 1.15rem 1.6rem;
  border: 1px solid #fff;
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
  color: #0B0B0B;
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .01em;
  transition: color .5s var(--ease), border-color .5s var(--ease), box-shadow .5s var(--ease);
}
.enq__send span, .enq__send em { position: relative; z-index: 1; font-style: normal; }
.enq__send em { transition: transform .5s var(--ease); }
.enq__send::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, #3FA9FF, var(--amber));
  transform: translateX(-101%);
  transition: transform .6s var(--ease);
}
.enq__send:hover { color: #0B0B0B; border-color: transparent; box-shadow: 0 18px 46px -22px rgba(63, 169, 255, .8); }
.enq__send:hover::before { transform: translateX(0); }
.enq__send:hover em { transform: translateX(5px); }
.enq__send[disabled] { opacity: .55; pointer-events: none; }

.enq__note { min-height: 1.2rem; font-size: .8rem; color: rgba(255, 255, 255, .55); }
.enq__note.is-bad { color: #ff8f8f; }
.enq__note.is-good { color: #7ee0a5; }

@media (max-width: 980px) {
  .deck__grid { grid-template-columns: 1fr; }
  .map__band { order: -1; }
}
@media (max-width: 560px) {
  .enq__row { grid-template-columns: 1fr; }
}

/* ── The "Contact" badge above the heading ─────────────────────────────── */
.deck__pill {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .45rem 1rem .45rem .45rem;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 999px;
  background: rgba(255, 255, 255, .04);
  font-family: var(--sans);
  font-size: .82rem;
  color: rgba(255, 255, 255, .88);
  transition: border-color .5s var(--ease), background-color .5s var(--ease);
}
.deck__pill i {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .07);
}
.deck__pill svg { width: 16px; height: 16px; fill: none; stroke: #fff; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.deck__pill:hover { border-color: rgba(255, 255, 255, .24); background: rgba(255, 255, 255, .07); }
.deck__title { margin-top: 1.2rem; }

/* ── Map vignette ──────────────────────────────────────────────────────────
   The map no longer ends on an edge. It darkens outward to exactly the
   ground colour, so there is no rectangle to see — only a lit centre that
   fades into the black the section already sits on.
   ------------------------------------------------------------------------ */
.map__band::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(115% 108% at 50% 45%,
              transparent 28%,
              rgba(11, 11, 11, .32) 56%,
              rgba(11, 11, 11, .8) 80%,
              #0B0B0B 100%);
  box-shadow: inset 0 0 74px 28px #0B0B0B;
}
/* Nothing of MapLibre's own furniture is shown in the corners. */
.map__canvas .maplibregl-ctrl-bottom-right,
.map__canvas .maplibregl-ctrl-bottom-left,
.map__canvas .maplibregl-ctrl-attrib,
.map__canvas .maplibregl-ctrl-logo { display: none; }


/* The eyebrow, the display heading and the subtitle are the phone's. */
.proc-row__eyebrow, .proc-row__sub, .proc-row__t-mob,
.pstep__no, .pstep__go { display: none; }
/* Doubled: .pstep__ico sets display below this, and one class each would
   leave both marks showing on the desktop. */
.pstep__ico.pstep__ico--m { display: none; }

/* ==========================================================================
   Our process
   Five stages as a row of line icons on a cream ground. This replaces the
   scroll-driven rail and its five photographs: the photographs were doing
   the explaining, and an icon says the same thing in a tenth of the weight.
   ========================================================================== */
.proc-row {
  background: #E8E6E1;
  color: #14130f;
  padding: clamp(3.5rem, 7vw, 6.5rem) var(--page-x);
}
.proc-row.proc-row .proc-row__title {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(2.2rem, 5.4vw, 4rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -.02em;
  text-transform: uppercase;
  color: #111;
}
.proc-row__rule {
  display: block;
  width: 56px;
  height: 3px;
  margin-top: clamp(1.1rem, 2vw, 1.6rem);
  background: #C1712C;
}

.proc-row__grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(1.4rem, 3vw, 2.6rem);
  margin: clamp(2.6rem, 6vw, 5rem) 0 0;
  padding: 0;
}
.pstep { min-width: 0; }
.pstep__ico {
  display: block;
  width: clamp(62px, 6vw, 86px);
  color: #14130f;
}
.pstep__ico svg { width: 100%; height: auto; display: block; }
.proc-row.proc-row .pstep__name {
  margin: clamp(.9rem, 1.8vw, 1.4rem) 0 0;
  font-family: var(--sans);
  font-size: clamp(1.05rem, 1.6vw, 1.4rem);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -.01em;
  color: #111;
}
.pstep__short { display: none; }
.pstep__text {
  margin: clamp(.7rem, 1.4vw, 1.1rem) 0 0;
  font-size: clamp(.86rem, 1.02vw, .95rem);
  line-height: 1.6;
  color: #6f6257;
}

/* The icon lifts and warms as you pass it, the way the service cards do. */
.pstep__ico, .pstep__name { transition: transform .5s var(--ease), color .5s var(--ease); }
.pstep:hover .pstep__ico { transform: translateY(-4px); color: #C1712C; }
.proc-row.proc-row .pstep:hover .pstep__name { color: #C1712C; }

@media (max-width: 1100px) {
  .proc-row__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: clamp(2rem, 5vw, 3rem); }
}
/* The process block's own two grounds. Black under the dark theme, white
   under the light one; the gold holds on either, and the ink flips. */
.proc-row {
  --pr-bg: #FFFFFF;
  --pr-ink: #14130F;
  --pr-dim: rgba(20, 19, 15, .62);
  --pr-line: rgba(20, 19, 15, .14);
  /* The soft gold all but disappears on white; this one is darker and
     carries. On black the lighter of the two is the legible one. */
  --pr-gold: #A9741F;
}
[data-theme='dark'] .proc-row {
  --pr-bg: #000000;
  --pr-ink: #F4EEE4;
  --pr-dim: rgba(244, 238, 228, .62);
  --pr-line: rgba(244, 238, 228, .16);
  --pr-gold: #D6B06A;
}

/* ── The phone: a lit rail on a plain sheet ──────────────────────────
   The stages step down a thin gold line laid over a room, each one marked
   by a glowing point on the line, a ringed icon, its number, its name and
   a way on. The line draws itself as you reach each stage and the point
   lights when it arrives, so the block is read at the pace it is scrolled.
   -------------------------------------------------------------------- */
@media (max-width: 760px) {
  .proc-row {
    display: block;
    min-height: 0;
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: clamp(1.68rem, 5.76vw, 2.38rem) var(--page-x) clamp(1.96rem, 6.48vw, 2.66rem);
    background: var(--pr-bg);
    color: var(--pr-ink);
  }

  .proc-row__eyebrow {
    display: flex; align-items: center; justify-content: center; gap: 0.63rem;
    margin: 0 0 clamp(0.63rem, 2.16vw, 0.91rem);
    font-family: var(--sans);
    font-size: 0.42rem; font-weight: 500;
    letter-spacing: 0.21em; text-transform: uppercase;
    color: var(--pr-dim);
  }
  .proc-row__eyebrow i { width: clamp(33.6px, 11.52vw, 58.8px); height: 0.7px; background: color-mix(in srgb, var(--pr-gold) 75%, transparent); }

  /* The label is the whole heading here; the display line and the three
     words under it are gone. */
  .proc-row.proc-row .proc-row__title { display: none; }
  .proc-row__t-desk { display: none; }
  .proc-row__sub { display: none; }
  .proc-row__t-mob {
    display: block;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(1.505rem, 7.2vw, 2.1rem);
    font-weight: 400;
    line-height: 1.04;
    letter-spacing: -0.003em;
    text-transform: none;
    color: var(--pr-ink);
  }
  /* The amber bar belongs to the cream sheet, not to this. */
  .proc-row__rule { display: none; }

  .proc-row__grid {
    position: relative;
    grid-template-columns: 1fr;
    max-width: 21rem;
    margin-inline: auto;
    gap: 0;
    margin-top: clamp(1.54rem, 6.48vw, 2.24rem);
  }


  .pstep {
    position: relative;
    display: grid;
    /* 42px, to match the ring that stands in it: the earlier pass that
       took a third off the block scaled the ring but not its column. */
    grid-template-columns: 42px minmax(0, 1fr);
    column-gap: clamp(0.49rem, 2.45vw, 0.735rem);
    align-items: start;
    padding: 0 0 clamp(1.61rem, 6.12vw, 2.17rem);
  }
  .pstep__ico { display: none; }
  .pstep__ico.pstep__ico--m {
    display: grid; place-items: center;
    grid-column: 1; grid-row: 1 / span 3;
    width: 42px; height: 42px;
    max-width: none;
    border: 1px solid color-mix(in srgb, var(--pr-gold) 50%, transparent);
    border-radius: 50%;
    background: transparent;
    color: var(--pr-gold);
  }
  .pstep__ico--m svg { width: 20.3px; height: 20.3px; }

  .pstep__no {
    display: flex; align-items: center; gap: 0.49rem;
    grid-column: 2; grid-row: 1;
    margin-bottom: 0.266rem;
    font-family: var(--sans);
    font-size: 0.462rem; font-weight: 500;
    letter-spacing: 0.14em;
    color: var(--pr-gold);
  }
  .pstep__no::after {
    content: ''; flex: 1; height: 0.7px;
    background: linear-gradient(90deg, color-mix(in srgb, var(--pr-gold) 55%, transparent), transparent);
  }

  .proc-row.proc-row .pstep__name {
    grid-column: 2; grid-row: 2;
    margin: 0;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(1.05rem, 4.75vw, 1.365rem);
    font-weight: 400;
    line-height: 1.12;
    letter-spacing: 0;
    color: var(--pr-ink);
  }
  .pstep__text {
    grid-column: 2; grid-row: 3;
    margin-top: 0.21rem;
    font-family: var(--sans);
    font-size: clamp(0.56rem, 2.45vw, 0.63rem);
    font-weight: 300;
    line-height: 1.5;
    color: var(--pr-dim);
  }
  .pstep__long { display: none; }
  .pstep__short { display: inline; }

  /* The arrows led nowhere, so they go, and the two columns that remain
     take the width between them. */
  .pstep__go { display: none; }
  .pstep__go--unused {
    display: grid; place-items: center;
    grid-column: 3; grid-row: 1 / span 3;
    align-self: center;
    width: 25.2px; height: 25.2px;
    border: 1px solid color-mix(in srgb, var(--pr-gold) 45%, transparent);
    border-radius: 50%;
    color: var(--pr-gold);
    font-size: 0.595rem;
    font-style: normal;
  }


  /* Held back until the stage arrives, so the line is drawn as it is read.
     Gated on .is-anim, which the script adds: if it never runs the stages
     are simply there rather than invisible. */
  .proc-row.is-anim .pstep {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .6s var(--ease) var(--step-delay, 0ms),
                transform .6s var(--ease) var(--step-delay, 0ms);
  }
  .proc-row.is-anim .pstep.is-in { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .pstep:hover .pstep__ico { transform: none; }
  .pstep { opacity: 1 !important; transform: none !important; }
  .pstep::before { transform: scaleY(1) !important; }
  .pstep::after { transform: scaleX(1) !important; }
}

/* ==========================================================================
   Hero on narrow screens
   The hero's pinned scrub is only built above 860px, but it is never torn
   down when the window is narrowed afterwards — so its inline fades survive
   into the stacked layout. The title block is left faded to nothing, leaving
   a hole between the photograph and the figures, and the reveal line, which
   on desktop sits clear above the figures, lands straight on top of them.

   Neither belongs at this width, so both are put back by hand.
   ========================================================================== */
@media (max-width: 860px) {
  .hero__block {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__caption { opacity: 1 !important; }
  /* Decorative, and the only thing it can overlap here is the figures. */
  .hero__reveal { display: none !important; }
  /* The scrub tweens the plate to the desktop viewport in explicit pixels;
     the grid row owns its size at this width. */
  .hero__plate {
    width: auto !important;
    height: auto !important;
  }
}

/* ==========================================================================
   The name as a wordmark
   Three heavy lines stacked tight is a headline, not a mark. A studio name
   is set the way it would go on the wall: one word held open on wide
   tracking, the descriptor smaller and wider still beneath it, and the rule
   carrying the full width of the lockup rather than one word of it.

   Typographic, not calligraphic — the site's own sans, only spaced and
   weighted like an identity instead of a heading.
   ========================================================================== */
.hero__title--mark {
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: normal;
  text-transform: uppercase;
}
.hero__title--mark .hero__set:first-child {
  font-size: clamp(2.3rem, 5.4vw, 4.4rem);
  font-weight: 300;
  /* Tracking pads the right of the last letter too, so the block is pulled
     back by the same amount to keep its left edge true. */
  letter-spacing: .17em;
  margin-left: -.02em;
}
.hero__title--mark b.hero__set {
  margin-top: clamp(.5rem, 1.1vw, .85rem);
  font-size: clamp(.72rem, 1.35vw, 1.05rem);
  font-weight: 400;
  letter-spacing: .44em;
}
.hero__title--mark .hero__ruled { padding-bottom: .5em; }
.hero__title--mark .hero__ruled::after { height: 2px; }

@media (max-width: 575px) {
  .hero__title--mark .hero__set:first-child { letter-spacing: .13em; }
  .hero__title--mark b.hero__set { letter-spacing: .34em; }
}

/* ==========================================================================
   Services in dark mode
   The block was cream in both themes, so in dark mode it was a sheet of
   paper in the middle of a dark page. It now takes the same ground as the
   rest of the sheet, and everything set for dark text on cream is inverted.

   Scoped with the block class doubled: studio.css repaints every heading
   white under [data-theme='dark'] at (0,2,1), and these have to outrank it.
   ========================================================================== */
[data-theme='dark'] .zf-block--cream { background-color: #0B0B0B; color: #fff; }

[data-theme='dark'] .zf-block.zf-block .text_black { color: #fff; }
[data-theme='dark'] .zf-block.zf-block .text_gray_03 { color: #fff; }
[data-theme='dark'] .zf-block.zf-block .text_gray_02 { color: rgba(255, 255, 255, .55); }
[data-theme='dark'] .zf-block.zf-block .text_gray_muted_dark { color: rgba(255, 255, 255, .5); }
[data-theme='dark'] .zf-block.zf-block .text_gray_muted_light { color: rgba(255, 255, 255, .55); }

[data-theme='dark'] .zf-block .service-card {
  border-top-color: rgba(255, 255, 255, .12);
  border-bottom-color: rgba(255, 255, 255, .12);
}
[data-theme='dark'] .zf-block .arrow-box { border-color: rgba(255, 255, 255, .22); }
[data-theme='dark'] .zf-block .arrow-box svg path { stroke: #fff; }

/* On a dark ground the hover cannot darken further, so it lifts instead. */
[data-theme='dark'] .zf-block .service-card:hover {
  background-color: #1b1b1b;
  border-left-color: #1b1b1b;
}
[data-theme='dark'] .zf-block .service-card::before {
  background-image:
    radial-gradient(circle at 78% 50%, rgba(243, 254, 0, .22) 0%, transparent 42%),
    linear-gradient(90deg, #262626 0%, #161616 100%);
}

/* ==========================================================================
   Services on a touch screen
   There is no hover on a phone, so the whole reveal — the dark wash, the
   white type, the inverted arrow — is unreachable, and worse, tapping a
   card leaves :hover stuck on it afterwards. On touch the cards stay in
   their resting state and the arrow does the inviting instead.
   ========================================================================== */
@media (hover: none) {
  .zf-block .service-card:hover {
    padding-left: 0;
    padding-right: 0;
    border-left: 0;
    background-color: transparent;
  }
  .zf-block .service-card:hover::before { opacity: 0; }
  .zf-block .service-card:hover .servic-text,
  .zf-block .service-card:hover .servic-title { color: inherit !important; }
  .zf-block .service-card:hover .arrow-box { background-color: transparent; }
  .zf-block .service-card:hover .arrow-box svg path { stroke: currentColor; }

  /* Standing invitation rather than one that only appears under a pointer. */
  .zf-block .arrow-box {
    border-color: var(--amber);
    background-color: color-mix(in srgb, var(--amber) 12%, transparent);
  }
  .zf-block .arrow-box svg path { stroke: var(--amber); }

  /* Something has to answer the finger, since nothing else will. */
  .zf-block .service-card:active { background-color: rgba(0, 0, 0, .05); }
  [data-theme='dark'] .zf-block .service-card:active { background-color: rgba(255, 255, 255, .06); }
}

/* ==========================================================================
   Hero film
   Three photographs and a blind became one looping shot. The video fills
   the plate the way the stills did — cover, so it crops rather than letter-
   boxes at any window shape — and carries the same slow pointer drift the
   photographs had, since studio.js sets --px/--py on the figure's children.
   ========================================================================== */
.hero__figure--film { position: absolute; inset: 0; overflow: hidden; margin: 0; }
.hero__figure--film video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Matches the still plates: a touch oversized so the drift has somewhere
     to travel without showing an edge. */
  transform: scale(1.05) translate3d(var(--px, 0px), var(--py, 0px), 0);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .hero__figure--film video { transform: none; }
}

/* ==========================================================================
   Hero still
   One photograph, one effect: it eases in when the pointer is over it and
   eases back when it leaves. No drift, no light sweep — studio.js still
   writes --px/--py for the old parallax and nothing reads them now.
   ========================================================================== */
.hero__figure--still { position: absolute; inset: 0; overflow: hidden; margin: 0; }
.hero__figure--still img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* studio.css starts every .hero__figure img at opacity 0 and reveals the
     current slide with .is-active. There are no slides any more, so this one
     has to say it is visible or the plate stays empty. */
  opacity: 1;
  transform: scale(1);
  transform-origin: center;
  /* Long and eased, so it reads as the room opening up rather than a jump. */
  transition: transform 1.6s cubic-bezier(.22, 1, .36, 1);
}
.hero__plate:hover .hero__figure--still img { transform: scale(1.08); }

/* A touch screen has no hover; leaving it in would latch the zoom on tap. */
@media (hover: none) {
  .hero__plate:hover .hero__figure--still img { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__figure--still img { transition: none; }
  .hero__plate:hover .hero__figure--still img { transform: scale(1); }
}

/* ==========================================================================
   About us
   A quiet block between the hero and the plates: a label, the line that
   says what the studio is for, and a short paragraph under it. It borrows
   the page's own type and rules rather than introducing a look of its own,
   so it reads as part of the sheet and not as a panel dropped onto it.
   ========================================================================== */
.about-note {
  padding: clamp(3rem, 6.5vw, 5.5rem) var(--page-x);
  border-top: 1px solid var(--hair-soft);
}
.about-note__inner {
  display: grid;
  gap: clamp(.9rem, 2vw, 1.4rem);
  max-width: 64ch;
}
/* studio.css gives paragraphs a bottom margin; the grid gap does it here. */
.about-note.about-note p { margin: 0; }
.about-note.about-note .about-note__lead {
  color: var(--ink);
  font-size: clamp(1.12rem, 2.3vw, 1.6rem);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: -.01em;
  text-wrap: balance;
}
.about-note.about-note .about-note__body {
  max-width: 56ch;
  color: var(--muted);
  font-size: clamp(.95rem, 1.3vw, 1.02rem);
  line-height: 1.75;
}
@media (max-width: 640px) {
  .about-note { padding-top: clamp(2.4rem, 9vw, 3.2rem); }
}

/* ==========================================================================
   Off the phone
   Two blocks that read well across a desktop and only add scrolling on a
   handset. The services list repeats what the about block and the plates
   already say, so on a phone the page goes hero, about, work. Both are
   untouched above 860px.
   ========================================================================== */
@media (max-width: 860px) {
  .zf-block#services { display: none; }
}

/* ==========================================================================
   The enquiry form on a phone
   Stacked one field to a row it ran well past a screen, and a form you have
   to scroll to see the end of reads as more work than it is. The pairs go
   back to two across, the fields lose the padding they only need under a
   mouse, and the message box asks for three lines rather than seven.
   Nothing here changes above 640px.
   ========================================================================== */
@media (max-width: 640px) {
  .deck { padding: 1.75rem var(--page-x) 2rem; }
  .deck__grid { gap: 1.5rem; }

  .deck__pill { padding: .32rem .8rem .32rem .32rem; font-size: .74rem; }
  .deck.deck .deck__title { margin-top: .7rem; font-size: 1.5rem; }
  .deck.deck .deck__lead {
    margin-top: .5rem;
    font-size: .8rem;
    line-height: 1.5;
  }

  .enq { gap: .6rem; margin-top: 1rem; }
  /* Two across again: the pairs belong together and stacking them was most
     of the length. Overrides the single column set at 560px above. */
  .enq__row { grid-template-columns: 1fr 1fr; gap: .6rem; }

  .enq__field input,
  .enq__field select,
  .enq__field textarea {
    padding: 1.15rem .75rem .45rem;
    border-radius: 11px;
    font-size: .85rem;
  }
  .enq__field textarea { min-height: 4.6rem; }

  /* The label rests centred in the field and rides up when it is filled.
     Both positions are tied to the padding above, so shrinking one without
     the other leaves the label sitting on the value. */
  .enq__field label,
  .enq__field--area label { left: .75rem; top: .88rem; font-size: .78rem; }
  .enq__field input:focus + label,
  .enq__field input:not(:placeholder-shown) + label,
  .enq__field textarea:focus + label,
  .enq__field textarea:not(:placeholder-shown) + label,
  .enq__field select:focus + label,
  .enq__field select:valid + label { transform: translateY(-.6rem) scale(.72); }

  /* The chevron follows the field's own right-hand padding. */
  .enq__field--select::after { right: .75rem; width: 7px; height: 7px; margin-top: -5px; }

  .enq__send { margin-top: .1rem; padding: .8rem 1.2rem; border-radius: 11px; font-size: .88rem; }
  .enq__note { min-height: .9rem; font-size: .72rem; }
}

/* ==========================================================================
   The studio introduces itself in the hero, on a phone
   Two blocks were saying the same thing one after the other: the trades
   line under the wordmark, then an about block a screen below it. On a
   phone the about lines go straight into the hero and both of the others
   stand down. The desktop keeps its own arrangement.
   ========================================================================== */
.hero__about { display: none; }

@media (max-width: 860px) {
  .hero__fields { display: none; }
  .about-note { display: none; }

  .hero__about {
    display: grid;
    gap: .6rem;
    max-width: 36ch;
    margin-top: 1rem;
    /* Arrives with the rest of the block rather than snapping in after it. */
    opacity: 0;
    animation: heroRise .9s var(--ease-io) .12s forwards;
  }
  .hero__about p { margin: 0; }
  .hero__about-lead {
    color: var(--ink);
    font-size: 1.02rem;
    line-height: 1.42;
    letter-spacing: -.01em;
  }
  .hero__about-body {
    color: var(--muted);
    font-size: .86rem;
    line-height: 1.62;
  }
}
/* If the animation never runs, the lines are simply there. */
@media (prefers-reduced-motion: reduce) {
  .hero__about { opacity: 1; animation: none; }
}

/* ==========================================================================
   One title for every block
   Three blocks were each announcing themselves differently: the work and
   about blocks with the corner-bracket label, the contact block with a
   heading at 2.8rem, the services block with a grey uppercase eyebrow over
   a 36px heading in a heavier weight, and the process block shouting in
   uppercase at 4rem. The two imported blocks are brought onto the contact
   block's heading — the one the site already treats as its title — so a
   reader meets the same voice at every stop down the page.

   Doubled class names throughout: the imported blocks carry their own
   utility classes, and [data-theme='dark'] :is(h1,h2,...) sits at (0,2,1).
   ========================================================================== */
.zf-block.zf-block .section-heading,
.proc-row.proc-row .proc-row__title {
  font-family: var(--sans);
  font-size: clamp(1.7rem, 3.4vw, 2.8rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -.02em;
  text-transform: none;
}

/* The label sits above the title with the same air the other blocks give it. */
.zf-block.zf-block .tag { margin-bottom: 1.1rem; }
.zf-block.zf-block .section-heading { margin-top: 0; }

/* The rule stays: it is the process block's own mark, and the contact block
   has its pill in the same place. */
.proc-row__rule { margin-top: clamp(1rem, 1.8vw, 1.4rem); }

/* ==========================================================================
   The hero name plate
   The half of the hero that carries the name is a dark stone panel: a warm
   pool of light falling across the top corner, two faint shafts crossing it,
   and a fine grain so a large flat area does not band. The name itself is
   set in a high-contrast serif, which is what makes it read as a mark rather
   than as a heading.

   The panel keeps its own colours in both themes, the way the contact block
   does — it is a plate, not a page.
   ========================================================================== */
.hero .hero__block {
  --plate-ink: #F3EEE5;
  --plate-gold: #C9A24A;
  --plate-dim: rgba(243, 238, 229, .58);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  color: var(--plate-ink);
  background-color: #0A0908;
  background-image: url('../herobg.webp');
  background-size: cover;
  /* The light falls across the top left of the plate and the olive branch
     sits in the bottom right, so the crop is anchored there — centring it
     loses the branch on a tall, narrow panel. */
  background-position: right bottom;
  background-repeat: no-repeat;
  padding: clamp(3rem, 9vh, 7.5rem) clamp(1.6rem, 4.2vw, 4.5rem);
}
/* ── Est. line ─────────────────────────────────────────────────────────── */
.hero .hero__slug {
  font-size: .58rem;
  font-weight: 500;
  letter-spacing: .3em;
  color: var(--plate-dim);
}
.hero .hero__slug i { width: 34px; background: var(--plate-gold); }

/* ── The name ──────────────────────────────────────────────────────────── */
.hero .hero__title--mark {
  font-family: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  color: var(--plate-ink);
}
.hero .hero__title--mark .hero__set:first-child {
  font-size: clamp(2.9rem, 7vw, 6.1rem);
  font-weight: 300;
  letter-spacing: .155em;
  line-height: 1;
}
.hero .hero__title--mark b.hero__set {
  margin-top: clamp(.35rem, .9vw, .7rem);
  font-size: clamp(.8rem, 1.55vw, 1.32rem);
  font-weight: 300;
  letter-spacing: .42em;
  color: var(--plate-ink);
}
.hero .hero__title--mark .hero__ruled::after {
  height: 1px;
  background: rgba(243, 238, 229, .38);
}

/* The gold stroke laid through the A. It is drawn over the letter rather
   than beside it, so it reads as one mark and not as a stray rule. */
.hero .hero__a { position: relative; display: inline-block; font-style: normal; }
.hero .hero__a svg {
  position: absolute; left: -9%; top: 5%;
  width: 118%; height: 88%;
  overflow: visible;
  fill: var(--plate-gold);
  pointer-events: none;
}

/* ── The two lines under the name ──────────────────────────────────────── */
.hero .hero__lead {
  max-width: 34ch;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: clamp(1.05rem, 1.55vw, 1.42rem);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .015em;
  color: rgba(243, 238, 229, .9);
}
.hero .hero__fields {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: clamp(.7rem, 1.5vw, 1.35rem);
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: clamp(1rem, 1.45vw, 1.3rem);
  font-weight: 400;
  letter-spacing: .04em;
  color: rgba(243, 238, 229, .82);
}
.hero .hero__fields b {
  width: 1px; height: 1.15em;
  background: rgba(201, 162, 74, .55);
}

/* ── The way through ───────────────────────────────────────────────────── */
.hero .hero__go {
  margin-top: clamp(.4rem, 1.4vh, 1rem);
  padding: 1rem 1.9rem;
  border: 1px solid rgba(201, 162, 74, .55);
  border-radius: 0;
  color: var(--plate-gold);
  font-size: .63rem;
  font-weight: 600;
  letter-spacing: .24em;
  transition: background-color .5s var(--ease), color .5s var(--ease),
              border-color .5s var(--ease);
}
.hero .hero__go em { transition: transform .5s var(--ease); }
.hero .hero__go:hover {
  background: var(--plate-gold);
  border-color: var(--plate-gold);
  color: #14120E;
}
.hero .hero__go:hover em { transform: translateX(5px); }

/* ── The decoration ────────────────────────────────────────────────────── */
.hero .hero__edge {
  position: absolute; right: clamp(.9rem, 1.6vw, 1.7rem); top: 50%;
  z-index: 2;
  display: flex; align-items: center; gap: 1.1rem;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--sans);
  font-size: .54rem; font-weight: 500;
  letter-spacing: .34em; text-transform: uppercase;
  color: rgba(243, 238, 229, .34);
  pointer-events: none;
}
.hero .hero__edge::before,
.hero .hero__edge::after {
  content: ''; width: 1px; height: clamp(28px, 5vh, 54px);
  background: rgba(243, 238, 229, .2);
}

/* On a phone the plate is the whole width and the decoration only crowds
   the lines that matter, so it stands down. */
@media (max-width: 860px) {
  .hero .hero__edge { display: none; }
  /* A tall, narrow crop of the plate: the middle of the stone rather than
     the corner the branch fills, which would sit under the words. */
  .hero .hero__block { background-position: 62% 38%; }
  /* The plate's own rule for this line is more specific than the one that
     retired it on a phone, so it has to be said again here: the about lines
     below carry this ground already. */
  .hero .hero__fields { display: none; }
  .hero .hero__block { padding: clamp(2rem, 5vh, 3rem) var(--page-x) clamp(2.4rem, 6vh, 3.5rem); }
  .hero .hero__about-lead { color: var(--plate-ink); }
  .hero .hero__about-body { color: rgba(243, 238, 229, .72); }
}

/* The photograph carries the hero on its own — no veil over it. The room
   is dark at either setting of the theme (its mean luminance is 38 of 255,
   28 across the top third), so the ink stays light in both rather than
   turning dark under the light theme and disappearing into the floor. */
.hero {
  --hero-ink: #FCF9F4;
  --hero-dim: rgba(240, 234, 225, .78);
  --hero-quiet: rgba(246, 241, 233, .92);
}

/* ==========================================================================
   The hero on a phone: one photograph, everything on it
   The wide screen sets the room beside the name on stone. Stacked, that was
   two pictures one above the other and the studio had said nothing by the
   end of the second. Here there is one room, edge to edge, and the whole
   introduction stands on it.

   The wrapper the signature sits in stays display: contents throughout, so
   the lines simply flow in the plate's own grid — nothing is lifted out of
   place at either width.
   ========================================================================== */
.hero__brand { display: contents; }

@media (max-width: 760px) {
  .hero {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(100svh, auto);
    min-height: 100svh;
    /* The studio's own reception, shot upright. At 941x1672 against a
       phone it covers on height exactly, so nothing is lost top or
       bottom and only the outer edges are trimmed — which is why the
       position is centred rather than pulled up as the old plate was. */
    background-color: #EFE9E0;
    background-image: url('../hero-mobile.webp');
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: no-repeat;
  }
  /* The photograph is the ground now, so the framed one comes out: two
     pictures stacked was the thing to be rid of. */
  .hero__plate { display: none; }

  /* Enough shade to read every line, and least of it across the top where
     the room should still be a room. */

  .hero .hero__block {
    grid-column: 1; grid-row: 1;
    position: relative;
    z-index: 1;
    isolation: auto;
    overflow: visible;
    background: none;
    align-content: center;
    gap: 0;
    padding: clamp(5.5rem, 17vh, 8rem) var(--page-x) clamp(4.5rem, 13vh, 6rem);
  }

  /* ── The signature ─────────────────────────────────────────────────── */
  .hero .hero__slug {
    margin-bottom: clamp(.55rem, 2vw, .85rem);
    font-size: .59rem;
    letter-spacing: .26em;
    color: var(--hero-quiet);
  }
  .hero .hero__slug i { width: 30px; background: #D6A85C; }

  .hero .hero__title--mark .hero__set:first-child { font-size: clamp(2.75rem, 12.6vw, 3.5rem); }
  .hero .hero__title--mark b.hero__set { font-size: clamp(.86rem, 3.9vw, 1.1rem); }
  /* The second line and the rule kept the stone plate's cream, which
     vanishes once the light theme pales the room behind them. */
  .hero .hero__title--mark,
  .hero .hero__title--mark b.hero__set { color: var(--hero-ink); }
  .hero .hero__ruled::after { background: color-mix(in srgb, var(--hero-ink) 45%, transparent); }

  .hero .hero__lead {
    margin-top: clamp(.85rem, 3.4vw, 1.25rem);
    font-size: clamp(1.02rem, 4.5vw, 1.3rem);
    color: var(--hero-ink);
  }

  /* ── What the studio says ──────────────────────────────────────────── */
  .hero .hero__about {
    margin-top: clamp(1.5rem, 6vw, 2.2rem);
    max-width: none;
    gap: 0;
  }
  .hero .hero__about-lead {
    font-family: var(--sans);
    font-size: clamp(1.08rem, 4.8vw, 1.38rem);
    font-weight: 400;
    line-height: 1.38;
    letter-spacing: -.005em;
    color: var(--hero-ink);
  }
  /* The short gold rule that separates the promise from the explanation. */
  .hero .hero__about-body::before {
    content: '';
    display: block;
    width: 38px; height: 2px;
    margin: clamp(1rem, 4vw, 1.4rem) 0 clamp(.95rem, 3.6vw, 1.3rem);
    background: #D6A85C;
  }
  .hero .hero__about-body {
    font-size: clamp(.88rem, 3.7vw, .98rem);
    line-height: 1.62;
    color: var(--hero-dim);
  }

  /* ── The way through ───────────────────────────────────────────────── */
  .hero .hero__go {
    margin-top: clamp(1.5rem, 6vw, 2.1rem);
    padding: 1.05rem 1.7rem;
    gap: 1.1rem;
    font-size: .66rem;
    letter-spacing: .22em;
  }

  /* ── The mark at the foot ──────────────────────────────────────────── */
  /* studio.css and panels.css both retire this at small widths; the mark at
     the foot of the reference is this element, so it is asked for again by
     name — doubled, because those two rules are single-class and one of them
     is in a sheet that loads after this one. */
  .hero .hero__scroll {
    display: grid;
    right: auto; left: 50%;
    bottom: clamp(1rem, 3.5vh, 1.8rem);
    transform: translateX(-50%);
    gap: .5rem;
  }
  .hero .hero__scroll span { display: none; }
  .hero .hero__scroll i { height: 34px; background: rgba(214, 168, 92, .45); }
  .hero .hero__scroll i::after { background: #D6A85C; }
  .hero .hero__scroll::after {
    content: '';
    width: 9px; height: 9px;
    margin-top: -.15rem;
    border-right: 1.5px solid #D6A85C;
    border-bottom: 1.5px solid #D6A85C;
    transform: rotate(45deg);
  }

  /* ── The reception, and nothing standing on it ──────────────────────
     The phone ground is now the studio's own reception, and the practice
     is already signed on the wall in it. So the wordmark, the trades
     line, the way through and the scroll mark all stand down, and the
     only thing left over the photograph is what the studio says — set
     small, into the bottom right corner, on the clear floor. */
  .hero .hero__brand,
  .hero .hero__fields,
  .hero .hero__go,
  .hero .hero__edge,
  .hero .hero__scroll { display: none; }

  /* The block is the grid cell that fills the hero, so it stops being a
     centred column and becomes the frame the note is placed inside. */
  .hero .hero__block {
    position: relative;
    display: block;
    padding: 0;
    min-height: 100svh;
  }
  .hero .hero__about {
    position: absolute;
    right: var(--page-x, 20px);
    /* Clear of the WhatsApp button, which is fixed 52px square at 14px
       from both edges — the note used to end underneath it. */
    bottom: calc(var(--page-x, 20px) + 4.2rem);
    width: min(74vw, 21rem);
    max-width: none;
    margin: 0;
    gap: 0;
    text-align: right;
  }
  /* The floor it sits on is a light travertine, so the ink stays dark
     here whichever theme the rest of the page is in. */
  .hero .hero__about-lead {
    font-family: var(--sans);
    font-size: .74rem;
    line-height: 1.5;
    font-weight: 400;
    letter-spacing: 0;
    color: #2C2317;
  }
  .hero .hero__about-body {
    margin-top: .5rem;
    font-size: .68rem;
    line-height: 1.5;
    color: #4A3D2C;
  }
  /* The gold rule belonged to the tall arrangement, not to a corner. */
  .hero .hero__about-body::before { display: none; }
}

/* The same two grounds, declared on the document so blocks other than the
   process one can take them — the plates and the services do, on a phone. */
:root {
  --pr-bg: #FFFFFF;
  --pr-ink: #14130F;
  --pr-dim: rgba(20, 19, 15, .62);
  --pr-gold: #A9741F;
}
[data-theme='dark'] {
  --pr-bg: #000000;
  --pr-ink: #F4EEE4;
  --pr-dim: rgba(244, 238, 228, .62);
  --pr-gold: #D6B06A;
}

/* ==========================================================================
   One ground from the work to the process
   The plates and the services ran over whatever the page was under them.
   On a phone they take the process block's own sheet, so the run reads as
   one surface: black under the dark theme, white under the light.
   ========================================================================== */
@media (max-width: 760px) {
  .folio, .zf-block#services { background: var(--pr-bg); color: var(--pr-ink); }
}
