/* ==== self-hosted fonts - no third-party request, no IP shared with Google ==== */
@font-face{font-family:'Fraunces';font-style:normal;font-weight:300 600;font-display:swap;src:url('../fonts/fraunces.woff2') format('woff2');}
@font-face{font-family:'Fraunces';font-style:italic;font-weight:300 600;font-display:swap;src:url('../fonts/fraunces-italic.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:300 700;font-display:swap;src:url('../fonts/hanken.woff2') format('woff2');}

/* ============================================================
   PCL PRIVATE OFFICE — working brand name, PLACEHOLDER
   v5 — the private deck.
   Not pages. Screens. One photograph, one line, one figure, one call.
   Ink on warm cream. No gold. No menu. The real WhatsApp mark.
   ============================================================ */

:root {
  --ease-settle: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-quick: 350ms;
  --dur-settle: 900ms;
  --ink: #141311;
  --ink-soft: #2a2825;
  --cream: #f4f1eb;
  --cream-deep: #ece7de;
  --paper: #faf8f4;
  --mute: rgba(20, 19, 17, 0.58);
  --faint: rgba(20, 19, 17, 0.32);
  --wa: #25d366;
  --serif: "Fraunces", "Georgia", serif;
  --sans: "Hanken Grotesk", "Helvetica Neue", Arial, sans-serif;
  --pad: clamp(1.4rem, 5vw, 6rem);
  --mast-h: 92px;
  --measure: 34em;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { overflow-x: hidden; }   /* v9.3: snap removed - the deck is one continuous page */
/* smooth only for in-page interaction, never the initial anchor landing */
html:focus-within { scroll-behavior: smooth; }

/* pages crossfade as one continuous room; chrome persists */
@view-transition { navigation: auto; }
.masthead .wordmark { view-transition-name: wordmark; }
.wa-float { view-transition-name: wafloat; }
body {
  overflow-x: hidden;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
::selection { background: var(--ink); color: var(--cream); }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; background: none; border: none; color: inherit; }
svg { display: inline-block; }

.shell { max-width: 1400px; margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }
.narrow { max-width: 62rem; }

/* ---------- type ---------- */
h1, h2, h3, .serif {
  font-family: var(--serif);
  font-weight: 340;
  font-variation-settings: "opsz" 120, "SOFT" 20, "WONK" 0;
  line-height: 1.02;
  letter-spacing: -0.02em;
}
em, i { font-style: italic; font-variation-settings: "opsz" 144, "SOFT" 60, "WONK" 1; }
.t-hero { font-size: clamp(2.8rem, 6.6vw, 6.2rem); line-height: 0.96; letter-spacing: -0.03em; }
.t-1 { font-size: clamp(2.4rem, 5.2vw, 4.6rem); }
.t-2 { font-size: clamp(1.8rem, 3.4vw, 3rem); }
.small-caps { font-family: var(--sans); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase; color: var(--mute); }
.lede { font-size: clamp(1.1rem, 1.5vw, 1.32rem); line-height: 1.6; color: var(--ink-soft); font-weight: 350; max-width: var(--measure); }
.prose p { max-width: var(--measure); color: var(--ink-soft); font-size: 1.05rem; line-height: 1.7; margin-bottom: 1.25em; }
.prose p:last-child { margin-bottom: 0; }
.prose p strong { font-weight: 500; color: var(--ink); }
.link { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; text-decoration-color: var(--faint); transition: text-decoration-color 0.3s; }
.link:hover { text-decoration-color: currentColor; }

/* ---------- actions ---------- */
.act {
  display: inline-flex; align-items: center; gap: 0.75em;
  padding: 1.05em 1.9em; font-size: 0.78rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
  background: var(--ink); color: var(--cream); transition: background 0.3s ease, transform 0.3s ease;
}
.act:hover { background: var(--ink-soft); }
.act:active { transform: translateY(1px); }
.act.quiet { background: transparent; color: var(--ink); padding: 1.05em 0; }
.act.quiet:hover { color: var(--mute); }
.act.quiet::after { content: "→"; margin-left: 0.2em; transition: transform 0.3s ease; }
.act.quiet:hover::after { transform: translateX(4px); }
.act-row { display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem 2.4rem; }

/* WhatsApp — the real mark. Green roundel, white handset. Alone. */
.wa-mark { display: inline-block; width: 2.6rem; height: 2.6rem; border-radius: 50%; transition: transform 0.35s cubic-bezier(0.16,1,0.3,1), box-shadow 0.35s ease; }
.wa-mark svg { width: 100%; height: 100%; display: block; }
.wa-mark:hover { transform: scale(1.06); }
/* "Speak to an Asset Manager" — plain serif text that opens WhatsApp; the one floating mark says how */
.wa-speak { display: inline-flex; align-items: baseline; gap: 0.5em; }
.wa-speak .say { font-family: var(--serif); font-size: clamp(1.2rem, 1.8vw, 1.5rem); color: var(--ink); border-bottom: 1px solid rgba(20,19,17,0.35); padding-bottom: 0.12em; transition: border-color 0.3s, color 0.3s; }
.wa-speak .say::after { content: " →"; font-family: var(--sans); font-size: 0.8em; }
.wa-speak:hover .say { border-color: var(--ink); }
.wa-speak.on-photo .say { color: var(--cream); border-color: rgba(244,241,235,0.45); }
.wa-speak.on-photo:hover .say { border-color: var(--cream); }

/* THE mark — one per screen, always the same place */
.wa-float { position: fixed; right: clamp(1.1rem, 3vw, 2.4rem); bottom: clamp(1.1rem, 3vw, 2.4rem); z-index: 85; width: 3.6rem; height: 3.6rem; box-shadow: 0 14px 34px rgba(20,19,17,0.28); }
.wa-float:hover { transform: scale(1.06); box-shadow: 0 18px 40px rgba(20,19,17,0.34); }

/* masthead: Back (not on home) + Menu */
.mast-back { font-size: 0.74rem; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: inherit; transition: color 0.3s; }
.mast-back:hover { color: var(--mute); }
.masthead.is-home .mast-back { display: none; }
.menu-btn { font-size: 0.74rem; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: inherit; padding: 0.4em 0; border-bottom: 1px solid currentColor; transition: color 0.3s; }
.menu-btn:hover { color: var(--mute); }

/* the menu — the blind drops to ink: five words, the register alive, the green mark the only action */
.menu {
  position: fixed; inset: 0; z-index: 80; background: var(--ink); color: var(--cream);
  overflow-y: auto; visibility: hidden; pointer-events: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.7s cubic-bezier(0.77, 0, 0.175, 1), visibility 0s linear 0.7s;
}
.menu.open { visibility: visible; pointer-events: auto; clip-path: inset(0 0 0 0); transition: clip-path 0.7s cubic-bezier(0.77, 0, 0.175, 1), visibility 0s; }
.menu-inner { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; padding: calc(var(--mast-h) + 1rem) var(--pad) 3rem; max-width: 1400px; margin: 0 auto; }
.menu-main { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: clamp(2rem, 6vw, 8rem); align-items: end; }

/* every entry rises into place, staggered by --i */
.menu .menu-list a, .menu .menu-side, .menu .menu-foot { opacity: 0; transform: translateY(22px); transition: opacity 0.6s ease, transform 0.7s cubic-bezier(0.16,1,0.3,1); transition-delay: 0s; }
.menu.open .menu-list a, .menu.open .menu-side, .menu.open .menu-foot { opacity: 1; transform: none; transition-delay: calc(0.28s + var(--i, 0) * 0.06s); }

.menu-list { display: flex; flex-direction: column; }
.menu-list a {
  font-family: var(--serif);
  font-size: clamp(2.2rem, 7.2vh, 4.4rem);
  line-height: 1.14;
  letter-spacing: -0.02em;
  color: var(--cream);
  padding: 0.12em 0;
  align-self: flex-start;
  transition: color var(--dur-quick) ease, transform 0.45s var(--ease-settle);
}
.menu-list a:hover {
  color: #a9a6a0;
  font-style: italic;
  font-variation-settings: "opsz" 144, "SOFT" 60, "WONK" 1;
  transform: translateX(0.18em);
}
.menu-list:hover a:not(:hover) { color: rgba(244,241,235,0.45); }

/* the register, alive, on the right — ink setting */
.menu-side { display: flex; flex-direction: column; gap: 1.2rem; padding-bottom: 0.6rem; }
.menu-side > .small-caps { color: rgba(244,241,235,0.55); }
.menu-live { position: relative; height: 5em; }
.menu-live .ml-item { position: absolute; inset: 0 auto auto 0; font-family: var(--serif); font-size: clamp(1.15rem, 1.7vw, 1.5rem); line-height: 1.35; color: var(--cream); opacity: 0; transform: translateY(10px); transition: opacity 0.7s ease, transform 0.7s var(--ease-settle); display: block; }
.menu-live .ml-item.is-on { opacity: 1; transform: none; }
.menu-live .ml-item em { display: block; font-style: normal; font-family: var(--sans); font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(244,241,235,0.55); font-weight: 500; margin-bottom: 0.35em; }
.menu-live .ml-item i { display: block; font-style: normal; font-family: var(--sans); font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(244,241,235,0.4); font-weight: 500; margin-top: 0.4em; }

.menu-foot { margin-top: clamp(1.6rem, 4vh, 3rem); display: flex; flex-wrap: wrap; align-items: baseline; gap: 1rem 2.4rem; }
.menu-foot .small-caps { color: rgba(244,241,235,0.55); }
.menu-foot .link { color: var(--cream); text-decoration-color: rgba(244,241,235,0.4); }
.menu-foot .link:hover { text-decoration-color: var(--cream); }

/* (the one action stays present over the menu — z-index set on the base rule below) */
/* masthead reads cream over the open menu */
.masthead.on-ink, .masthead.on-ink.scrolled { background: transparent; backdrop-filter: none; color: var(--cream); }
.masthead.on-ink .wordmark small { color: rgba(244,241,235,0.66); }

/* the Menu word turns over into Close */
.menu-btn { position: relative; overflow: hidden; height: 1.6em; min-width: 3.6em; text-align: left; }
.menu-btn .w { display: block; transition: transform 0.45s cubic-bezier(0.16,1,0.3,1); }
.menu-btn .w + .w { position: absolute; left: 0; top: 100%; }
.menu-btn.open .w { transform: translateY(-100%); }

/* ---------- rhythm ---------- */
section { padding: clamp(5rem, 11vw, 10rem) 0; }
.deep { background: var(--cream-deep); }
.paper { background: var(--paper); }

/* ============================================================
   MASTHEAD — wordmark · telephone glyph · WhatsApp mark. No menu.
   ============================================================ */
.masthead { position: fixed; inset: 0 0 auto 0; z-index: 90; transition: background 0.4s ease, color 0.4s ease; }
.masthead.scrolled { background: rgba(244, 241, 235, 0.92); backdrop-filter: blur(14px); color: var(--ink); }
.masthead.over-photo:not(.scrolled) { color: var(--cream); }
.masthead-inner { height: var(--mast-h); display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.masthead .wordmark { flex-shrink: 1; min-width: 0; }
.masthead .mast-actions { flex-shrink: 0; }
.wordmark { font-family: var(--serif); font-size: 1.15rem; letter-spacing: 0.02em; line-height: 1; }
.wordmark small { display: block; font-family: var(--sans); font-size: 0.62rem; letter-spacing: 0.26em; text-transform: uppercase; color: var(--mute); margin-top: 0.5em; font-weight: 500; }
.masthead.over-photo:not(.scrolled) .wordmark small { color: rgba(244,241,235,0.72); }
.mast-actions { display: flex; align-items: center; gap: clamp(1.4rem, 3vw, 2.8rem); }

/* ============================================================
   HOME — the statement
   ============================================================ */
/* the fold gives ~3.5rem to the feed band's dark crest — the scroll cue is the deal flow itself */
.statement { min-height: calc(100svh - 3.5rem); display: flex; align-items: center; padding-top: var(--mast-h); }
/* the statement runs the full width of the screen — room to breathe */
.statement .statement-inner { width: 100%; }
.statement .t-hero { max-width: none; text-wrap: balance; }
.statement .lede { margin-top: 2rem; }
.statement .act-row { margin-top: 2.4rem; }

/* "Central London" — silver italic */
.t-hero em.silver { color: #9a9a97; }

/* "below-market-value" — one glint as the page arrives, then stillness */
.shimmer {
  white-space: nowrap;
  background: linear-gradient(100deg, var(--ink) 0%, var(--ink) 40%, #7d7a72 50%, var(--ink) 60%, var(--ink) 100%);
  background-size: 260% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: shimmer 3.6s ease-in-out 0.6s 1 both;
}
.shimmer.done { background: none; -webkit-text-fill-color: var(--ink); color: var(--ink); animation: none; }
@keyframes shimmer { 0% { background-position: 120% 0; } 100% { background-position: -140% 0; } }
@media (prefers-reduced-motion: reduce) { .shimmer { animation: none; -webkit-text-fill-color: var(--ink); color: var(--ink); background: none; } }
.assurance { margin-top: 2.4rem; display: flex; flex-wrap: wrap; gap: 0.6rem 2.2rem; }
.assurance span { font-size: 0.74rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--mute); font-weight: 500; }
/* off-screen animations hold still until scrolled into view */
.anim-paused, .anim-paused img { animation-play-state: paused !important; }

/* entrance choreography — once per session, on the home statement; then total stillness */
@media (prefers-reduced-motion: no-preference) {
  body.choreo .statement-inner > * {
    opacity: 0;
    animation: rise 1.05s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  }
  body.choreo .statement-inner > :nth-child(1) { animation-delay: 0.12s; }
  body.choreo .statement-inner > :nth-child(2) { animation-delay: 0.34s; }
  body.choreo .statement-inner > :nth-child(3) { animation-delay: 0.52s; }
  .wa-float.float-in { opacity: 0; animation: rise 0.7s ease 1.3s forwards; }
}
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ============================================================
   FEED
   ============================================================ */
.feed { display: block; background: var(--ink); color: var(--cream); overflow: hidden; padding: 1.5rem 0; position: relative; max-width: 100vw; }
.feed::before, .feed::after { content: ""; position: absolute; top: 0; bottom: 0; width: clamp(3rem, 8vw, 9rem); z-index: 2; pointer-events: none; }
.feed::before { left: 0; background: linear-gradient(to right, var(--ink), transparent); }
.feed::after { right: 0; background: linear-gradient(to left, var(--ink), transparent); }
.feed-track { display: flex; width: max-content; animation: feedMove 80s linear infinite; will-change: transform; }
@keyframes feedMove { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.feed-set { display: flex; align-items: baseline; }
.feed-item { white-space: nowrap; font-family: var(--serif); font-size: 1.15rem; padding-right: 4.5rem; }
.feed-item .pc { font-family: var(--sans); font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(244,241,235,0.62); margin-right: 1.1em; }

/* ============================================================
   THE DECK — one opportunity, one screen
   ============================================================ */
.deck { display: block; }
.slide {
  position: relative; min-height: 100svh; display: flex; align-items: flex-end;
  color: var(--cream); background: var(--ink); overflow: hidden;
  scroll-snap-align: start;
}

/* ---- six beats: information arrives in the order a dealmaker speaks it ---- */
@media (prefers-reduced-motion: no-preference) {
  .slide .beat { opacity: 0; transform: translateY(16px); transition: opacity 0.8s var(--ease-settle), transform 0.8s var(--ease-settle); }
  .slide.in-view .beat { opacity: 1; transform: none; transition-delay: calc(0.1s + (var(--b) - 1) * 0.28s); }
  /* the held beat before the payoff */
  .slide.in-view .saving.beat { transition-delay: calc(0.1s + (var(--b) - 1) * 0.28s + 0.45s); }
  .slide.in-view .act-row.beat { transition-delay: calc(0.1s + (var(--b) - 1) * 0.28s + 0.45s); }
  /* the market price is crossed out before your eyes */
  .slide .strike { background-image: linear-gradient(currentColor, currentColor); background-repeat: no-repeat; background-size: 0% 1px; background-position: 0 55%; transition: background-size 0.6s ease; }
  .slide.in-view .strike { background-size: 100% 1px; transition-delay: calc(0.1s + 3 * 0.28s + 0.4s); }
}
.slide .circ { color: rgba(244,241,235,0.66); margin-top: 0.9rem; }
/* the sourced evidence line — quiet, checkable, never louder than the figure */
.slide .evid { margin-top: 1.4rem; max-width: 34em; font-size: 0.86rem; line-height: 1.7; color: rgba(244,241,235,0.66); }
.evid { color: var(--mute); font-size: 0.92rem; line-height: 1.7; }
.slide .circ + .terms { margin-top: 1.2rem; }
.slide .terms + .circ { margin-top: 1rem; }
.slide .strike { color: rgba(244,241,235,0.62); }
@media (prefers-reduced-motion: reduce) {
  .slide .strike { text-decoration: line-through; text-decoration-thickness: 1px; }
}

/* under offer — the saving receding, truthfully */
.slide.uo .saving { opacity: 0.5; }
@media (prefers-reduced-motion: no-preference) {
  .slide.uo.in-view .saving.beat { opacity: 0.5; }
}
.slide .bg { position: absolute; inset: 0; }
.slide .bg img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.78) brightness(0.86); animation: drift 44s ease-in-out infinite alternate; }
.slide:nth-child(even) .bg img { animation-duration: 52s; animation-direction: alternate-reverse; }
@keyframes drift { from { transform: scale(1.02) translate(0,0); } to { transform: scale(1.09) translate(-1.4%, 1%); } }
/* two veils: a bottom-weighted wash for legibility, and a left-side wash so the type always sits on a quiet field */
.slide .veil { position: absolute; inset: 0; background: linear-gradient(to top, rgba(20,19,17,0.92) 0%, rgba(20,19,17,0.72) 30%, rgba(20,19,17,0.28) 58%, rgba(20,19,17,0.18) 100%); }
.slide .veil::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(20,19,17,0.62) 0%, rgba(20,19,17,0.30) 42%, transparent 70%); }
.slide .body { position: relative; z-index: 2; width: 100%; padding-top: calc(var(--mast-h) + 3rem); padding-bottom: clamp(3rem, 7vh, 6rem); }
.slide .pc { display: block; font-size: 0.74rem; letter-spacing: 0.24em; text-transform: uppercase; color: rgba(244,241,235,0.72); font-weight: 500; }
.slide .pc i { font-style: normal; margin-left: 1.4em; color: rgba(244,241,235,0.5); }
.slide .what { margin-top: 1.1rem; font-size: clamp(1.7rem, 3.4vw, 3rem); max-width: 14em; text-wrap: balance; }
.slide .terms { margin-top: 1.6rem; font-family: var(--serif); font-size: clamp(1.05rem, 1.8vw, 1.5rem); line-height: 1.45; max-width: min(24em, 100%); color: rgba(244,241,235,0.92); overflow-wrap: anywhere; }
.slide .terms s { color: rgba(244,241,235,0.62); text-decoration-thickness: 1px; text-decoration-color: rgba(244,241,235,0.9); }
.slide .saving { display: block; margin-top: 1.6rem; font-family: var(--serif); font-size: clamp(3.2rem, 8vw, 7.4rem); line-height: 0.95; letter-spacing: -0.03em; }
.slide .saving small { display: block; font-family: var(--sans); font-size: 0.74rem; letter-spacing: 0.2em; text-transform: uppercase; color: rgba(244,241,235,0.68); margin-top: 0.9rem; font-weight: 500; }
.slide .act-row { margin-top: 2.2rem; }
.slide .act { background: var(--cream); color: var(--ink); }
.slide .act:hover { background: #fff; }
.slide .act.quiet { background: transparent; color: var(--cream); }
.slide .act.quiet:hover { color: rgba(244,241,235,0.7); }
.slide .num { position: absolute; top: calc(var(--mast-h) + 1.4rem); right: var(--pad); z-index: 2; font-family: var(--serif); font-size: 0.95rem; color: rgba(244,241,235,0.55); letter-spacing: 0.08em; }

/* the register — a ledger inscribing itself */
.slide.register { background: var(--cream-deep); color: var(--ink); align-items: center; }
.slide.register .body { padding-top: calc(var(--mast-h) + 2rem); padding-bottom: 4rem; }
.slide.register .entries { max-width: 52rem; margin-top: 2.4rem; }
.slide.register .entry {
  position: relative;
  display: grid; grid-template-columns: 4.6rem minmax(0, 1fr) auto;
  gap: 0.2rem 1.6rem; align-items: baseline;
  padding: 1.5rem 0;
}
.slide.register .entry::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: rgba(20,19,17,0.16); transform-origin: left center;
}
@media (prefers-reduced-motion: no-preference) {
  .slide.register .entry::before { transform: scaleX(0); transition: transform 0.9s var(--ease-settle); transition-delay: calc(var(--i, 0) * 0.08s); }
  .slide.register.in-view .entry::before { transform: scaleX(1); }
}
.slide.register .entry .rn { font-family: var(--serif); font-size: 1.05rem; color: var(--mute); }
.slide.register .entry .pc { color: var(--mute); }
.slide.register .entry .line { margin-top: 0.3rem; font-family: var(--serif); font-size: clamp(1.05rem, 1.5vw, 1.3rem); line-height: 1.5; color: var(--ink-soft); }
.slide.register .entry .line .strike-s { color: var(--mute); text-decoration: line-through; text-decoration-thickness: 1px; }
.slide.register .entry .line strong { color: var(--ink); font-weight: 400; }
.slide.register .entry .r-act { display: inline-block; margin-top: 0.5rem; color: var(--mute); transition: color 0.3s; }
.slide.register .entry:hover .r-act { color: var(--ink); }
.slide.register .entry .rs { font-family: var(--serif); font-size: clamp(1.2rem, 1.8vw, 1.6rem); font-feature-settings: "tnum"; text-align: right; }
.slide.register .entry .rs small { display: block; font-family: var(--sans); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--mute); font-weight: 500; margin-top: 0.3em; }
.slide.register .reg-foot { margin-top: 1.6rem; }
.slide.register .edition-line { margin-top: 0.6rem; color: var(--faint); }
.slide.register .act-row { margin-top: 2.2rem; }
.slide.register .act { background: var(--ink); color: var(--cream); }
.slide.register .act.quiet { background: transparent; color: var(--ink); }
.movements { margin-top: 1rem; display: flex; flex-direction: column; gap: 0.3rem; }
.movements .mv-line { color: var(--faint); }

/* the closing screen — end in ink */
.slide.close { background: var(--ink); color: var(--cream); align-items: center; }
.slide.close .body { padding-top: calc(var(--mast-h) + 2rem); padding-bottom: 5rem; }
.slide.close .small-caps { color: rgba(244,241,235,0.6); }
.slide.close .lede { color: rgba(244,241,235,0.78); }
.slide.close .link { color: var(--cream); text-decoration-color: rgba(244,241,235,0.4); }
.slide.close .link:hover { text-decoration-color: var(--cream); }

/* inner-page close band, same ink bookend */
.close-band.ink { background: var(--ink); color: var(--cream); padding: clamp(5rem, 11vw, 10rem) 0; }
.close-band.ink .small-caps { color: rgba(244,241,235,0.6); }
.close-band.ink .lede { color: rgba(244,241,235,0.78); }
.close-band.ink .link { color: var(--cream); text-decoration-color: rgba(244,241,235,0.4); }
.close-band.ink .wa-speak { margin-top: 2rem; display: inline-flex; }

/* ============================================================
   INNER PAGES — one photograph, one passage, the figure, the mark
   ============================================================ */
.photo-open { position: relative; height: 82svh; min-height: 520px; overflow: hidden; background: var(--ink); }
.photo-open img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.85); animation: drift 44s ease-in-out infinite alternate; }
.photo-open::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(20,19,17,0.28), transparent 40%); }
.after-photo { padding-top: clamp(3rem, 6vw, 5rem); }
.crumbs { display: flex; flex-wrap: wrap; gap: 0.6em; margin-bottom: 1.6rem; }
.crumbs, .crumbs a { font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--mute); font-weight: 500; }
.crumbs a:hover { color: var(--ink); }
.terms-large { font-family: var(--serif); font-size: clamp(1.4rem, 2.6vw, 2.2rem); line-height: 1.4; max-width: 24em; color: var(--ink-soft); }
.terms-large s { color: var(--mute); text-decoration-thickness: 1px; }
.terms-large strong { color: var(--ink); font-weight: 400; }
.saving-large { display: block; margin-top: 1.6rem; font-family: var(--serif); font-size: clamp(3rem, 6vw, 5.4rem); line-height: 1; letter-spacing: -0.025em; }
.saving-large small { display: block; font-family: var(--sans); font-size: 0.74rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--mute); margin-top: 0.8rem; font-weight: 500; }

.two { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(1.5rem, 4vw, 5rem); }
.two > :first-child { grid-column: 1 / span 6; }
.two > :last-child { grid-column: 8 / span 5; }
.passage { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(1.5rem, 4vw, 5rem); align-items: center; }
.passage .p-copy { grid-column: 1 / span 6; }
.passage .p-photo { grid-column: 8 / span 5; overflow: hidden; }
.passage .p-photo img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; filter: saturate(0.85); animation: drift 40s ease-in-out infinite alternate; }
.passage figcaption { margin-top: 0.9rem; }

.pcs { display: flex; flex-direction: column; }
.pcs a { display: grid; grid-template-columns: minmax(6rem, 10rem) 1fr; gap: 2rem; align-items: baseline; padding: 1.4rem 0; transition: color 0.3s; }
.pcs a:hover { color: var(--mute); }
.pcs a .code { font-family: var(--serif); font-size: clamp(2rem, 3.6vw, 3rem); }
.pcs a .name { font-family: var(--serif); font-size: clamp(1.15rem, 1.7vw, 1.4rem); color: var(--ink-soft); }
.pcs a .name span { display: block; font-family: var(--sans); font-size: 0.95rem; color: var(--mute); margin-top: 0.3em; max-width: 36em; }

.faq details { padding: 1.4rem 0; }
.faq details + details { border-top: 1px solid rgba(20,19,17,0.10); }
.faq summary { list-style: none; cursor: pointer; font-family: var(--serif); font-size: clamp(1.15rem, 1.7vw, 1.4rem); display: flex; justify-content: space-between; gap: 2rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--sans); font-weight: 300; color: var(--mute); transition: transform 0.3s; }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .a { margin-top: 1rem; max-width: var(--measure); color: var(--ink-soft); line-height: 1.7; }

.form { display: grid; grid-template-columns: 1fr 1fr; gap: 2.2rem 2.6rem; }
.form .full { grid-column: 1 / -1; }
.field label { display: block; font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--mute); font-weight: 500; margin-bottom: 0.4rem; }
.field input, .field select, .field textarea { width: 100%; background: transparent; border: none; border-bottom: 1px solid rgba(20,19,17,0.28); color: var(--ink); font-family: var(--serif); font-size: 1.15rem; padding: 0.5em 0; border-radius: 0; -webkit-appearance: none; appearance: none; transition: border-color 0.3s; }
.field select { cursor: pointer; }
.field select option { color: var(--ink); background: #fff; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-bottom-color: var(--ink); }
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.form-note { font-size: 0.85rem; color: var(--mute); max-width: 32em; }
.capture { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(1.5rem, 4vw, 5rem); align-items: start; }
.capture .c-copy { grid-column: 1 / span 5; }
.capture .c-form { grid-column: 7 / span 6; }

.comps { width: 100%; border-collapse: collapse; max-width: 60rem; }
.comps th { text-align: left; font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--mute); font-weight: 500; padding: 0 1rem 0.8rem 0; }
.comps td { font-family: var(--serif); font-size: 1.05rem; padding: 0.9rem 1rem 0.9rem 0; color: var(--ink-soft); }
.comps tr + tr td { border-top: 1px solid rgba(20,19,17,0.10); }
.comps th.num, .comps td.num { text-align: right; padding-right: 0; }
.comps .placeholder td { font-style: italic; color: var(--mute); }
.source { font-size: 0.85rem; color: var(--mute); margin-top: 1rem; }

.gallery { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1.2rem; }
.gallery figure { overflow: hidden; }
.gallery img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.85); animation: drift 40s ease-in-out infinite alternate; }
.gallery figure:nth-child(even) img { animation-duration: 46s; animation-direction: alternate-reverse; }
.gallery .a { grid-column: 1 / span 8; aspect-ratio: 16/10; }
.gallery .b { grid-column: 9 / span 4; aspect-ratio: 4/5; }
.gallery .c { grid-column: 1 / span 4; aspect-ratio: 4/5; }
.gallery .d { grid-column: 5 / span 8; aspect-ratio: 16/10; }

/* closing band on inner pages */
.close-band .wa-speak { margin-top: 2.2rem; }

/* ============================================================
   FOOTER — a signature
   ============================================================ */
.foot { padding: clamp(4rem, 8vw, 7rem) 0 8rem; }
.foot-inner { display: flex; flex-direction: column; gap: 2rem; }
.foot-links { display: flex; flex-wrap: wrap; gap: 0.6rem 2.2rem; }
.foot-links a { font-size: 0.74rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--mute); font-weight: 500; }
.foot-links a:hover { color: var(--ink); }
.foot-fine { font-size: 0.8rem; color: var(--faint); max-width: 56em; line-height: 1.7; }

/* report contents + file lines */
.toc .toc-line { display: grid; grid-template-columns: 2.2rem 1fr; align-items: baseline; gap: 1rem; font-family: var(--serif); font-size: clamp(1.05rem, 1.5vw, 1.3rem); color: var(--ink-soft); padding: 0.45em 0; }
.toc .toc-line + .toc-line { border-top: 1px solid rgba(20,19,17,0.08); }
.file-line { margin-bottom: 1.2rem; color: var(--faint); }

/* the deck and files print as dated private-circulation documents */
@media print {
  body { background: #fff; color: #000; }
  .masthead .mast-actions, .menu, .wa-float, .sticky, .feed, .act, .wa-speak, .scroll-hint { display: none !important; }
  .slide { min-height: 0; color: #000; background: #fff; page-break-inside: avoid; padding: 1.5cm 0; }
  .slide .bg, .slide .veil, .slide .num { display: none; }
  .slide .beat { opacity: 1 !important; transform: none !important; }
  .slide .pc, .slide .circ { color: #444; }
  .slide .terms, .slide .saving { color: #000; }
  .slide.close, .close-band.ink { background: #fff; color: #000; }
  .foot-fine { color: #444; }
}

/* mobile sticky — Call · Speak to an Asset Manager · Enquire (text; the float carries the mark) */
.sticky { position: fixed; inset: auto 0 0 0; z-index: 65; display: none; grid-template-columns: 1fr 2fr 1fr; align-items: stretch; background: rgba(244,241,235,0.97); backdrop-filter: blur(10px); border-top: 1px solid rgba(20,19,17,0.10); }
.sticky a { padding: 1.05rem 0.4rem; text-align: center; font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; display: flex; align-items: center; justify-content: center; }
.sticky a.primary { background: var(--ink); color: var(--cream); }

/* ============================================================
   MOTION
   ============================================================ */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity 1.1s cubic-bezier(0.16,1,0.3,1), transform 1.1s cubic-bezier(0.16,1,0.3,1); }
.reveal.visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } img, .feed-track { animation: none !important; } }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1100px) {
  .two > :first-child, .two > :last-child { grid-column: 1 / -1; }
  .passage .p-copy, .passage .p-photo { grid-column: 1 / -1; }
  .passage .p-photo { order: -1; }
  .passage .p-photo img { aspect-ratio: 16 / 10; }
  .capture .c-copy, .capture .c-form { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  body { font-size: 16px; }
  :root { --mast-h: 76px; }
  .sticky { display: grid; }
  .wa-float { bottom: 4.6rem; width: 3.2rem; height: 3.2rem; }
  .wordmark { font-size: 1rem; }
  .wordmark small { font-size: 0.55rem; letter-spacing: 0.2em; }
  .mast-actions { gap: 1.2rem; }
  .slide .what { font-size: clamp(1.5rem, 7vw, 2.2rem); }
  .slide .saving { font-size: clamp(2.6rem, 13vw, 4rem); }
  .wa-speak .say { font-size: 1.1rem; }
  .menu-main { grid-template-columns: 1fr; gap: 2rem; }
  .menu-list a { grid-template-columns: 1.8em 1fr; grid-template-areas: "n t" "n s"; row-gap: 0.1rem; padding: 0.5em 0; white-space: normal; }
  .menu-list a .mn { grid-area: n; }
  .menu-list a .mt { grid-area: t; font-size: clamp(1.5rem, 5.2vh, 2.2rem); }
  .menu-list a .ms { grid-area: s; margin-left: 0; }
  .menu-side { display: none; }
  .form { grid-template-columns: 1fr; }
  .gallery .a, .gallery .b, .gallery .c, .gallery .d { grid-column: 1 / -1; aspect-ratio: 16/10; }
  .pcs a { grid-template-columns: 1fr; gap: 0.4rem; }
  .photo-open { height: 60svh; min-height: 380px; }
  .foot { padding-bottom: 9.5rem; }
  .slide .num { top: calc(var(--mast-h) + 0.6rem); }
  .slide .body { padding-bottom: 6.5rem; }
  .slide.close .body, .slide.register .body { padding-bottom: 7rem; }
}

/* ============================================================
   v8.0 - DEAL SLIDES: photograph right, written terms left.
   No full-bleed image, no numerals. Ink on cream.
   ============================================================ */
.slide.deal {
  display: grid; grid-template-columns: 1.04fr 1fr; align-items: stretch;
  background: var(--cream); color: var(--ink); overflow: hidden;
  /* both columns clear the masthead, so the wordmark and the controls always sit
     on cream and never fight the photograph for legibility */
  padding-top: var(--mast-h);
}
.slide.deal .s-text {
  display: flex; align-items: center; min-width: 0;
  padding: clamp(2rem, 5vh, 3.6rem) clamp(1.6rem, 3.4vw, 3.6rem)
           clamp(2.6rem, 6vh, 4.6rem) var(--pad);
}
.slide.deal .s-inner { width: 100%; max-width: 34rem; }
.slide.deal .s-img { position: relative; margin: 0; overflow: hidden; background: var(--cream-deep); }
.slide.deal .s-img img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: saturate(0.92); animation: drift 46s ease-in-out infinite alternate;
}
.slide.deal:nth-child(even) .s-img img { animation-duration: 54s; animation-direction: alternate-reverse; }

/* the typographic panel used when an asset has no photography yet */
.slide.deal .s-plate {
  display: flex; align-items: center; justify-content: center;
  background: var(--ink); color: var(--cream); padding: clamp(2rem, 4vw, 4.5rem);
}
.slide.deal .s-plate .plate { max-width: 24em; }
.slide.deal .s-plate .plate .small-caps { display: block; color: rgba(244,241,235,0.55); margin-bottom: 1.4rem; }
.slide.deal .s-plate .plate p {
  font-family: var(--serif); font-size: clamp(1.05rem, 1.5vw, 1.42rem);
  line-height: 1.55; color: rgba(244,241,235,0.9);
}

/* ---- ink-on-cream type ---- */
.slide.deal .pc { color: var(--mute); }
.slide.deal .pc i { color: var(--faint); }
.slide.deal .what { color: var(--ink); margin-top: 1rem; font-size: clamp(1.5rem, 2.5vw, 2.35rem); max-width: 15em; }
.slide.deal .circ { color: var(--mute); }
.slide.deal .terms { color: var(--ink-soft); margin-top: 1.4rem; font-size: clamp(1.02rem, 1.35vw, 1.28rem); }
.slide.deal .strike { color: var(--mute); }
.slide.deal .saving { color: var(--ink); margin-top: 1.4rem; font-size: clamp(2.6rem, 5.2vw, 4.6rem); }
.slide.deal .saving small { color: var(--mute); margin-top: 0.7rem; font-size: 0.68rem; }
.slide.deal .evid { color: var(--mute); margin-top: 1.3rem; max-width: 32em; font-size: 0.9rem; }
.slide.deal .act-row { margin-top: 1.9rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem; }
.slide.deal .act { background: var(--ink); color: var(--cream); }
.slide.deal .act:hover { background: var(--ink-soft); }
.slide.deal .act.quiet { background: transparent; color: var(--ink); }
.slide.deal .act.quiet:hover { color: var(--mute); }

/* ---- mobile: photograph above, terms beneath ---- */
@media (max-width: 880px) {
  .slide.deal { grid-template-columns: 1fr; grid-template-rows: 38svh auto; min-height: 100svh; padding-top: var(--mast-h); }
  .slide.deal .s-img { order: -1; }
  .slide.deal .s-text { padding: 2.4rem var(--pad) 3.4rem; }
  .slide.deal .s-inner { max-width: none; }
  .slide.deal .s-plate { padding: 2rem var(--pad); }
}

/* ==== v9.0 - the named plate that stands in for photography ==== */
.slide.deal .s-plate .plate { max-width: 22em; }
.slide.deal .s-plate .plate .small-caps { display: block; color: rgba(244,241,235,0.5); margin-bottom: 2rem; }
.slide.deal .s-plate .plate .pl-name {
  font-family: var(--serif); font-size: clamp(1.7rem, 2.6vw, 2.6rem); line-height: 1.12;
  color: var(--cream); letter-spacing: -0.01em;
}
.slide.deal .s-plate .plate .pl-where {
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(244,241,235,0.55); margin-top: 1.1rem; font-weight: 500; line-height: 1.7;
}

/* ==== v9.1 - the deck alternates. Odd numbers: picture left, text right. ====
   Source order stays text-then-picture on every slide (the written terms are the
   content); only the grid placement swaps, so nothing changes for a screen reader. */
.slide.deal.flip { grid-template-columns: 1fr 1.04fr; }
.slide.deal.flip .s-img  { grid-column: 1; grid-row: 1; }
.slide.deal.flip .s-text {
  grid-column: 2; grid-row: 1;
  padding-left: clamp(1.6rem, 3.4vw, 3.6rem);
  padding-right: var(--pad);
}

@media (max-width: 880px) {
  /* stacked on mobile: picture on top for every slide, alternation switched off */
  .slide.deal.flip { grid-template-columns: 1fr; }
  .slide.deal.flip .s-img  { grid-column: 1; grid-row: auto; }
  .slide.deal.flip .s-text { grid-column: 1; grid-row: auto;
                             padding-left: var(--pad); padding-right: var(--pad); }
}

/* ==== v9.2 - the picture is FRAMED, not bled ====
   Wayne, 22 Aug: the image box was running to the screen edge and being cut by it.
   It is now a mounted plate - hairline rule, cream mount, centred in its column and
   sized to sit against the text block rather than tower over it. */
.slide.deal .s-img {
  align-self: stretch; justify-self: stretch;
  height: min(64vh, 560px);
  /* margins mirror the text column exactly: the outer edge sits on --pad, the inner
     edge on the gutter, so frame and text share one margin down both sides */
  margin: 0 var(--pad) 0 clamp(1.6rem, 3.4vw, 3.6rem);
  padding: 0.7rem;                              /* the mount */
  background: var(--cream);
  border: 1px solid rgba(20, 19, 17, 0.18);
  overflow: visible;
}
.slide.deal.flip .s-img { margin: 0 clamp(1.6rem, 3.4vw, 3.6rem) 0 var(--pad); }
.slide.deal .s-img {
  position: relative; overflow: hidden;
}
/* The photograph is taken OUT OF FLOW so its own proportions can never drive the frame
   height - a portrait source would otherwise make its slide twice the height of the
   others. The text column sets the height; the picture is cropped to fit it. */
/* CONTAIN, never cover. Cover crops to fill the frame, which zooms into the facade and
   loses the building - the whole point is that you can see the whole of it. The cream
   mount showing above and below a wide photograph is the mount doing its job. */
.slide.deal .s-img img {
  position: absolute; inset: 0.7rem; display: block;
  width: calc(100% - 1.4rem); height: calc(100% - 1.4rem);
  object-fit: contain; object-position: center;
  animation: none;                              /* a framed photograph does not drift */
}

/* the ink plate that stands in until Wayne's building photography arrives */
.slide.deal .s-plate { display: block; background: var(--cream); }
.slide.deal .s-plate .plate {
  width: 100%; height: 100%; max-width: none;
  background: var(--ink); color: var(--cream);
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(1.6rem, 3.2vw, 3rem);
}
.slide.deal .s-plate .plate > * { max-width: 18em; }

/* the text column no longer needs to hold its own against a full-bleed photograph */
.slide.deal .s-text { padding-top: clamp(1.6rem, 4vh, 3rem); padding-bottom: clamp(1.6rem, 4vh, 3rem); }

@media (max-width: 880px) {
  .slide.deal .s-img,
  .slide.deal.flip .s-img {
    height: auto; aspect-ratio: 4 / 3;
    margin: 1.6rem var(--pad) 0;
  }
  .slide.deal { grid-template-rows: auto auto; }
}

/* ==== v9.3 - ONE CONTINUOUS PAGE ====
   Wayne, 22 Aug: the full-height slides read as page breaks. Assets now sit to their own
   height in a single flow. Do not reinstate 100svh or scroll-snap on .slide.deal. */
.slide.deal {
  min-height: 0;
  padding: clamp(2.2rem, 5vh, 4rem) 0;
  scroll-snap-align: none;
}
/* only the first asset of a deck clears the fixed masthead */
.deck > .slide.deal:first-child { padding-top: calc(var(--mast-h) + clamp(1.4rem, 4vh, 3rem)); }

.slide.deal .s-text { padding-top: 0; padding-bottom: 0; }
/* the frame matches the text column exactly - it stretches to the grid row, so its
   foot lands on the same line as the bottom of "Speak to an Asset Manager", and it
   stays matched however long a given asset's text runs. */
.slide.deal .s-img  { align-self: stretch; height: auto; min-height: min(48vh, 420px); }

/* the register and the closing screen keep their own presence, just less of it */
.slide.register, .slide.close { min-height: 0; scroll-snap-align: none;
                                padding: clamp(3rem, 8vh, 6rem) 0; }
.slide.register .body, .slide.close .body { padding-top: 0; padding-bottom: 0; }

@media (max-width: 880px) {
  .slide.deal { padding: clamp(1.8rem, 4vh, 3rem) 0; }
  .deck > .slide.deal:first-child { padding-top: calc(var(--mast-h) + 1.4rem); }
  .slide.deal .s-img { height: auto; }
}

/* ==== v10.1 - THE FRAME HUGS THE PICTURE ====
   Wayne's own images are wide (2.1:1, 2.3:1). Forcing them into a frame the height of the
   text column left them as thin strips in a sea of mount. The frame now takes its height
   from the photograph, centred against the text. Nothing is cropped and nothing is
   scaled up: the image is shown at its own proportions, capped so a tall source cannot
   run away with the layout. NEVER put object-fit: cover back on these. */
.slide.deal .s-img {
  align-self: center; justify-self: stretch;
  height: auto; min-height: 0; aspect-ratio: auto;
  display: flex; align-items: center; justify-content: center;
}
.slide.deal .s-img img {
  position: static; inset: auto; display: block;
  width: auto; height: auto;
  max-width: 100%; max-height: min(62vh, 540px);
  object-fit: contain; animation: none;
}
/* the standing plate keeps a presence of its own when a building has no photograph yet */
.slide.deal .s-plate { min-height: min(48vh, 420px); }

@media (max-width: 880px) {
  .slide.deal .s-img { height: auto; }
  .slide.deal .s-img img { max-height: 52vh; }
}

/* ==== v10.2 - EVERY FRAME IDENTICAL ====
   Wayne, 22 Aug: all frames the same size, all images the same, stretch the odd ones.
   The frame is now a fixed 16:10 at full column width, so all six are identical, and the
   photograph is stretched to fill it (object-fit: fill) rather than cropped. 16:10 is the
   geometric middle of his six sources, which keeps the stretch off any single one.
   NOT cover (that crops and zooms) and NOT contain (that leaves uneven mount). */
.slide.deal .s-img {
  align-self: center; justify-self: stretch;
  display: block; position: relative;
  /* width comes from justify-self: stretch, which already accounts for the margins.
     Setting width:100% here adds the margins ON TOP and the frame overflows its
     column and runs under the text. Do not reinstate it. */
  width: auto; height: auto; min-height: 0;
  aspect-ratio: 16 / 10;
}
.slide.deal .s-img img {
  position: absolute; inset: 0.7rem;
  width: calc(100% - 1.4rem); height: calc(100% - 1.4rem);
  max-width: none; max-height: none;
  object-fit: fill; animation: none;
}
.slide.deal .s-plate { aspect-ratio: 16 / 10; min-height: 0; }

@media (max-width: 880px) {
  .slide.deal .s-img { aspect-ratio: 16 / 10; }
  .slide.deal .s-img img { max-height: none; }
}

/* ==== v10.3 - the figure carries the claim ====
   Wayne, 22 Aug: not "one billion pounds" spelled out - the numeral, larger, and set in
   the headline's serif rather than the body sans. The words "property" and "real estate"
   are deliberately absent from this line. */
.lede .bn {
  font-family: var(--serif);
  font-size: 1.85em;
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--ink);
  vertical-align: -0.06em;
  padding: 0 0.04em;
}

/* ==== v11.0 - the legal pages: long-form, readable, still the house voice ==== */
.prose.legal h2 {
  font-family: var(--serif); font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 400; color: var(--ink); margin: 2.8rem 0 0.9rem;
  letter-spacing: -0.01em;
}
.prose.legal h2:first-child { margin-top: 0; }
.prose.legal ul {
  list-style: none; padding: 0; margin: 0 0 1.25em;
  max-width: var(--measure);
}
.prose.legal li {
  position: relative; padding-left: 1.5em; margin-bottom: 0.7em;
  color: var(--ink-soft); font-size: 1.05rem; line-height: 1.7;
}
.prose.legal li::before {
  content: ""; position: absolute; left: 0; top: 0.82em;
  width: 0.6em; height: 1px; background: var(--faint);
}
.prose.legal li strong { font-weight: 500; color: var(--ink); }

/* ==== v11.2 - an h1 the page needs but the design does not show ====
   opportunities.html opens straight into the deck, so it had no h1 at all. This gives
   crawlers and screen readers the heading without putting anything on screen. */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ==== v12.0 - comparable rows: unit type, amount below comps, per cent below comps ==== */
.slide.deal .comps { margin-top: 1.6rem; display: flex; flex-direction: column; gap: 1.7rem; }
.slide.deal .comp-row {
  display: grid; grid-template-columns: minmax(0, 8.4em) 1fr 1fr;
  align-items: start; column-gap: 1.2rem;
}
.slide.deal .comp-row.nounit { grid-template-columns: 1fr 1fr; }
.slide.deal .comp-unit {
  font-family: var(--serif); font-size: clamp(0.95rem, 1.3vw, 1.18rem);
  color: var(--ink-soft); line-height: 1.3; padding-top: 0.5em;
}
.slide.deal .comp-fig {
  font-family: var(--serif); font-size: clamp(1.45rem, 2.5vw, 2.24rem);
  line-height: 1.05; letter-spacing: -0.025em; color: var(--ink);
  font-feature-settings: "tnum"; white-space: nowrap;
}
.slide.deal .comp-fig small {
  display: block; margin-top: 0.7rem; white-space: normal;
  font-family: var(--sans); font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.19em; text-transform: uppercase; color: var(--mute);
  line-height: 1.55;
}
@media (max-width: 880px) {
  .slide.deal .comp-row { grid-template-columns: 1fr 1fr; row-gap: 0.4rem; }
  .slide.deal .comp-unit { grid-column: 1 / -1; padding-top: 0; }
}

/* ==== v13.0 - the register carries the same two figures the deck does ==== */
.slide.register .entry .rs { text-align: right; line-height: 1.1; }
.slide.register .entry .rs b {
  display: block; margin-top: 0.9rem; font-weight: 400;
  font-family: var(--serif); font-size: clamp(1.2rem, 1.8vw, 1.6rem);
  font-feature-settings: "tnum"; color: var(--ink);
}
.slide.register .entry .rs small { margin-top: 0.3em; }

/* ============================================================================
   v16.0 - THE ELEVATION
   ============================================================================ */

/* ---- 1. a third tone -------------------------------------------------------
   Not gold. A deep, desaturated green that reads as a dark neutral with warmth.
   Used only for hovers, the register's numerals and the rule beneath a CTA -
   never as decoration, never as a fill. */
:root {
  --accent: #2F3B35;
  --accent-soft: rgba(47, 59, 53, 0.42);
}

/* ---- 2. paper -------------------------------------------------------------
   The cream was a hex value. A 180px noise plate at low alpha makes it read as
   stock. It sits under everything, so it shows on cream and is covered by the
   ink surfaces, which is exactly where you would and would not want it. */
body, .slide.register, .deep, .capture {
  background-image: url("../img/grain.png");
  background-repeat: repeat;
  background-size: 180px 180px;
}
/* the ink surfaces keep their own flat black - grain on ink reads as noise, not paper */
.slide.close, .menu, .s-plate, .feed { background-image: none; }

/* ---- 3. Fraunces, properly ------------------------------------------------
   The face has four axes and the site was driving one. WONK gives the angled,
   slightly eccentric terminals that make Fraunces distinctive rather than
   generic; opsz is meant to track the rendering size. Display sizes get WONK
   and a high optical size; running text gets neither, because at 17px the
   wonky terminals turn to mush. */
html { font-optical-sizing: auto; }

.t-hero, .t-1, .t-2,
.slide.deal .what,
.slide.deal .comp-fig,
.slide.deal .saving,
.lede .bn,
.s-plate .pl-name,
.prose.legal h2 {
  font-variation-settings: "opsz" 144, "WONK" 1, "SOFT" 0;
}
.slide.deal .terms,
.wa-speak .say,
.slide.register .entry .line {
  font-variation-settings: "opsz" 24, "WONK" 0, "SOFT" 0;
}

/* ---- 4. hierarchy in the numbers -------------------------------------------
   The pound figure is the claim; the percentage is the annotation that proves
   it. They were the same size, so the eye had to choose. Now it does not. */
.slide.deal .comp-row {
  grid-template-columns: minmax(0, 8.4em) minmax(0, auto) minmax(0, auto);
  justify-content: start; column-gap: clamp(1.1rem, 2.2vw, 2.4rem);
}
.slide.deal .comp-row.nounit {
  grid-template-columns: minmax(0, auto) minmax(0, auto);
}
.slide.deal .comp-fig.pct {
  font-size: clamp(1.0rem, 1.55vw, 1.42rem);
  color: var(--ink-soft);
  align-self: start; padding-top: 0.34em;
  position: relative; padding-left: clamp(1.1rem, 2.2vw, 2.4rem);
}
/* a hairline standing between the figure and its annotation */
.slide.deal .comp-fig.pct::before {
  content: ""; position: absolute; left: 0; top: 0.36em; bottom: 1.9em;
  width: 1px; background: var(--faint);
}
.slide.deal .comp-fig.pct small { color: var(--mute); }
/* the annotation must not wrap onto a second line - let the column size to the label */
.slide.deal .comp-fig small { white-space: nowrap; }
@media (max-width: 880px) { .slide.deal .comp-fig small { white-space: normal; } }

/* ---- 5. the chapter break -------------------------------------------------
   Eight alternating rows becomes metronomic by the fourth. One rule across the
   page resets the eye and tells you the register is a different kind of thing. */
.chapter {
  display: flex; align-items: center; gap: clamp(1.4rem, 3vw, 2.6rem);
  padding: clamp(3rem, 8vh, 6rem) var(--pad) clamp(1.5rem, 4vh, 3rem);
  max-width: 1400px; margin: 0 auto;
}
.chapter .ch-rule { flex: 1; height: 1px; background: var(--faint); }
.chapter .ch-word { color: var(--mute); white-space: nowrap; }

/* ---- 6. the register as a ledger ------------------------------------------
   It is the most distinctive idea on the site and it was styled like everything
   else. Ruled, inscribed, and given room. */
.slide.register .entry {
  padding-top: clamp(1.5rem, 3vh, 2.2rem);
  padding-bottom: clamp(1.5rem, 3vh, 2.2rem);
}
.slide.register .entry .rn {
  font-variation-settings: "opsz" 144, "WONK" 1;
  color: var(--accent); font-size: 1.2rem; letter-spacing: 0.02em;
}
.slide.register .entry:hover .rn { color: var(--ink); }
.slide.register .entries { border-top: 1px solid var(--faint); }
.slide.register .entry { border-bottom: 1px solid var(--faint); }
.slide.register .entry::before { background: var(--accent-soft); }

/* ---- 7. hovers pick up the third tone -------------------------------------- */
.link:hover, .act.quiet:hover,
.menu-list a:hover, .foot-links a:hover,
.slide.register .entry:hover .r-act { color: var(--accent); }
.wa-speak:hover .say { color: var(--accent); }

/* ---- 8. the masthead answers the scroll ------------------------------------ */
.masthead { --mast-scale: 1; }
.masthead.scrolled .masthead-inner { height: calc(var(--mast-h) * 0.74); }
.masthead-inner { transition: height 0.45s cubic-bezier(0.16, 1, 0.3, 1); }
.masthead .wordmark { transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1); transform-origin: left center; }
.masthead.scrolled .wordmark { transform: scale(0.88); }
.masthead.scrolled .wordmark small { opacity: 0; transition: opacity 0.3s; }

/* ---- 9. the arrival --------------------------------------------------------
   The wordmark sets first, then a hairline draws the width of the page, then
   the statement settles. Four hundred milliseconds that say what kind of firm
   this is. */
@media (prefers-reduced-motion: no-preference) {
  body.choreo .masthead .wordmark { opacity: 0; animation: rise 0.8s cubic-bezier(0.16,1,0.3,1) 0.05s forwards; }
  body.choreo .masthead::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: var(--faint); transform: scaleX(0); transform-origin: left center;
    animation: draw 1.1s cubic-bezier(0.16,1,0.3,1) 0.3s forwards;
  }
  @keyframes draw { to { transform: scaleX(1); } }
}

/* ---- 10. the WhatsApp mark -------------------------------------------------
   The shape is what identifies WhatsApp, not the green - which is why it works
   in monochrome on every phone's share sheet. At rest the mark belongs to this
   palette; on hover it fills to WhatsApp green, so the one saturated colour on
   the site appears only at the moment of intent. Moved off the corner and onto
   the page grid, because bottom-right-against-the-edge is the live-chat-bot
   position and this is not one. */
.wa-float {
  right: var(--pad); bottom: clamp(1.6rem, 4vh, 2.6rem);
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  filter: none;
}
.wa-float svg { width: 52px; height: 52px; display: block; }
.wa-float .wa-disc { fill: var(--ink); transition: fill 0.45s cubic-bezier(0.16,1,0.3,1); }
.wa-float:hover .wa-disc, .wa-float:focus-visible .wa-disc { fill: #25D366; }
.wa-float .wa-label {
  position: absolute; right: calc(100% + 0.85rem); top: 50%; transform: translateY(-50%) translateX(4px);
  white-space: nowrap; color: var(--mute); opacity: 0; pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.16,1,0.3,1);
}
.wa-float:hover .wa-label, .wa-float:focus-visible .wa-label {
  opacity: 1; transform: translateY(-50%) translateX(0);
}
@media (max-width: 880px) {
  /* the sticky bar already carries the action on mobile; the float is desktop furniture */
  .wa-float { width: 46px; height: 46px; }
  .wa-float svg { width: 46px; height: 46px; }
  .wa-float .wa-label { display: none; }
}

/* ---- 11. the photographs are already 16:10, so nothing is stretched --------- */
.slide.deal .s-img img { object-fit: cover; }

/* ==== v17.0 - the entries that carry no price ====
   Set in the serif at the weight of a figure, so the eye reads it as the answer to
   "how much" rather than as an absence. Two lines, because "Priced in conversation"
   stacked reads as a statement; on one line it reads as a label. */
.slide.register .entry .rs-talk {
  display: block; text-align: right;
  font-family: var(--serif);
  font-variation-settings: "opsz" 144, "WONK" 1;
  font-size: clamp(1.05rem, 1.5vw, 1.34rem);
  line-height: 1.18; color: var(--ink); font-style: normal;
}
.slide.register .entry .rs-talk em {
  display: block; font-style: normal;
}
.slide.register .entry .rs-talk small {
  display: block; margin-top: 0.75rem;
  font-family: var(--sans); font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--mute);
}
.slide.register .entry:hover .rs-talk { color: var(--accent); }

/* ==== v18.0 - the company exists, and the reader has somewhere else to go ==== */

/* ---- the footer states who and where ------------------------------------- */
.foot-co {
  display: flex; flex-wrap: wrap; gap: clamp(1.6rem, 5vw, 4.5rem);
  margin-top: 2.2rem; padding-top: 1.8rem; border-top: 1px solid var(--faint);
}
.foot-addr, .foot-reach {
  font-style: normal; font-family: var(--sans);
  font-size: 0.82rem; line-height: 1.85; color: var(--mute);
}
.foot-reach .link { color: var(--ink-soft); }
.foot-reach .link:hover { color: var(--accent); }

/* ---- two routes, not one -------------------------------------------------
   WhatsApp stays primary because the audience is international and it is what
   they use. The written route sits beside it for everyone not ready to message
   a stranger - which is most people, most of the time. */
.two-routes {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(1.2rem, 3vw, 2.6rem); margin-top: 2.2rem;
}
.act.quiet.on-ink { color: var(--cream); }
.act.quiet.on-ink:hover { color: rgba(244,241,235,0.66); }

/* ---- the criteria band ---------------------------------------------------
   The conversation for the reader who has reached the bottom and found nothing
   that fits. Quieter than the close, and deliberately after it. */
.criteria {
  background: var(--cream-deep);
  padding: clamp(3.5rem, 10vh, 7rem) 0;
  border-top: 1px solid var(--faint);
}

/* ---- what changed since you last looked ---------------------------------- */
.reg-change {
  margin-top: 1rem; font-family: var(--sans); font-size: 0.72rem;
  font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--accent);
}
.slide.deal .pc .since {
  font-style: normal; margin-left: 1.4em; color: var(--accent);
}

/* ==== v18.1 - the trading disclosure ==== */
.foot-entity {
  font-family: var(--sans); font-size: 0.82rem; line-height: 1.85;
  color: var(--mute); margin: 0;
}

/* ==== v19.0 - the LDP wordmark ====
   Three letters carry no meaning on their own, so they are set large and tracked open,
   with the words beneath doing the explaining. Same structure as before; different
   proportions, because initials need air that a word does not. */
.wordmark {
  font-variation-settings: "opsz" 144, "WONK" 1, "SOFT" 0;
  font-size: 1.42rem; letter-spacing: 0.07em; line-height: 1;
}
.wordmark small {
  letter-spacing: 0.24em; margin-top: 0.62em; font-size: 0.58rem;
}
.masthead.scrolled .wordmark { transform: scale(0.9); }
.foot .wordmark { font-size: 1.62rem; }

/* ==== v19.1 - two corrections ====
   opsz 144 is drawn for a headline at 60px+. Inherited by the 31px inline figure it goes
   thin and fragile, and the glyphs crowd. 48 is the right optical size for that mark. */
.lede .bn { font-variation-settings: "opsz" 48, "WONK" 1, "SOFT" 0; padding: 0 0.08em; }

/* ============================================================================
   v20.0 - THE REGISTER ON A PHONE
   The entry was a three-column grid with no mobile rule at all. On a 375px screen
   that left the description 21 pixels wide, running to fifteen lines, and pushed
   the figures half off the edge. The register is where the two largest lots live,
   so this was the worst thing on the site. It stacks now.
   ============================================================================ */
@media (max-width: 760px) {
  .slide.register .entry {
    grid-template-columns: 1fr;
    gap: 0.5rem;
    align-items: start;
    padding: 1.6rem 0;
  }
  .slide.register .entry .rn { font-size: 0.98rem; }
  .slide.register .entry .line { font-size: 1.04rem; line-height: 1.55; }

  /* figures move under the description and read left, like the rest of the column */
  .slide.register .entry .rs,
  .slide.register .entry .rs-talk {
    text-align: left; margin-top: 0.5rem;
  }
  .slide.register .entry .rs b { margin-top: 0.7rem; }
  .slide.register .entry .rs small { letter-spacing: 0.16em; }
  .slide.register .entry .rs-talk em { display: inline; }
  .slide.register .entry .rs-talk em + em::before { content: " "; }

  .slide.register .entry .r-act { margin-top: 0.7rem; }
}

/* the comparable rows want more room to breathe on a narrow column */
@media (max-width: 760px) {
  .slide.deal .comps { gap: 1.35rem; }
  .slide.deal .comp-row { column-gap: 1.1rem; }
  .slide.deal .comp-fig { font-size: clamp(1.35rem, 6.4vw, 1.75rem); }
  .slide.deal .comp-fig.pct {
    font-size: clamp(0.95rem, 4.4vw, 1.15rem);
    padding-left: 1.1rem; padding-top: 0.28em;
  }
  .slide.deal .comp-fig small { font-size: 0.56rem; letter-spacing: 0.15em; }
}

/* ============================================================================
   v20.1 - THE MENU ON A PHONE, AND THINGS BIG ENOUGH TO PRESS
   ============================================================================ */

/* The menu links are sized in VH, so on a 375x812 phone they came out at 58px and
   the six of them ran to 1075px in an 812px viewport - "How it works", "Speak to
   us" and the telephone number all sat below the fold. The existing mobile rule
   targeted .mn/.mt/.ms, sub-elements that no longer exist in the markup, so it was
   doing nothing at all. */
@media (max-width: 760px) {
  .menu-inner {
    justify-content: flex-start;
    padding-top: calc(var(--mast-h) + 1.6rem);
    padding-bottom: 2.4rem;
  }
  .menu-list a {
    font-size: clamp(1.7rem, 4.6vh, 2.4rem);
    padding: 0.34em 0;
  }
  .menu-foot { margin-top: 1.8rem; }
}
/* shorter phones again - an SE is 667 tall */
@media (max-width: 760px) and (max-height: 700px) {
  .menu-list a { font-size: clamp(1.45rem, 4.2vh, 1.95rem); padding: 0.28em 0; }
}

/* ---- things big enough to press ------------------------------------------
   Apple and WCAG both want 44px. The Menu button measured 19px tall and the
   Back link the same. The hit area is expanded without moving anything: the
   pseudo-element is invisible and does not affect layout. */
.menu-btn, .mast-back { position: relative; }
.menu-btn::after, .mast-back::after {
  content: ""; position: absolute; inset: -13px -10px; }

@media (max-width: 760px) {
  .wa-speak { padding: 0.55rem 0; }              /* 31px -> 44px+ */
  .act, .act.quiet { padding-top: 0.7rem; padding-bottom: 0.7rem; }
  .r-act, .foot-links a { display: inline-block; padding: 0.42rem 0; }
}

/* ---- no image may exceed its column -------------------------------------
   A postcode hero was rendering 383px wide inside a 375px viewport. Clipped
   rather than scrolling, so it never showed as overflow, but it was cropping
   the right edge of the photograph on every phone. */
img { max-width: 100%; }

/* ==== v21.1 - labels now vary in length, so they wrap evenly instead of nowrap ==== */
.slide.deal .comp-fig small { white-space: normal; text-wrap: balance; max-width: 13em; }

/* ==== v21.3 - a longer basis label should not cost a third line ==== */
.slide.deal .comp-fig small { max-width: 15em; }
@media (max-width: 760px) {
  .slide.deal .comp-fig small { letter-spacing: 0.12em; max-width: none; }
}
