/* ==========================================================================
   COZY HOME BY SHAM
   1 hero · 2 services · 3 proof · 4 start · 5 why · 6 process · 7 close · 8 faq
   ========================================================================== */

/* ------------------------------------------------------------------- BASE */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--cream);color:var(--ink);
  font:300 var(--t-body)/1.7 var(--sans);
  letter-spacing:.004em;-webkit-font-smoothing:antialiased;overflow-x:hidden;
}
body.lock{overflow:hidden}
img,svg,picture,video{display:block;max-width:100%}
img{height:auto}
/* A <picture> is only a wrapper, it must fill its frame or the img inside
   falls back to its natural ratio and object-fit never applies. */
.ss__stage .lyr>picture,.ss__mob>picture,.pf__fig>picture,.cmp__lyr>picture,
.fin__media,.hero__media,.op__fig>picture,.wy__fig .frame>picture{width:100%;height:100%}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none;padding:0}
button,input,select,textarea{font:inherit;color:inherit;background:none;border:0}
button{cursor:pointer}
.defs{position:absolute;width:0;height:0}
/* A class-level `display` beats the UA rule for [hidden], which would leave
   the dialog and menu overlays displayed (and click-catching) at opacity 0. */
[hidden]{display:none!important}
::selection{background:var(--olive-700);color:var(--cream)}

:focus-visible{outline:2px solid var(--olive-700);outline-offset:4px}
.st :focus-visible,.fin :focus-visible,.ft :focus-visible,.menu :focus-visible,
.inq :focus-visible,.pf__fig--over :focus-visible{outline-color:var(--champagne)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:1rem;top:-6rem;z-index:1000;background:var(--olive-900);color:var(--cream);
  padding:.9rem 1.4rem;border-radius:var(--r-pill);box-shadow:var(--sh-md);
  font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  transition:top var(--d-fast) var(--ease)}
.skip:focus{top:1rem}

/* ------------------------------------------------------------- TYPOGRAPHY */
.eyebrow{font-size:var(--t-xs);font-weight:500;letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-muted)}
.st .eyebrow,.fin .eyebrow,.inq .eyebrow{color:var(--champagne)}

.display,.title,.mega{font-family:var(--serif);font-weight:300;letter-spacing:-.018em;line-height:1}
.display{font-size:var(--t-display)}
.title{font-size:var(--t-title);line-height:1.04}
.display em,.title em,.it{font-style:italic;font-weight:300;color:var(--bronze)}
.st .display em,.fin .display em{color:var(--champagne)}
.st .display,.fin .display{color:var(--cream)}

p{text-wrap:pretty}

.clip{display:block;overflow:hidden;padding-bottom:.08em}
.clip__i{display:block;transform:translateY(105%)}
.is-still .clip__i{transform:none}

/* -------------------------------------------------------------- INSTAGRAM */
/* The one dark object on the ivory work section, so it reads as the way out of
   the page. No borrowed brand gradient: a rainbow ring on a warm olive and
   cream palette reads as a widget bolted on, not as part of the studio. The
   glyph sits in a champagne disc instead, which is the one place in this
   section the jewellery colour appears, and the hairline is champagne held
   back to a third. */
.ig{position:relative;display:inline-flex;align-items:center;gap:var(--s4);
  padding:.6rem 1.7rem .6rem .6rem;border-radius:var(--r-pill);
  color:var(--cream);isolation:isolate;overflow:hidden;
  background:linear-gradient(180deg,#24271C,#14160F);
  box-shadow:
    inset 0 0 0 1px rgba(217,201,169,.34),   /* champagne rim, deliberately faint */
    inset 0 1px 0 rgba(255,255,255,.08),
    0 2px 6px rgba(20,22,15,.22),
    0 16px 34px -16px rgba(20,22,15,.55);
  transition:transform var(--d) var(--ease-out),box-shadow var(--d) var(--ease)}
/* the champagne wash arrives from the bottom edge on hover, the same wipe the
   filled buttons use, so the whole site hovers the same way */
.ig::before{content:'';position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,#2E3124,#1B1E15);
  transform:translateY(101%);transition:transform var(--d) var(--ease-out)}
.ig:hover,.ig:focus-visible{transform:translateY(-2px);
  box-shadow:
    inset 0 0 0 1px rgba(217,201,169,.62),
    inset 0 1px 0 rgba(255,255,255,.10),
    0 3px 8px rgba(20,22,15,.24),
    0 26px 48px -18px rgba(20,22,15,.6)}
.ig:hover::before,.ig:focus-visible::before{transform:translateY(0)}
.ig:active{transform:translateY(0) scale(.99)}
@media (prefers-reduced-motion:reduce){
  .ig,.ig:hover,.ig:focus-visible{transform:none}
}

.ig__glyph{flex:none;display:grid;place-items:center;
  width:clamp(38px,3.4vw,44px);aspect-ratio:1;border-radius:50%;
  background:var(--champagne);color:var(--olive-950);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 1px 3px rgba(20,22,15,.35);
  transition:background var(--d) var(--ease)}
.ig:hover .ig__glyph,.ig:focus-visible .ig__glyph{background:var(--ivory)}
.ig__glyph svg{width:21px;height:21px}
.ig__txt{display:grid;gap:.2rem;text-align:left}
.ig__l{font:500 .92rem/1.1 var(--sans);letter-spacing:.006em}
.ig__h{font-size:.78rem;line-height:1.1;letter-spacing:.05em;color:var(--on-dark-mute)}

/* ------------------------------------------------------------------ GHOST */
/* Oversized tone-on-tone words behind the content. They are what make the
   sections read as large rooms instead of stacked boxes. Purely decorative:
   aria-hidden in the markup, no pointer events, no selection, and held to a
   few percent of the ground so text sitting over one loses nothing measurable.
   `overflow:clip` rather than `hidden` so no section becomes a scroll
   container and nothing inside loses position:sticky. */
.sv,.pf,.st,.wy,.pr,.faq{position:relative;isolation:isolate;overflow:clip}
.ghost{position:absolute;z-index:-1;pointer-events:none;
  -webkit-user-select:none;user-select:none;
  font-family:var(--serif);font-weight:400;
  font-size:clamp(6rem,21vw,19rem);line-height:.74;letter-spacing:-.045em;
  white-space:nowrap;color:rgba(65,68,55,.055)}
/* Cream and ivory are bright enough to take a deepened watermark with room to
   spare. Limestone is not: darkening it pulls the eyebrow from 4.67:1 to
   4.30:1. On that ground, and on the dark one, the watermark LIFTS the tone
   instead, which can only ever raise the contrast of the text over it. */
.pr .ghost{color:rgba(251,249,244,.10)}
.st .ghost{color:rgba(243,239,230,.06)}
/* bled off the edges by a fraction of their own size, so the crop scales with
   the type rather than drifting at different widths */
.ghost--tl{top:-.10em;left:-.05em}
.ghost--tr{top:-.10em;right:-.05em}
.ghost--bl{bottom:-.16em;left:-.05em}
.ghost--br{bottom:-.16em;right:-.05em}
@media (max-width:740px){
  .ghost{font-size:clamp(4.5rem,30vw,9rem)}
}

/* ------------------------------------------------------------------- CTAs */
/* Sentence case at a readable size with almost no tracking. Tiny caps set at
   .2em is the thing that dates a button; the label should read as language,
   not as a specimen. */
.cta{display:inline-flex;align-items:center;gap:.6em;
  font:500 .9rem/1 var(--sans);letter-spacing:.006em;
  color:inherit;position:relative;white-space:nowrap}
/* same box as the arrow, so a button carrying either glyph is the same height */
.cta__wa{width:19px;height:19px;flex:none}

.cta--line{padding:.7em 0}
.cta--line::after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:left;transition:transform var(--d) var(--ease-out)}
.cta--line:hover::after,.cta--line:focus-visible::after{transform:scaleX(1)}

/* Actions are pills with a contact shadow, and they compress a touch when
   pressed, so they read as objects rather than painted rectangles. */
.cta--fill{padding:1.05em 1.75em 1.05em 1.9em;color:var(--cream);
  background:linear-gradient(180deg,#4C5041,#3A3E31);
  border-radius:var(--r-pill);overflow:hidden;isolation:isolate;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.13),
             0 1px 2px rgba(20,22,15,.22),
             0 9px 22px -11px rgba(20,22,15,.6);
  transition:background var(--d) var(--ease),color var(--d) var(--ease),
             box-shadow var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.cta--fill::before{content:'';position:absolute;inset:0;border-radius:inherit;
  background:var(--olive-950);z-index:-1;
  transform:translateY(101%);transition:transform var(--d) var(--ease-out)}
.cta--fill:hover::before,.cta--fill:focus-visible::before{transform:translateY(0)}
.cta--fill:hover,.cta--fill:focus-visible{transform:translateY(-1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),
             0 2px 4px rgba(20,22,15,.24),
             0 16px 32px -14px rgba(20,22,15,.66)}
.cta--fill:active{transform:translateY(0) scale(.986);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 2px rgba(20,22,15,.3)}
.cta--sm{padding:.85em 1.4em;font-size:.82rem}

/* Glass action, the same box as .cta--fill, only the surface changes. A
   filled olive pill standing on photography reads as a foreign object dropped
   onto the picture; this one is mostly the picture. It is only used where the
   veil behind it is already deep, which is why it can open up this far. */
.cta--glass{
  background:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,0) 54%),
             rgba(26,24,21,.18);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  /* at this opacity the rim is doing the work of telling you it is a button,
     so it carries more light than the pill's own surface */
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3),
             inset 0 0 0 1px rgba(255,255,255,.26),
             0 10px 26px -12px rgba(20,22,15,.4)}
/* the wipe frosts rather than darkens */
.cta--glass::before{background:rgba(255,255,255,.15)}
.cta--glass:hover,.cta--glass:focus-visible{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.36),
             inset 0 0 0 1px rgba(255,255,255,.38),
             0 16px 32px -14px rgba(20,22,15,.46)}
.cta--glass:active{box-shadow:inset 0 1px 0 rgba(255,255,255,.14),
             inset 0 0 0 1px rgba(255,255,255,.16)}

.cta--line-light{padding:calc(1.05em - 1px) calc(1.9em - 1px);border-radius:var(--r-pill);
  border:1px solid rgba(243,239,230,.34);color:var(--cream);
  box-shadow:inset 0 0 0 0 rgba(243,239,230,0);
  transition:background var(--d) var(--ease),border-color var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.cta--line-light:hover{background:rgba(243,239,230,.12);border-color:rgba(243,239,230,.7)}
.cta--line-light:active{transform:scale(.982)}

.cta--quiet{padding:.7em 0;color:var(--on-dark-mute)}
.cta--quiet:hover{color:var(--on-dark)}
.cta[disabled],.cta.off{opacity:.3;pointer-events:none}

/* -------------------------------------------------------------------- NAV */
/* A floating glass pill: dark at the ends, lit from beneath in the middle,
   with a bevelled top edge. It hovers off the viewport rather than sitting
   flush against it. */
.nav{position:fixed;top:clamp(1rem,2.4vw,1.9rem);left:0;right:0;z-index:var(--z-nav);
  padding-inline:var(--gutter);transition:transform var(--d) var(--ease)}
.nav.up{transform:translateY(calc(-100% - 1.5rem))}

.nav__in{
  max-width:min(78rem,100%);margin-inline:auto;position:relative;isolation:isolate;
  display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;gap:var(--s5);
  padding:.4rem clamp(.7rem,1.1vw,1.05rem);border-radius:var(--r-pill);color:var(--cream);
  /* Warm frosted glass so the photograph reads through it. The tint is a warm
     near-black, never olive, tinted chrome fights the picture. 58% is as far
     as it can open up: the photograph behind the left-hand links peaks at
     0.80 sRGB, and any thinner the uppercase links drop under 4.5:1. */
  background:
    linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,0) 54%),
    rgba(26,24,21,.36);
  /* 36% is a floor, not a preference. Blurred, the photograph behind the
     left-hand links still reads 0.855 sRGB: that whole corner is sheer curtain
     in daylight, not one stray highlight. Below 36% with this crown the small
     uppercase links drop under 4.5:1. The blur earns its place here too, since
     it averages the specular hits out before the tint is applied. */
  -webkit-backdrop-filter:blur(22px) saturate(140%);
  backdrop-filter:blur(22px) saturate(140%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.26),        /* light catching the top edge */
    inset 0 0 0 1px rgba(255,255,255,.26),      /* the rim, now the main event  */
    0 10px 24px -16px rgba(20,22,15,.3)}        /* barely there: a see-through
                                                   object should not cast much */

/* The whole bar is present from the first screen, links, mark and button.
   Past the hero the chrome only sits heavier and the mark steps back a little,
   so the row slims without anything appearing or disappearing. */
.nav__in{transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease)}

/* Past the hero the glass sits over cream and limestone sections, which are
   far brighter than the photograph, so it takes more body to hold the type. */
.nav.solid .nav__in{
  background:
    linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 54%),
    rgba(24,22,19,.80);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 0 0 1px rgba(255,255,255,.09),
    0 18px 38px -18px rgba(20,22,15,.5),
    0 36px 72px -30px rgba(20,22,15,.6)}

/* ---- the brand: the client's own artwork, used as drawn ----
   The wordmark reads down the left end of the bar, where a masthead goes,
   rather than floating in the middle of the links. The artwork is the
   client's own stacked setting of the name, placed whole and never split.

   It carries a real alpha channel, so it no longer needs the `screen` blend
   the previous artwork depended on to drop its baked-in black.

   The extra left padding is not decoration. The bar is a pill, so at the
   height of the logo's top and bottom edges the rounded end has already cut
   about 14px into the track, and a logo sitting on the track's own padding
   would clip into that curve. */
.nav__brand{grid-area:1/1;justify-self:start;display:flex;align-items:center;
  padding-left:clamp(.5rem,1.1vw,1rem)}
/* The wordmark is set on three lines, so its height is shared between COZY,
   HOME and the small BY SHAM under them. At 44px that third line closed up
   into a smudge; 52px is the point where it still reads. */
.nav__logo{flex:none;height:52px;width:auto;
  transition:opacity var(--d) var(--ease),height var(--d-slow) var(--ease-out)}
/* the mark carries the landing view; once the bar goes solid it steps back so
   the row stays slim */
.nav.solid .nav__logo{height:45px}
.nav__brand:hover .nav__logo{opacity:.82}

/* Two equal outer tracks with the mark between them, which is the only way
   the mark lands on the true centre of the bar: the masthead and the button
   are nothing like the same width, so a middle track sized around them would
   put the mark off centre by the difference.

   Each side then pushes its two children apart, so the wordmark and the
   button sit at the outer ends and both runs of links close in on the mark. */
.nav__side{grid-area:1/1;display:flex;align-items:center;gap:var(--s5);
  min-width:0;justify-content:space-between}
.nav__side--r{grid-area:1/3}
/* margin-auto rather than relying on the row's space-between: below 1025px
   the links beside it are display:none, and space-between with a single
   visible child parks that child at the start of the track, which left the
   menu button stranded 94px short of the end of the bar. */
.nav__end{display:flex;align-items:center;gap:var(--s5);margin-left:auto}

.nav__emblem{grid-area:1/2;justify-self:center;display:flex;align-items:center;
  color:var(--cream)}
.nav__emblem svg{display:block;width:42px;height:42px;
  transition:width var(--d-slow) var(--ease-out),height var(--d-slow) var(--ease-out)}
/* it steps back with the rest of the bar once the page is past the hero */
.nav.solid .nav__emblem svg{width:36px;height:36px}
.nav__links{display:flex;gap:var(--s6)}
.nav__links a{font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;font-weight:500;
  opacity:.95;position:relative;padding:6px 0;transition:opacity var(--d) var(--ease);
  text-shadow:0 1px 10px rgba(20,22,15,.5)}
.nav__links a::after{content:'';position:absolute;left:0;bottom:0;height:1px;width:100%;
  background:currentColor;transform:scaleX(0);transform-origin:right;
  transition:transform var(--d) var(--ease-out)}
.nav__links a:hover,.nav__links a.here{opacity:1}
.nav__links a:hover::after,.nav__links a.here::after{transform:scaleX(1);transform-origin:left}



/* ---- raised CTA ---- */
/* Outlined and see-through to match the bar, so nothing on the first screen is
   a solid block. The colour arrives on hover: .cta--fill already carries a
   wipe that slides up from the bottom edge, so it only needs repainting cream
   and the label flipping dark as it lands. */
.nav__cta{border:0;flex:none;padding:.85em 1.5em;color:var(--cream);
  background:none;
  /* with no fill, this hairline is the whole boundary of the control, so it
     has to clear 3:1 against the bar behind it (WCAG 1.4.11) */
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.58)}
.nav__cta::before{background:var(--cream)}
.nav__cta:hover,.nav__cta:focus-visible{color:var(--olive-950);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),
             0 2px 10px rgba(20,22,15,.22)}
.nav__cta:active{box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.nav__cta:hover,.nav__cta:focus-visible{color:var(--olive-950)}

/* ---- the burger sits in a recessed well ---- */
.burger{display:grid;flex:none;width:42px;height:42px;place-items:center;color:var(--cream);
  border-radius:13px;
  background:linear-gradient(180deg,rgba(0,0,0,.42),rgba(0,0,0,.16));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 -1px 2px rgba(0,0,0,.6),
    inset 0 0 0 1px rgba(255,255,255,.07);
  transition:background var(--d) var(--ease)}
.burger:hover{background:linear-gradient(180deg,rgba(0,0,0,.2),rgba(255,255,255,.09))}
.burger__bars{display:grid;gap:4px;width:17px}
.burger i{display:block;height:1.5px;border-radius:2px;background:currentColor;
  transition:transform var(--d) var(--ease),opacity var(--d-fast) var(--ease)}
.burger[aria-expanded="true"] i:first-child{transform:translateY(5.5px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:last-child{transform:translateY(-5.5px) rotate(-45deg)}

/* --------------------------------------------------------------- FULLMENU */
/* The drawer opens as glass over the page rather than a solid panel wiping
   down it. You can still sense where you were, which is what stops a menu
   feeling like a different screen you have been thrown to.

   The tint is .86, which sounds heavy for glass and is not: the page behind
   can be the ivory sections, and at anything thinner the cream type would be
   sitting on close to white. At .86 even pure white blurs down to about 50 of
   255 behind it, so the type holds about 10:1 wherever the drawer is opened.

   Eight full width hairlines between eight links is what made the old one
   read as a list of rows. There is one rule now, between the destinations and
   the actions, and it is doing real work. */
.menu{position:fixed;inset:0;z-index:var(--z-menu);color:var(--cream);
  padding:calc(5.4rem + env(safe-area-inset-top)) var(--gutter)
          calc(var(--s6) + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;gap:var(--s6);
  overflow-y:auto;overscroll-behavior:contain;
  background:rgba(18,19,14,0);
  -webkit-backdrop-filter:blur(0px) saturate(100%);
  backdrop-filter:blur(0px) saturate(100%);
  opacity:0;
  transition:opacity .42s var(--ease-out),background .5s var(--ease-out),
             backdrop-filter .62s var(--ease-out)}
.menu.open{opacity:1;background:rgba(18,19,14,.86);
  -webkit-backdrop-filter:blur(30px) saturate(125%);
  backdrop-filter:blur(30px) saturate(125%)}

/* While the drawer is open the bar rides above it. The drawer is fixed to the
   whole viewport and sits over the navigation, which means it was covering
   the burger: the one control that dismisses it. Lifting the bar keeps the
   masthead in place and leaves the X in the corner where it is expected.
   The bar also stops hiding itself, since there is nothing to scroll. */
body.lock .nav{z-index:calc(var(--z-menu) + 1)}
body.lock .nav.up{transform:none}

.menu__links{display:flex;flex-direction:column}
/* Baseline aligned, so the numerals sit on the same line as the words rather
   than floating beside them. The target is 52px; the type is a third smaller
   than it was, because a drawer that shouts its own navigation at you is the
   opposite of expensive. */
.menu__links a{display:flex;align-items:baseline;gap:clamp(.85rem,3.4vw,1.25rem);
  min-height:48px;padding:.26em 0;
  opacity:0;transform:translateY(16px)}
.menu.open .menu__links a{opacity:1;transform:none;
  transition:opacity .62s var(--ease-out),transform .62s var(--ease-out)}
.menu__n{flex:none;width:2ch;
  font:500 var(--t-xs)/1 var(--sans);letter-spacing:.18em;
  color:var(--champagne);opacity:.7;
  font-variant-numeric:lining-nums tabular-nums;
  transition:opacity var(--d) var(--ease)}
.menu__t{position:relative;font-family:var(--serif);font-weight:300;
  font-size:clamp(1.45rem,5.6vw,2.05rem);line-height:1.05;letter-spacing:-.015em}
/* the rule is drawn under the words only, not across the whole row */
.menu__t::after{content:'';position:absolute;left:0;right:0;bottom:-.16em;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:right;
  transition:transform var(--d) var(--ease-out)}
.menu__links a:hover .menu__t::after,
.menu__links a:focus-visible .menu__t::after{transform:scaleX(1);transform-origin:left}
/* where you already are */
.menu__links a[aria-current] .menu__n{opacity:1}
.menu__links a[aria-current] .menu__t::after{transform:scaleX(1);
  background:var(--champagne)}

.menu__foot{display:grid;gap:var(--s4);margin-top:auto;
  padding-top:var(--s5);border-top:1px solid var(--rule-dark-sf)}
/* the row already sits in a grid with its own gap, so its own top margin was
   spacing it twice and pushing the icons off the bottom of the panel */
.menu__foot .menu__soc{margin-top:0}
.menu__foot > *{opacity:0;transform:translateY(16px)}
.menu.open .menu__foot > *{opacity:1;transform:none;
  transition:opacity .62s var(--ease-out),transform .62s var(--ease-out)}
.menu__foot .cta--fill{justify-content:center}
.menu__contact{display:grid;gap:.35rem;font-size:var(--t-sm);color:var(--on-dark-mute)}
.menu__contact a:hover{color:var(--cream)}
/* the same icon row as the footer, on the dark overlay */
.menu__soc{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:var(--s5);
  list-style:none;padding:0}
.menu__soc a{width:46px;height:46px;display:grid;place-items:center;
  border-radius:50%;color:var(--on-dark-mute);
  transition:color var(--d) var(--ease),background var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.menu__soc svg{width:21px;height:21px}
.menu__soc a:hover{color:var(--cream);background:rgba(243,239,230,.1)}
.menu__soc a:active{transform:scale(.94)}

/* ================================================================ 1 · HERO */
.hero{position:relative;
  /* lvh, not svh: svh is the height with the browser chrome showing, so the
     moment the URL bar retracts the viewport grows and the next section slides
     into view on its own. lvh is the chrome-hidden height, so the hero always
     covers the screen and the page below it only arrives on a scroll.
     The vh line is the fallback for browsers without the newer units. */
  min-height:100vh;min-height:100lvh;
  display:grid;align-items:end;
  /* the block sits lower than it did: the foot was 64px on a 1440 screen and
     is 40 now, which is the client asking for the opening view to feel
     focused rather than spread */
  isolation:isolate;overflow:hidden;
  /* The foot is shared. The facts band at the bottom cancels it with a
     negative margin so the band itself can reach the bottom of the screen,
     and pays the same air back as its own padding. */
  --hero-pad-b:clamp(1.8rem,3vw,2.5rem);
  padding:var(--s11) var(--gutter) var(--hero-pad-b)}
/* the film sits over the still, so the still is what shows whenever the film
   cannot or should not play */
.hero__v{position:absolute;inset:0;z-index:-1;width:100%;height:100%;
  object-fit:cover;object-position:50% 58%;display:block}
/* below the hero's own breakpoint a 16:9 film centre cropped to a portrait
   screen keeps about a quarter of the room, so the phone keeps its still */
/* Mobile video is now decided in js/motion.js, based on the device's
   effective connection type: fast connections see the film, slow ones
   see the still. See heroFilm(). */
@media (prefers-reduced-motion:reduce){ .hero__v{display:none} }
.hero__media{position:absolute;inset:0;z-index:-2}
.hero__media img{width:100%;height:100%;object-fit:cover;
  transform:scale(1.05);animation:push 14s var(--ease-soft) forwards}
@keyframes push{to{transform:scale(1)}}
/* This photograph is bright the whole way down, including the polished floor
   in the bottom corners, so the base needs a real ramp, not the shallow pool
   the old darker image wanted. The top four-tenths of the frame is left
   completely alone, which is where the airiness lives. */
.hero__veil{position:absolute;inset:0;z-index:-1;background:
  /* A wide, low pool carrying the whole type block. It was 70% wide centred
     at 18%, which was right when the block ended at the buttons. The facts
     row now reaches about 46% across the frame, and its last label was
     sitting out past the edge of the pool at 3.93:1. Widening the pool and
     moving its centre right carries that label at 4.9:1 without touching the
     top four-tenths of the frame, which is where the airiness lives. */
  radial-gradient(88% 115% at 24% 106%,rgba(18,20,14,.74),rgba(18,20,14,0) 84%),
  /* the base ramp, carrying the whole lower band the type occupies */
  linear-gradient(to top,rgba(18,20,14,.48),rgba(18,20,14,.43) 22%,
    rgba(18,20,14,.34) 42%,rgba(18,20,14,.15) 58%,rgba(18,20,14,0) 72%),
  /* THE CROWN, and why it is as deep as it is.
     It carries the navigation, whose pill is almost fully see-through, and
     the opening hours, which have no plate and no pool of their own.

     The hours land on a window, and the window is blown out: the brightest
     pixel under that line measures 254,254,255, which is paper white. Cream
     on paper white is about one to one, so something has to take the light
     out of it, and the only shape that can do that without being seen doing
     it is one that spans the whole frame. Measured rather than guessed: 62%
     is what carries cream past 4.5:1 against that pixel, so the ramp holds
     near 62 through the band the mark sits in, 16% to 19% down, and then
     falls away quickly so the darkness stays in the top quarter instead of
     spreading into the room. */
  linear-gradient(to bottom,
    rgba(18,20,14,.66),
    rgba(18,20,14,.63) 13%,
    rgba(18,20,14,.61) 20%,
    rgba(18,20,14,.34) 27%,
    rgba(18,20,14,.12) 34%,
    rgba(18,20,14,0) 43%)}

.hero__in{position:relative;max-width:var(--maxw);margin-inline:auto;width:100%;color:var(--cream)}
/* a wide, soft halo hugging the letterforms, invisible as a shadow, but it
   lifts the type clear of whatever the photograph is doing behind it */
.hero__h,.hero__line{
  text-shadow:0 1px 2px rgba(18,20,14,.42),0 2px 18px rgba(18,20,14,.55),
              0 8px 64px rgba(18,20,14,.72)}
/* 24px under the heading read as a gap rather than as a pair. The line
   belongs to the heading, so it sits up against it. */
.hero__h{font-family:var(--serif);font-weight:300;font-size:var(--t-hero);
  line-height:.94;letter-spacing:var(--track-mega);margin-bottom:var(--s2)}
.hero__h .it{color:var(--champagne)}
.hero__line{max-width:30rem;color:var(--cream);font-size:var(--t-lede);
  letter-spacing:.01em;margin-bottom:var(--s5)}
/* The buttons sit directly under the opening line now, with the facts moved
   below them into a band of their own. So this is the ordinary air between a
   sentence and the buttons answering it, not the gap that used to hold two
   groups apart. */
.hero__acts{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;
  margin-top:clamp(.9rem,1.8vw,1.4rem)}

/* ---- the facts, ruled across the foot of the first screen ---- */
/* They used to be a group in the left third, three short entries each with a
   26px kicker over it. The client asked for them spread out, with the rule
   running across the screen, so they are a band now: one hairline from edge
   to edge, three columns holding the whole measure, hairlines between them.

   HOW THE RULE REACHES THE GLASS. The band steps out of the measure by
   exactly the distance back to the edge of the window, then pays the same
   distance back as padding. The rule runs edge to edge while the writing
   stays in line with the heading above it, at every width, with no second
   set of numbers to keep in step. --vw is the window without its scrollbar,
   which is the reason this does not put a horizontal scrollbar on a page
   that has nothing to scroll sideways to, the way 100vw would.

   It sits flush to the bottom of the hero: the negative bottom margin
   cancels the hero's own foot, and the band carries that air inside itself
   instead, so the shade under it goes all the way to the edge of the screen
   rather than stopping short of it. */
.hf{--bleed:max(var(--gutter),calc((var(--vw) - var(--maxw)) / 2));
  list-style:none;position:relative;order:2;
  margin:clamp(2.1rem,4vw,3.4rem) calc(var(--bleed) * -1)
         calc(var(--hero-pad-b) * -1);
  padding:clamp(1rem,2vw,1.55rem) var(--bleed) var(--hero-pad-b);
  border-top:1px solid rgba(217,201,169,.34);
  display:grid;grid-auto-flow:column;grid-auto-columns:1fr}

/* Four columns is too tight on a 375px phone: "Island-" clipped and
   "Mon to Fri, 9 to 2" wrapped to three lines. Two-up two-rows gives
   each fact enough width to breathe. */
@media (max-width:560px){
  .hf{grid-auto-flow:row;grid-template-columns:1fr 1fr;grid-auto-columns:auto;
    gap:var(--s4) 0}
  /* re-establish the dividers for the 2x2 layout: a vertical hairline
     between columns, a horizontal one between rows */
  .hf__i + .hf__i::before{display:none}
  .hf__i:nth-child(even){border-left:1px solid rgba(217,201,169,.3)}
  .hf__i:nth-child(n+3){border-top:1px solid rgba(217,201,169,.22);
    padding-top:var(--s4)}
  .hf__i:nth-child(odd){padding-left:0}
}

/* THE BAND'S OWN SHADE.
   The ramp on the veil was built for a group of words in the left third of
   the frame. The band reaches the right hand side now, where the window and
   the curtains are the brightest thing in the film, and the last label was
   reading 3.7 against them. This is a wash under the band alone, fading
   upward so it has no top edge to be seen, only a corner of the room in
   shade. */
/* Two washes, because the light in the frame is not even. The upward one
   carries the band; the sideways one answers the window, which is the
   brightest thing in the room and sits under the third column. Measured:
   WHERE WE WORK in champagne was reading 3.54 against the glass behind it
   and 4.98 with this. The left hand end is untouched, where the pool on the
   veil is already doing the work. */
.hf::after{content:'';position:absolute;z-index:-1;pointer-events:none;
  inset:0;background:
    linear-gradient(to right,rgba(18,20,14,0) 38%,rgba(18,20,14,.28) 100%),
    linear-gradient(to top,
      rgba(18,20,14,.56),rgba(18,20,14,.42) 58%,rgba(18,20,14,0))}

/* a column, so the band can be ordered below the buttons without moving it
   in the markup, where a phone still needs it first */
.hero__foot{display:flex;flex-direction:column}

.hf__i{display:grid;gap:.5rem;align-content:start;
  /* Two rows, label on row 1 and value on row 2. The value row is
     subgridded across all four items via a shared ancestor grid, so the
     values always sit on the same baseline no matter whether a label
     wraps onto a second line or not. */
  grid-template-rows:auto 1fr;
  padding-inline:clamp(1.1rem,3vw,2.8rem)}
.hf{align-items:stretch}
.hf__i:first-child{padding-left:0}
.hf__i:last-child{padding-right:0}
/* The dividers fade out at the foot. A hairline that stops dead reads as a
   table border; one that fades reads as a pen stroke. They start level with
   the long rule, so the three meet at a corner rather than crossing. */
.hf__i + .hf__i{position:relative}
.hf__i + .hf__i::before{content:'';position:absolute;pointer-events:none;
  left:0;top:calc(clamp(1rem,2vw,1.55rem) * -1);bottom:.2rem;width:1px;
  background:linear-gradient(to bottom,
    rgba(217,201,169,.34),rgba(217,201,169,.3) 40%,rgba(217,201,169,0))}
/* the kicker over each entry has nothing left to do; the long rule does it */
.hf__r{display:none;width:26px;height:1px;background:var(--champagne);
  margin-bottom:.35rem}
.hf__k{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--champagne);line-height:1.3;
  text-shadow:0 1px 10px rgba(18,20,14,.8);
  /* Reserve two lines of label height, so a one-word label ("Open") and a
     two-word one ("Opening hours") both push the value down by the same
     amount. Values below are then on the same baseline. */
  min-height:calc(1.3em * 2)}
/* Values anchor to the bottom of their cell: with labels of varying real
   line count, this is what makes the figure line up across all four. */
.hf__v{align-self:end}
.hf__v{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.2rem,2.4vw,1.95rem);line-height:1.15;letter-spacing:-.01em;
  color:var(--cream);text-wrap:balance;
  text-shadow:0 1px 12px rgba(18,20,14,.75),0 2px 30px rgba(18,20,14,.6)}

@media (max-width:740px){
  /* three across is too tight to read at this width, so they run two up and
     one under, which keeps the figures at a size worth printing */
  /* a two column grid rather than a wrapping flex row: left on its own on
     the second line, the odd item stretched to the full width and the group
     came out lopsided */
  /* Facts and actions become one grid. `display:contents` drops the list box
     so its three entries become cells of that grid directly, which is what
     lets the buttons take the fourth cell, beside Where we work, instead of
     starting a new row under it. The list keeps an explicit role, since
     contents has historically taken the list semantics with the box.

     The columns are not even: the right one is widened because it carries a
     button whose words cannot be made to wrap, while the left one only has to
     hold a short label. */
  .hero__foot{display:flex;flex-direction:column;gap:0}
  /* THE PHONE GETS THE SAME BAND AS THE DESKTOP.
     It used to break the band up and scatter the three facts through a two
     column grid with the buttons, each with its own little kicker rule. That
     read as clutter, and it threw away the one device that makes the desktop
     foot work: a single line running the whole way across with the facts
     standing along it.

     Three across at this width is tight but it measures: the values are the
     widest thing in each column at about 80px and the columns are 105, so
     only the small caps labels wrap, which is what small caps labels are
     for. The buttons take a row of their own above it. */
  .hf__r{display:none}
  .hf__i:nth-child(1){grid-column:auto;grid-row:auto}
  /* Champagne is a beautiful label colour and it holds 4.97:1 on the wide
     crop, but on the portrait photograph, at this height, it lands at 3.12.
     Cream carries 5.34 in the same spot. The kicker rule above each fact
     stays champagne, so the accent does not leave the group. */
  .hf__k{color:var(--cream)}
  /* the tracking gives way rather than the line: at .14em WHERE WE WORK broke
     across two lines once the column narrowed to make room for the button */
  .hf__k{letter-spacing:.09em}
  .hf__v{font-size:1.1rem}
  .hf__r{width:20px}
}


/* -------------------------------------------------- CENTRED SECTION HEADS */
/* Eyebrow, a short hairline echoing the rule beside JAMAICA in the hero,
   then the heading on a measure tight enough to break into balanced lines. */
.shead{justify-items:center;text-align:center}
.shead .eyebrow{display:flex;flex-direction:column;align-items:center;gap:var(--s3)}
.shead .eyebrow::after{content:'';width:54px;height:1px;background:currentColor;opacity:.45}
.shead .display,.shead .title{max-width:20ch;text-wrap:balance}
.shead p:not(.eyebrow){max-width:32rem;margin-inline:auto;text-wrap:pretty}

/* section CTAs sit on the centre line so the block reads as one column */
.pf__foot,.pr__foot{display:flex;justify-content:center;align-items:center}

/* ======================================================= 2 · SERVICES */
.sv{padding:var(--bay) var(--gutter);background:var(--cream)}
.sv__head{max-width:var(--maxw);margin:0 auto var(--s8);display:grid;gap:var(--s4)}
.ss{max-width:var(--maxw);margin-inline:auto;display:grid;gap:var(--s7)}

.ss__list{border-top:1px solid var(--rule)}
.ss__i{border-bottom:1px solid var(--rule)}
.ss__b{width:100%;display:flex;align-items:baseline;gap:var(--s5);padding:var(--s5) 0;text-align:left}
.ss__n{font:500 var(--t-xs)/1 var(--sans);letter-spacing:.28em;color:var(--ink-faint);flex:none;
  transition:color var(--d) var(--ease)}
.ss__name{flex:1;font-family:var(--serif);font-weight:300;line-height:1.06;
  font-size:clamp(1.45rem,3.4vw,2.7rem);color:var(--ink-muted);
  transition:color var(--d) var(--ease)}
.ss__plus{flex:none;position:relative;width:14px;height:14px;align-self:center;color:var(--ink-faint)}
.ss__plus::before,.ss__plus::after{content:'';position:absolute;inset:50% 0 auto 0;height:1px;
  background:currentColor;transition:transform var(--d) var(--ease),opacity var(--d) var(--ease)}
.ss__plus::after{transform:rotate(90deg)}
.ss__i.on .ss__name{color:var(--ink)}
.ss__i.on .ss__n{color:var(--bronze)}
.ss__i.on .ss__plus::after{transform:rotate(0);opacity:0}
.ss__i.on .ss__plus{color:var(--bronze)}

.ss__p{overflow:hidden;height:0;transition:height var(--d) var(--ease-out)}
.ss__p-in{padding:0 0 var(--s6);display:grid;gap:var(--s5);justify-items:start;max-width:34rem}
.ss__mob{width:100%;aspect-ratio:3/2;overflow:hidden;background:var(--limestone-lt);
  border-radius:var(--r-lg);box-shadow:var(--edge)}
.ss__mob img{width:100%;height:100%;object-fit:cover}
.ss__line{color:var(--ink-muted)}
.ss__stage{display:none}

/* ========================================================== 3 · THE PROOF */
.pf{padding:var(--bay) var(--gutter);background:var(--ivory)}
.pf__head{max-width:var(--maxw);margin:0 auto var(--s8);display:grid;gap:var(--s4);
  justify-items:center}
/* the portfolio link sits under the heading now, so it needs its own air
   above it rather than the tight gap the eyebrow and title share */
.pf__head .pf__portfolio{margin-top:var(--s4)}
.pf__feature{max-width:var(--maxw);margin-inline:auto}
.pf__fig{position:relative;overflow:hidden;background:var(--limestone-lt);aspect-ratio:16/9;
  border-radius:var(--r-lg);box-shadow:var(--edge)}
.pf__fig img{width:100%;height:100%;object-fit:cover;transition:transform 1.4s var(--ease-out)}
.pf__feature:hover .pf__fig img,.pf__s:hover .pf__fig img{transform:scale(1.035)}
.pf__fig--over{max-height:84svh;border-radius:var(--r-xl);box-shadow:var(--sh-md),var(--edge)}
.pf__fig--over::after{content:'';position:absolute;inset:auto 0 0 0;height:50%;z-index:1;
  background:linear-gradient(to top,rgba(20,22,15,.76),rgba(20,22,15,.26) 45%,transparent);
  pointer-events:none}
.pf__cap{position:absolute;z-index:2;left:clamp(1.1rem,3vw,2.4rem);bottom:clamp(1rem,2.4vw,1.9rem);
  color:var(--cream);display:grid;gap:.5rem}
.pf__t{font-family:var(--serif);font-weight:300;font-size:clamp(1.7rem,4.4vw,3.4rem);line-height:1;
  letter-spacing:-.02em}
.pf__m{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;color:rgba(243,239,230,.8)}

.pf__pair{max-width:var(--maxw);margin:var(--s6) auto 0;display:grid;gap:var(--s6)}
.pf__s .pf__fig{aspect-ratio:4/5}
.pf__scap{padding-top:var(--s4);display:grid;gap:.35rem}
.pf__st{font-family:var(--serif);font-weight:300;font-size:clamp(1.2rem,2.4vw,1.7rem);line-height:1.1}
.pf__s .pf__m{color:var(--ink-muted)}

.pf__cmp{max-width:var(--maxw);margin:var(--s9) auto 0}
/* Full width is right for a landscape pair and far too tall for an upright
   one, so the upright frame is held to a portrait's width.

   The cap sits on the frame rather than on the carousel around it. Holding
   the whole carousel to 38rem pulled the control row in with it, which put
   the arrows against the edge of the photograph instead of the edge of the
   section. The row now runs the full measure and the controls range right
   against it, with the picture still centred inside.

   A definite width, not max-width. These are grid items now, and an auto
   inline margin stops a grid item stretching to its track, so max-width alone
   left the stage sized to its contents. Its slides are absolutely positioned,
   so those contents measure zero and the frame vanished entirely. */
/* `cmpx--tall` used to cap the frame at 38rem so an upright pair did not
   tower. Nothing adds that class any more: the stage is 16/9 and runs the
   full measure, matching the featured project above it. The rule is gone
   rather than left sitting here unreachable. See the note in proofSection()
   in js/app.js for the history. */
.pf__foot{max-width:var(--maxw);margin:var(--s7) auto 0}

/* drag comparison */
.cmp{position:relative;aspect-ratio:16/9;overflow:hidden;--pos:50%;touch-action:pan-y;user-select:none;
  background:var(--limestone-lt);border-radius:var(--r-lg);box-shadow:var(--edge)}
.cmp__lyr{position:absolute;inset:0}
/* An upright photograph covered into the wide frame keeps a band across its
   middle by default. --cmp-focus moves that band, so a room whose subject
   sits low is not cropped off at the knees. */
.cmp__lyr img{width:100%;height:100%;object-fit:cover;
  object-position:50% var(--cmp-focus,50%)}
.cmp__lyr--b{clip-path:inset(0 calc(100% - var(--pos)) 0 0)}
.cmp__tag{position:absolute;bottom:1.2rem;font-size:var(--t-xs);letter-spacing:.2em;
  text-transform:uppercase;color:var(--cream);z-index:3;pointer-events:none;
  padding:.55em 1em;border-radius:var(--r-pill);background:rgba(20,22,15,.42);
  -webkit-backdrop-filter:blur(12px) saturate(140%);backdrop-filter:blur(12px) saturate(140%);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.14)}
.cmp__tag--b{left:1.2rem}
.cmp__tag--a{right:1.2rem}
.cmp__handle{position:absolute;top:0;bottom:0;left:var(--pos);width:1px;background:var(--cream);
  z-index:4;pointer-events:none}
.cmp__grip{position:absolute;top:50%;left:50%;translate:-50% -50%;width:54px;height:54px;
  border-radius:50%;border:1px solid rgba(243,239,230,.65);background:rgba(20,22,15,.35)}
.cmp__grip::before,.cmp__grip::after{content:'';position:absolute;top:50%;width:7px;height:7px;
  border-top:1px solid var(--cream);border-right:1px solid var(--cream)}
.cmp__grip::before{left:15px;transform:translateY(-50%) rotate(-135deg)}
.cmp__grip::after{right:15px;transform:translateY(-50%) rotate(45deg)}

/* Placeholder plate. A fine hatch reads at any width, so a clipped plate
   never looks empty.

   KEEP THIS IN STEP WITH .rsv, further down the file. They are the same
   object: a picture the studio is holding space for. This one is absolutely
   positioned inside a figure and carries a dark variant for the before and
   after frames; .rsv fills its parent on the about spread and the portfolio
   tiles. Everything else about them, ground, mark, rule and label, matches on
   purpose, because two different treatments for a missing photograph is the
   sort of thing that makes a finished site look unfinished. */
.plate{position:absolute;inset:0;display:grid;place-items:center;
  background:
    repeating-linear-gradient(135deg,rgba(29,31,24,.05) 0 1px,transparent 1px 14px),
    linear-gradient(152deg,var(--limestone-lt),var(--limestone))}
.plate--dark{background:
    repeating-linear-gradient(135deg,rgba(243,239,230,.05) 0 1px,transparent 1px 14px),
    linear-gradient(152deg,var(--olive-800),var(--olive-950))}
/* the printed rule, inset from the trim, the way a reserved plate is marked */
.plate::after{content:'';position:absolute;inset:clamp(.7rem,1.6vw,1.15rem);
  border:1px solid rgba(125,95,58,.24);pointer-events:none}
.plate--dark::after{border-color:rgba(217,201,169,.2)}
.plate__m{width:clamp(56px,16%,104px);aspect-ratio:1/1;
  color:var(--bronze);opacity:.3}
.plate--dark .plate__m{color:var(--champagne);opacity:.26}
.plate__m svg{width:100%;height:100%;display:block}
/* 11px caps: 5.12 on the light ground at its worst pixel, 5.58 on the flat,
   and 5.58 for the cream on the dark variant. See the note on .rsv__t. */
.plate__t{position:absolute;left:0;right:0;bottom:clamp(1.4rem,3vw,2.1rem);
  text-align:center;padding:0 1.5rem;
  font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:#513B1F}
.plate--dark .plate__t{color:var(--on-dark-mute)}
.ph{display:inline-block;font-size:9px;letter-spacing:.18em;text-transform:uppercase;font-weight:500;
  padding:.4em .7em;border-radius:var(--r-pill);border:1px solid currentColor;
  vertical-align:middle;margin-left:.5em}

/* ============================================================ 3b · REVIEWS */
/* A rail that drifts across the full width of the page. Edge-to-edge with the
   ends feathered away, so quotes appear to come from off-screen rather than
   from a container. */
/* ------------------------------------------------------- 4b · REVIEWS RAIL */
/* The band is set on olive, and that one decision is most of this redesign.
   On limestone a cream card had about four points of value between it and the
   ground, so five of them in a row read as a single beige mass with some
   rounding in it, and no amount of shadow work rescues that. On a dark ground
   the same cards become paper on a dark table: the shadow has somewhere to
   fall, the champagne rim catches the light, and the quotes carry.

   It buys the homepage a change of key too. Selected work, about, why and
   process all sit on light grounds, so without this the middle of the page
   runs five sections in the same register.

   Three things make it read as live rather than merely animated:
     the rail drifts, and holds still only once the pointer settles on a card
     the cards nearest the middle come forward and the outer ones fall back
     an idle voice note shimmers along its own waveform until it is played */
.rv{position:relative;isolation:isolate;padding:var(--bay) 0;
  background:var(--olive-950);color:var(--cream);overflow:hidden}
/* light for the cards to sit in and a floor beneath them, so the band has
   depth of its own before anything has moved */
.rv::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(58% 46% at 50% 46%,rgba(203,176,125,.18),transparent 72%),
    radial-gradient(130% 62% at 50% 106%,rgba(0,0,0,.5),transparent 64%)}

.rv__head{max-width:var(--maxw);margin:0 auto var(--s8);padding:0 var(--gutter);
  display:grid;gap:var(--s4);justify-items:center;text-align:center}
/* the eyebrow and its hairline are coloured for the light grounds they
   usually sit on, and come out near 2.5:1 here */
.rv .eyebrow{color:var(--champagne)}

.rv__rail{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:pan-y;
  /* the cards dissolve at the edges instead of being cut off by them */
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 clamp(3rem,9vw,9rem),
    #000 calc(100% - clamp(3rem,9vw,9rem)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 clamp(3rem,9vw,9rem),
    #000 calc(100% - clamp(3rem,9vw,9rem)),transparent 100%)}
.rv__rail.grabbing{cursor:grabbing}
.rv__rail:focus-visible{outline:2px solid var(--champagne);outline-offset:6px}

.rv__track{display:flex;align-items:center;gap:clamp(1.25rem,2.4vw,2.25rem);
  width:max-content;padding-inline:var(--gutter);
  padding-block:clamp(2.25rem,4vw,3.5rem);will-change:transform}

/* ---- depth ---- */
/* The custom property is written by the rail every frame: 1 when the card is
   at the middle of the band, 0 at either edge. It defaults to 1, so with the
   script absent or motion reduced every card is simply full size.

   The alternating vertical drop the cards used to carry is gone. It was
   trying to make rhythm by offsetting a row of identical rectangles, and what
   it actually read as was a layout that had not quite settled. Depth does
   that job properly, and in the right axis. */
.rv__i{flex:none;width:clamp(290px,27vw,406px);--near:1;
  transform:scale(calc(.9 + var(--near) * .1));
  opacity:calc(.76 + var(--near) * .24);
  will-change:transform,opacity}

/* ---- the card ---- */
/* Paper: a ground that warms away from a top-left light, a champagne rim fine
   enough to read as an edge rather than a border, and a shadow with black in
   it, because the brown one that worked on limestone vanishes on olive. */
.rv__card{position:relative;isolation:isolate;overflow:hidden;
  display:grid;gap:clamp(1.3rem,2vw,1.8rem);
  padding:clamp(2.3rem,3.2vw,3rem) clamp(1.7rem,2.5vw,2.25rem) clamp(1.6rem,2.3vw,2.05rem);
  border-radius:var(--r-xl);
  background:
    radial-gradient(135% 95% at 0% 0%,rgba(255,255,255,.96),transparent 56%),
    linear-gradient(168deg,var(--ivory) 0%,#F1EADC 100%);
  box-shadow:
    inset 0 0 0 1px rgba(203,176,125,.5),
    inset 0 1px 0 rgba(255,255,255,.9),
    0 2px 5px rgba(0,0,0,.36),
    0 34px 62px -28px rgba(0,0,0,.9);
  transition:transform .55s var(--ease-out),box-shadow .55s var(--ease-out)}
/* the lift lives on the card and the depth scale on the item around it, so
   the two never write to the same transform and fight each other */
.rv__rail:not(.grabbing) .rv__card:hover{transform:translateY(-8px);
  box-shadow:
    inset 0 0 0 1px rgba(203,176,125,.82),
    inset 0 1px 0 rgba(255,255,255,1),
    0 3px 7px rgba(0,0,0,.42),
    0 48px 84px -30px rgba(0,0,0,1)}

/* The quotation mark set oversized as a watermark behind the opening line,
   rather than a small glyph sitting politely in the margin.

   It used to hang at -.3em, on the idea that cropping it against the top edge
   would read as a bleed. At this size a serif quotation mark carries its ink
   in the top third of its own line box, so what survived the crop was two
   tails, and two champagne blobs in the corner of every card read as a
   rendering fault rather than as typography. It now sits inside the card,
   with the opacity dropped far enough that the first line of the quote still
   clears AA over it by a wide margin. */
.rv__card::before{content:'\201C';position:absolute;z-index:-1;
  top:.01em;left:.05em;font-family:var(--serif);font-weight:400;
  font-size:clamp(5.5rem,7.6vw,8.6rem);line-height:1;
  color:var(--champagne);opacity:.3;pointer-events:none}

.rv__q{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.1rem,1.6vw,1.36rem);line-height:1.58;color:var(--ink);
  letter-spacing:-.004em;text-wrap:pretty}

/* ---- who said it ---- */
.rv__by{position:relative;display:flex;align-items:center;gap:var(--s4);
  padding-top:clamp(1.1rem,1.6vw,1.4rem)}
.rv__by::before{content:'';position:absolute;top:0;left:0;width:34px;height:1px;
  background:var(--bronze);opacity:.5}
/* the initial, taken from the name already on the card */
.rv__mono{flex:none;width:40px;height:40px;display:grid;place-items:center;
  border-radius:50%;font-family:var(--serif);font-weight:300;font-size:1.15rem;
  line-height:1;color:var(--bronze);
  background:radial-gradient(circle at 50% 30%,rgba(203,176,125,.34),rgba(203,176,125,.16));
  box-shadow:inset 0 0 0 1px rgba(125,95,58,.22)}
.rv__id{display:grid;gap:.2rem;min-width:0}
.rv__who{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--ink)}
.rv__meta{font-size:var(--t-sm);color:var(--ink-muted)}
/* One short word in the corner rather than a sentence on a pill under every
   quote. The rail shows five cards and then clones them, so that sentence was
   appearing fifteen times on one screen and was the loudest thing in the
   band. The full disclosure sits once, under the rail, where it reads. */
.rv__sample{position:absolute;top:0;right:0;
  font:500 10px/1 var(--sans);letter-spacing:.2em;text-transform:uppercase;
  /* a deeper umber than --bronze. At 10px on the tag's own tinted ground,
     and with the card dimmed to .76 at the edge of the rail, bronze lands at
     3.44:1. This carries 5.35:1 and still reads brown rather than grey. */
  color:#513B1F;padding:.62em 1em;
  border-radius:0 var(--r-xl) 0 var(--r-md);
  background:rgba(125,95,58,.12)}

/* ---- the card that holds a voice note ---- */
/* It is set in ink instead of paper. It is the one card on the rail you can
   do something with, and a strip of identical rectangles needs somewhere for
   the eye to land. The champagne rim and the bloom behind the band keep it
   reading as a card rather than a hole in the row. */
.rv__i--audio .rv__card{
  background:
    radial-gradient(135% 95% at 0% 0%,rgba(203,176,125,.2),transparent 58%),
    linear-gradient(168deg,#242718 0%,#14160F 100%);
  box-shadow:
    inset 0 0 0 1px rgba(203,176,125,.36),
    inset 0 1px 0 rgba(203,176,125,.18),
    0 2px 5px rgba(0,0,0,.4),
    0 38px 70px -28px rgba(0,0,0,1)}
.rv__rail:not(.grabbing) .rv__i--audio .rv__card:hover{
  box-shadow:
    inset 0 0 0 1px rgba(203,176,125,.62),
    inset 0 1px 0 rgba(203,176,125,.26),
    0 3px 7px rgba(0,0,0,.46),
    0 52px 92px -30px rgba(0,0,0,1)}
.rv__i--audio .rv__card::before{opacity:.26}
.rv__i--audio .rv__q{color:var(--cream)}
.rv__i--audio .rv__who{color:var(--cream)}
.rv__i--audio .rv__meta{color:var(--on-dark-soft)}
.rv__i--audio .rv__by::before{background:var(--champagne);opacity:.55}
.rv__i--audio .rv__mono{color:var(--champagne);
  background:radial-gradient(circle at 50% 30%,rgba(203,176,125,.3),rgba(203,176,125,.1));
  box-shadow:inset 0 0 0 1px rgba(203,176,125,.36)}
.rv__i--audio .rv__sample{color:var(--champagne);background:rgba(203,176,125,.16)}

/* ---- the voice note ---- */
/* A drawn waveform rather than a progress line. Two sets of bars sit on top of
   each other and the played one is clipped to the position, which is the same
   trick the before and after slider uses. */
.rv__kind{font:500 var(--t-xs)/1 var(--sans);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--bronze);
  display:inline-flex;align-items:center;gap:.55em}
.rv__i--audio .rv__kind{color:var(--champagne)}
.rv__kind::before{content:'';width:6px;height:6px;border-radius:50%;
  background:currentColor}
/* it breathes while the note is playing, so the card looks live */
.rv__i--audio .rvp.on ~ .rv__by,
.rv__card:has(.rvp.on) .rv__kind::before{animation:rvPulse 1.6s ease-in-out infinite}
@keyframes rvPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.8)}}

.rvp{--p:0%;display:flex;align-items:center;gap:var(--s4);
  padding:clamp(.7rem,1.1vw,.95rem) clamp(.8rem,1.2vw,1.05rem);
  border-radius:var(--r-md);
  background:rgba(203,176,125,.1);
  box-shadow:inset 0 0 0 1px rgba(203,176,125,.28)}
.rvp__b{flex:none;width:40px;height:40px;display:grid;place-items:center;
  border-radius:50%;color:var(--olive-950);background:var(--champagne);
  box-shadow:0 1px 3px rgba(0,0,0,.45);
  transition:background var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.rvp__b svg{width:17px;height:17px}
.rvp__b:hover{background:var(--cream)}
.rvp__b:active{transform:scale(.93)}
.rvp__pause{display:none}
.rvp.on .rvp__play{display:none}
.rvp.on .rvp__pause{display:block}

.rvp__track{position:relative;flex:1;min-width:0;height:30px;cursor:pointer}
.rvp__track:focus-visible{outline:2px solid var(--champagne);outline-offset:3px;
  border-radius:4px}
.rvp__w{position:absolute;inset:0;display:flex;align-items:center;
  gap:2px;pointer-events:none}
.rvp__w i{flex:1;min-width:0;border-radius:2px;background:currentColor;
  transition:height .3s var(--ease-out)}
.rvp__w--base{color:rgba(203,176,125,.32)}
.rvp__w--on{color:var(--champagne);
  clip-path:inset(0 calc(100% - var(--p)) 0 0)}
/* A third copy of the bars, masked to a narrow window that travels along the
   waveform while the note sits unplayed. It is the difference between a
   picture of a player and something with sound in it. It is decoration and
   not playback, so it goes the moment real progress takes over. */
.rvp__w--idle{color:var(--champagne);opacity:.5;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 50%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 50%,transparent);
  -webkit-mask-size:34% 100%;mask-size:34% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  animation:rvScan 4.4s var(--ease) infinite}
@keyframes rvScan{
  0%{-webkit-mask-position:-38% 0;mask-position:-38% 0}
  70%,100%{-webkit-mask-position:138% 0;mask-position:138% 0}}
.rvp.on .rvp__w--idle{display:none}
.rvp__t{flex:none;font-size:var(--t-xs);letter-spacing:.06em;color:var(--on-dark-soft);
  font-variant-numeric:tabular-nums;min-width:4ch;text-align:right}
.rvp.bad{opacity:.55}

/* ---- the foot ---- */
.rv__foot{max-width:var(--maxw);margin:var(--s7) auto 0;padding:0 var(--gutter);
  display:grid;gap:var(--s4);justify-items:center;text-align:center}
.rv__hint{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--on-dark-soft);display:inline-flex;align-items:center;gap:var(--s4)}
.rv__hint::before,.rv__hint::after{content:'';width:clamp(16px,2vw,26px);height:1px;
  background:currentColor;opacity:.6}
.rv__note{font-size:var(--t-sm);color:var(--on-dark-soft);font-style:italic;
  max-width:52ch}

/* a thumb needs more than the drawn control: the button grows, and the seek
   bar keeps its 30px of waveform but takes a 44px hit area around it */
@media (pointer:coarse){
  .rvp__b{width:46px;height:46px}
  .rvp__track{height:44px}
  .rvp__w{top:50%;bottom:auto;height:30px;transform:translateY(-50%)}
}

/* On a narrow screen a card already fills most of the band, so there is no
   room either side for the depth to be seen. Holding every card at full size
   there costs nothing and saves a compositor layer per card. */
@media (max-width:740px){
  .rv__i{transform:none;opacity:1;will-change:auto}
  /* One card fills the screen at this width, so the row height is set by the
     tallest card in the set, which is the one carrying the player. A short
     quote was then floating in the middle of a 420px band with about 150px
     of empty ground above and below it, and reading as a layout fault.
     Stretching the items gives every card the same height; the writing then
     sits as one optically centred block inside it. Pushing the attribution to
     the foot instead was worse: on a two line quote it opened a hole through
     the middle of the card. */
  .rv__track{align-items:stretch}
  .rv__i{display:grid}
  .rv__card{align-content:center}
}

@media (prefers-reduced-motion:reduce){
  .rv__card,.rv__card:hover{transition:none;transform:none}
  .rv__i{transform:none;opacity:1}
  .rv__kind::before{animation:none}
  .rvp__w--idle{display:none}
}


/* no animation, no cloning, the rail becomes a normal scroller */
@media (prefers-reduced-motion:reduce){
  .rv__rail{overflow-x:auto;cursor:auto;scroll-snap-type:x proximity}
  .rv__i{scroll-snap-align:center}
}

/* ======================================================= 4 · START (dark) */
.st{padding:var(--bay) var(--gutter);background:var(--olive-950);color:var(--cream)}
.st__head{max-width:var(--maxw);margin:0 auto var(--s8);display:grid;gap:var(--s4)}
.st__line{color:var(--on-dark-soft);max-width:34rem;text-wrap:pretty}
.st__grid{max-width:var(--maxw);margin-inline:auto;display:grid;border-top:1px solid var(--rule-dark)}

/* flex column so every option's CTA lands on the same baseline, however
   much detail sits above it */
.op{display:flex;flex-direction:column;gap:var(--s4);padding:var(--s6) 0;
  border-bottom:1px solid var(--rule-dark)}
.op__n{font:500 var(--t-xs)/1 var(--sans);letter-spacing:.28em;color:var(--champagne)}
.op__name{font-family:var(--serif);font-weight:300;font-size:clamp(1.6rem,3vw,2.2rem);line-height:1.05}
.op__meta{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--on-dark-mute)}
.op__price{font-family:var(--serif);font-weight:300;font-size:clamp(2rem,4.4vw,3rem);line-height:1;
  letter-spacing:-.02em;margin-top:calc(var(--s3) * -1)}
.op__line{font-size:var(--t-sm);color:var(--on-dark-soft)}
.op__inc{display:grid}
.op__inc li{padding:.6rem 0;border-bottom:1px solid var(--rule-dark-sf);
  font-family:var(--serif);font-size:1.1rem}
.op__rates{display:grid;gap:.5rem;padding-top:var(--s2)}
.op__rate{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4)}
.op__rate span{font-size:var(--t-xs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--on-dark-mute);max-width:11rem}
.op__rate b{font:400 1.18rem/1 var(--serif);color:var(--cream);flex:none}
.op__adds{display:grid;gap:.5rem;padding-top:var(--s4);border-top:1px solid var(--rule-dark-sf)}
.op__add{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;font-size:var(--t-sm)}
.op__add span{color:var(--on-dark-mute)}
.op__add b{font:400 1.05rem/1 var(--serif);color:var(--champagne)}
.op__add i{font-style:normal;font-size:var(--t-xs);color:var(--on-dark-mute)}
.op__foot{margin-top:auto;padding-top:var(--s5)}
.op__foot .cta--fill{background:var(--cream);color:var(--olive-950);width:100%;justify-content:center}
.op__foot .cta--fill::before{background:var(--champagne)}

.st__custom{max-width:var(--maxw);margin:var(--s8) auto 0;padding-top:var(--s6);
  border-top:1px solid var(--rule-dark);display:grid;gap:var(--s5);
  justify-items:center;text-align:center}
.st__ct{font-family:var(--serif);font-weight:300;font-size:clamp(1.4rem,2.8vw,2rem);line-height:1.1}
.st__cl{color:var(--on-dark-soft);font-size:var(--t-sm);max-width:36rem;
  margin:.6rem auto 0;text-wrap:pretty}

/* ============================================================== 5 · WHY */
.wy{padding:var(--bay) var(--gutter);background:var(--cream);display:grid;gap:var(--s8);
  max-width:calc(var(--maxw) + var(--gutter) * 2);margin-inline:auto}
.wy__body{display:grid;gap:var(--s4);align-content:center}
.frame{overflow:hidden;position:relative;aspect-ratio:3/4;
  border-radius:var(--r-lg);box-shadow:var(--edge)}
/* taller than the frame so the parallax shift never exposes an edge */
.frame img{width:100%;height:116%;object-fit:cover;position:absolute;inset:-8% 0 auto 0}
.wy__list{margin-top:var(--s5);display:grid;gap:var(--s6)}
/* ON A PHONE THESE TRAVEL SIDEWAYS RATHER THAN DOWN.
   Four points, 30 to 58 words each, cost 815px stacked. Two columns would
   cut the measure to 160px, which is unreadable for a paragraph. A rail
   keeps the full measure and costs the height of one. 82% rather than 100%
   so the next one shows at the edge and it is obvious there is more.
   The reviews already work this way; this is the page's own idiom. */
@media (max-width:740px){
  .wy__list{display:flex;gap:var(--s4);
    margin-inline:calc(var(--gutter) * -1);
    padding-inline:var(--gutter);
    scroll-padding-inline:var(--gutter);
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    scrollbar-width:none}
  .wy__list::-webkit-scrollbar{display:none}
  .wy__list li{flex:0 0 82%;scroll-snap-align:start}
}
.wy__list li{display:grid;gap:.4rem;padding-top:var(--s4);border-top:1px solid var(--rule)}
.wy__n{font:500 var(--t-xs)/1 var(--sans);letter-spacing:.28em;color:var(--bronze)}
.wy__name{font-family:var(--serif);font-weight:300;font-size:clamp(1.3rem,2.4vw,1.75rem);line-height:1.1}
.wy__line{color:var(--ink-muted);font-size:var(--t-sm);max-width:30rem}

/* ========================================================== 6 · PROCESS */
.pr{padding:var(--bay) var(--gutter);background:var(--limestone-lt)}
.pr__head{max-width:var(--maxw);margin:0 auto clamp(3rem,6vw,5.5rem);display:grid;gap:var(--s4)}
.pr__line{color:var(--ink-muted);max-width:34rem;margin-inline:auto;text-wrap:pretty}
.pr__foot{max-width:var(--maxw);margin:clamp(3.25rem,6vw,5.5rem) auto 0}
.pr__foot .cta--fill{padding-inline:2.2em;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),
             0 1px 2px rgba(92,78,54,.18),
             0 14px 30px -14px rgba(92,78,54,.5)}
.pr__foot .cta--fill:hover,.pr__foot .cta--fill:focus-visible{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),
             0 2px 5px rgba(92,78,54,.2),
             0 22px 44px -18px rgba(92,78,54,.55)}

/* ------------------------------------------------------------------ BOOK */
/* A book that actually turns. The leaf is hinged on the spine, has a front
   and a back, and swings through 180 degrees; app.js swaps the static pages
   underneath it at the moment it lands, so the join is invisible.

   THE SPREAD IS TWO-TONE, AND THAT IS THE WHOLE REDESIGN
   -----------------------------------------------------
   It used to be cream facing cream. Two pages of the same paper, the same
   value, with a soft fold drawn between them, which is why it read as two
   rounded rectangles rather than as a book: nothing on the spread had any
   more weight than anything else, and the left page was nine tenths empty.

   The verso is now an ink plate and the recto is paper, which is how an art
   monograph sets a chapter: a dark title page facing the text. It gives the
   spread a hierarchy, it gives the numeral somewhere to be gold, and it makes
   the turn itself worth watching, because now a page of light swings over and
   lands showing ink.

   Four things then do the work of making it read as paper rather than as a
   div on a hinge: the stack of page edges down the outer sides, the gutter
   shadow either side of the spine, the sheen that sweeps across a page as it
   catches the light on the way round, and a printed grain on both grounds. */

/* the tooth of the paper, tiled. It sits in the background stack rather than
   in an overlay so it never lies over the type and never touches contrast. */
.fb{max-width:var(--maxw);margin:0 auto;
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)' opacity='.16'/%3E%3C/svg%3E")}

.fb__book{position:relative;perspective:2600px;perspective-origin:50% 42%;
  border-radius:var(--r-xl)}
.fb__book:focus-visible{outline:2px solid var(--olive-700);outline-offset:10px}

/* the stack of page edges, which is most of why it reads as a book */
.fb__book::before,.fb__book::after{content:'';position:absolute;top:1.4%;bottom:1.4%;
  width:10px;border-radius:3px;z-index:0;pointer-events:none}
.fb__book::before{left:-9px;
  background:repeating-linear-gradient(to right,
    rgba(65,68,55,.16) 0 1px,rgba(255,255,255,.55) 1px 3px)}
.fb__book::after{right:-9px;
  background:repeating-linear-gradient(to left,
    rgba(65,68,55,.16) 0 1px,rgba(255,255,255,.55) 1px 3px)}

/* a deeper, warmer shadow than before: the book has to sit on the limestone
   rather than float a millimetre above it */
/* The floor was 30rem. Consultation, the longest stage, measured 571px once
   her writing went in, so the book grew by 36px the moment you turned onto
   it and shrank again on the way out. The floor now clears the tallest page,
   which holds all eight at one height. Below 900px the stage sets
   min-height:0 and the pages simply flow, so this only bites on the spread. */
.fb__stage{position:relative;display:grid;grid-template-columns:1fr 1fr;
  min-height:clamp(37rem,58vh,40rem);
  transform-style:preserve-3d;touch-action:pan-y;
  border-radius:var(--r-xl);
  background:var(--ivory);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.09),
             0 2px 6px rgba(20,22,15,.14),
             0 44px 86px -34px rgba(20,22,15,.72)}

.fb__side{position:relative;overflow:hidden;background:var(--ivory)}
.fb__side--l{border-radius:var(--r-xl) 0 0 var(--r-xl)}
.fb__side--r{border-radius:0 var(--r-xl) var(--r-xl) 0}

/* the gutter: paper curving down into the fold on both sides. The ink half is
   darkened rather than lightened, so the fold reads on both grounds. */
.fb__spine{position:absolute;top:0;bottom:0;left:50%;width:76px;
  transform:translateX(-50%);z-index:4;pointer-events:none;
  background:
    linear-gradient(to right,
      rgba(20,22,15,0) 0%,
      rgba(0,0,0,.24) 44%,
      rgba(0,0,0,.42) 49.4%,
      rgba(0,0,0,.5) 50%,
      rgba(20,22,15,.16) 50.6%,
      rgba(20,22,15,.085) 56%,
      rgba(20,22,15,0) 100%)}

/* ---- the verso: the chapter title page, in ink ---- */
/* There is no photography anywhere in the process, by request, so this page
   has to be carried by type alone. It gets the studio's mark, a printed rule
   inset from the trim the way a title page is ruled, and a numeral set large
   enough to be the picture. */
.fb__title{position:relative;display:grid;align-content:center;justify-items:center;
  height:100%;text-align:center;color:var(--cream);
  padding:clamp(3.4rem,6.5vw,5rem) clamp(1.6rem,4vw,3.5rem);
  background:
    var(--grain),
    radial-gradient(86% 64% at 50% 32%,rgba(203,176,125,.17),transparent 68%),
    linear-gradient(168deg,#262918 0%,#14160F 100%);
  background-size:160px 160px,auto,auto}
/* the printed rule, inset from the trim */
.fb__title::before{content:'';position:absolute;
  inset:clamp(.95rem,2.1vw,1.6rem);
  border:1px solid rgba(203,176,125,.2);pointer-events:none}
/* the running head, the way a book prints its title across the top of a
   chapter opening */
.fb__vh{position:absolute;top:clamp(2rem,3.8vw,3rem);left:50%;
  transform:translateX(-50%);white-space:nowrap;
  font-size:var(--t-xs);letter-spacing:.32em;text-transform:uppercase;
  /* .8 put it at 4.53 against the lightest part of the bloom; .9 carries
     5.26 and still reads as printed rather than stamped on */
  color:var(--champagne);opacity:.9}
/* The emblem is square, and at 40px across it was turning to mush anyway.
   It gets enough width here to be read as the house mark rather than as a
   smudge. */
.fb__mark{width:clamp(46px,5.2vw,62px);aspect-ratio:1/1;
  color:var(--champagne);opacity:.62;
  margin-bottom:clamp(1rem,2.2vw,1.6rem)}
.fb__mark svg{width:100%;height:100%;display:block}
.fb__lbl{font-size:var(--t-xs);letter-spacing:.32em;text-transform:uppercase;
  color:var(--champagne);opacity:.9;margin-bottom:clamp(.7rem,1.4vw,1rem)}
/* Lining, tabular figures with the tracking opened out. Cormorant's default
   figures are old style, and at this size with the old negative tracking the
   zero and the one ran together and the numeral read as the word OI. */
.fb__title .fb__n{font-size:clamp(4.6rem,10vw,8.4rem);line-height:.78;
  letter-spacing:.05em;margin-bottom:0;opacity:1;color:var(--champagne);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.ar__folio::before,.ar__folio::after{content:'';
  width:clamp(26px,6vw,54px);height:1px;background:var(--rule)}
.fb__rule{display:block;width:44px;height:1px;background:var(--champagne);
  opacity:.5;margin:clamp(1.3rem,2.6vw,2rem) 0}
.fb__title .fb__name{max-width:16ch;color:var(--cream)}
/* the placeholder marker leaves the title line and becomes a corner tag, so
   the chapter name is not permanently sharing its baseline with a label */
.fb__title .ph{position:absolute;right:clamp(1.6rem,3.2vw,2.5rem);
  bottom:clamp(1.6rem,3.2vw,2.5rem);margin:0;
  color:var(--champagne);opacity:.75}

/* ---- the recto: the writing, on paper ---- */
/* The head and the folio are pinned to the edges of the page, so the padding
   is what reserves room for them. It used to be one even value, which left
   the writing one pixel clear of the running head on a short stage and
   fifteen pixels UNDER it on the longest. Top and bottom are now set to clear
   each of them outright. */
.fb__page{position:relative;display:grid;align-content:center;height:100%;
  padding:clamp(2rem,4.5vw,3rem) clamp(1.6rem,4vw,3.5rem);
  background:var(--grain),var(--ivory);
  background-size:160px 160px,auto}
/* The running head, with the rule a book would set beside it, pinned to the
   head of the page. Sitting in the flow it was vertically centred with the
   text and floated in the middle of a very tall page, which is the one place
   a running head never goes. */
.fb__rh{position:absolute;top:clamp(2.1rem,4.2vw,3.4rem);
  left:clamp(1.6rem,4vw,3.5rem);right:clamp(1.6rem,4vw,3.5rem);margin:0;
  display:flex;align-items:center;gap:var(--s4);
  font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--bronze)}
.fb__rh::after{content:'';flex:1;height:1px;background:currentColor;opacity:.32}
.fb__n{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.6rem,5vw,4.2rem);line-height:.8;letter-spacing:-.04em;
  color:var(--bronze);margin-bottom:clamp(1.2rem,2.2vw,1.8rem)}
.fb__name{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.5rem,2.8vw,2.3rem);line-height:1.08;letter-spacing:-.015em;
  text-wrap:balance}
/* The recto used to carry one serif sentence. It now carries her opener, one
   or two paragraphs and, on the first two stages, her Come Prepared With
   list, so the writing is set as a proper column: a display line to open, and
   a smaller sans beneath it that can take sixty words without the page
   becoming a wall of large italic. */
/* 40ch left a 304px column inside a 500px page and ran the longest stage to
   six lines a paragraph, which is what pushed the book taller than the other
   seven. 46ch fills the page properly and takes a line off each paragraph. */
.fb__body{display:grid;gap:clamp(.8rem,1.5vw,1rem);max-width:46ch;
  align-content:center}
.fb__lead{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.15rem,2.2vw,1.62rem);line-height:1.24;letter-spacing:-.015em;
  color:var(--ink);text-wrap:balance}
.fb__p{font-size:clamp(.875rem,1.15vw,.95rem);line-height:1.64;
  color:var(--ink-soft);text-wrap:pretty}

/* Her list, set as a note between the paragraphs the way a book sets an aside:
   hairlines above and below rather than a tinted box, because the page is
   paper and a panel on it would read as a screen. */
.fb__prep{border-block:1px solid var(--rule);
  padding-block:clamp(.6rem,1.3vw,.8rem);
  display:grid;gap:clamp(.45rem,1vw,.58rem)}
.fb__prep-h{font:500 var(--t-xs)/1 var(--sans);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--bronze)}
.fb__prep-l{list-style:none;margin:0;padding:0;
  display:grid;gap:.32rem .9rem;font-size:clamp(.82rem,1.05vw,.9rem);
  line-height:1.5;color:var(--ink-soft)}
/* She wrote these as one run separated by bullets, not as a tall stack. Two
   columns is closer to how she set it down, and it keeps the longest stage
   from pushing the book taller than the other seven. */
@media (min-width:901px){
  .fb__prep-l{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* the head and the folio are pinned to the edges here, so the padding is
     what keeps the writing off them. One even value left the longest stage
     fifteen pixels UNDER the running head. */
  .fb__page{padding:clamp(4rem,7.5vw,5.6rem) clamp(1.6rem,4vw,3.5rem) clamp(3rem,5vw,3.9rem)}
}
.fb__prep-l li{position:relative;padding-left:.95rem}
.fb__prep-l li::before{content:'';position:absolute;left:0;top:.6em;
  width:4px;height:4px;border-radius:50%;background:var(--bronze);opacity:.62}
/* the folio moves to the outer corner, which is where a book sets it and
   where it stops looking like a caption floating under the column */
.fb__folio{position:absolute;left:auto;right:clamp(1.6rem,4vw,3.5rem);
  bottom:clamp(1.3rem,2.6vw,2.1rem);transform:none;
  font-size:var(--t-xs);letter-spacing:.3em;color:var(--ink-muted);opacity:.9;
  font-variant-numeric:tabular-nums}

/* the light that runs across a page as it turns. Flat until the leaf moves. */
.fb__sheen{position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(102deg,
    rgba(255,255,255,0) 38%,rgba(255,255,255,.45) 50%,rgba(255,255,255,0) 62%)}

/* ---- the turning leaf ---- */
.fb__leaf{position:absolute;top:0;left:50%;width:50%;height:100%;
  transform-style:preserve-3d;transform-origin:left center;
  z-index:6;display:none;will-change:transform}
.fb__leaf.on{display:block}
.fb__leaf.fwd{transform:rotateY(0deg)}
.fb__leaf.bwd{transform:rotateY(-180deg)}
/* 1.1s is long for an interface and exactly right for paper: a page has
   weight, and a quick flick reads as a slide rather than a turn */
.fb__leaf.turning{
  transition:transform 1.1s cubic-bezier(.56,.02,.28,1)}
.fb__leaf.fwd.turning{transform:rotateY(-180deg)}
.fb__leaf.bwd.turning{transform:rotateY(0deg)}

.fb__face{position:absolute;inset:0;overflow:hidden;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:var(--ivory)}
.fb__face--f{border-radius:0 var(--r-xl) var(--r-xl) 0;
  box-shadow:-1px 0 0 rgba(65,68,55,.1)}
.fb__face--b{transform:rotateY(180deg);
  border-radius:var(--r-xl) 0 0 var(--r-xl);
  box-shadow:1px 0 0 rgba(65,68,55,.1)}
.fb__face>*{width:100%;height:100%}

/* the leaf darkens as it stands up and lifts again as it lands, which is what
   a page does between you and the light */
.fb__face::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:rgba(20,22,15,.5);opacity:0}
.fb__leaf.turning .fb__face::after{
  animation:fbShade 1.1s cubic-bezier(.56,.02,.28,1) both}
@keyframes fbShade{
  0%   {opacity:0}
  30%  {opacity:.2}
  50%  {opacity:.32}
  72%  {opacity:.18}
  100% {opacity:0}
}
.fb__leaf.turning .fb__sheen{
  animation:fbSheen 1.1s cubic-bezier(.56,.02,.28,1) both}
/* a narrow band of light crossing the page, not a wash over it: the shade and
   the sheen peak together, so anything stronger bleaches the type */
@keyframes fbSheen{
  0%   {opacity:0;transform:translateX(-34%)}
  40%  {opacity:.26}
  62%  {opacity:.14}
  100% {opacity:0;transform:translateX(34%)}
}
/* and the page beneath is briefly in its shadow */
.fb__leaf.turning~.fb__spine{animation:fbGutter 1.1s ease both}
@keyframes fbGutter{0%{opacity:1}45%{opacity:.35}100%{opacity:1}}

/* ---- turning ---- */
.fb__bar{margin-top:var(--s6);display:flex;align-items:center;justify-content:center;
  gap:clamp(.75rem,2vw,1.5rem)}
.fb__nav{flex:none;width:48px;height:48px;display:grid;place-items:center;
  border-radius:50%;color:var(--ink-soft);background:var(--ivory);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.12),0 1px 2px rgba(20,22,15,.08);
  transition:background var(--d) var(--ease),color var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.fb__nav svg{width:20px;height:20px}
.fb__nav:hover{background:var(--olive-700);color:var(--cream)}
.fb__nav:active{transform:scale(.94)}

/* The index is numbered rather than eight anonymous dashes. The dashes told
   you how many stages there were and nothing else, and they gave the reader
   no reason to go to any particular one. */
.fb__dots{display:flex;align-items:center;gap:0;flex-wrap:wrap;justify-content:center}
.fb__d{position:relative;min-width:40px;height:44px;padding:0 .2rem;
  display:grid;place-items:center;
  font:500 var(--t-xs)/1 var(--sans);letter-spacing:.12em;
  color:var(--ink-muted);font-variant-numeric:tabular-nums;
  transition:color var(--d) var(--ease)}
.fb__d::after{content:'';position:absolute;left:50%;bottom:9px;
  transform:translateX(-50%);width:0;height:1px;background:#5E4526;
  transition:width var(--d) var(--ease)}
.fb__d:hover{color:var(--ink)}
/* deeper than --bronze, which lands at 3.76:1 on limestone at this size */
.fb__d.on{color:#5E4526}
.fb__d.on::after{width:20px}
@media (pointer:coarse){ .fb__d{min-width:44px} }

/* ---- stacked, where there is no spine to hinge on ---- */
@media (max-width:900px){
  .fb__book{perspective:none}
  .fb__book::before,.fb__book::after{display:none}
  .fb__stage{grid-template-columns:1fr;grid-template-rows:auto auto;
    min-height:0;transform-style:flat;
    transition:opacity .22s var(--ease),transform .22s var(--ease)}
  /* THE PAGE TURN ON A PHONE.
     No spread, no spine, so no half sheet to hinge. One card, turning:
     it lifts away on the edge being left behind and the next arrives
     from the other side. The perspective is inside the transform rather
     than on the parent, so nothing else in the book has to become a 3D
     context to get it. */
  .fb__stage{backface-visibility:hidden}
  .fb__stage.x,.fb__stage.in{will-change:transform,opacity}
  /* the plain fade is what reduced motion still gets */
  .fb__stage.x{opacity:0;transform:translateY(8px)}
  .fb__stage.x--f,.fb__stage.x--b,
  .fb__stage.in--f,.fb__stage.in--b{opacity:1;transform:none}
  .fb__stage.x--f{transform-origin:left center;
    animation:fbOutF .24s var(--ease-soft) both;
    box-shadow:-20px 0 44px -20px rgba(18,20,14,.5)}
  .fb__stage.x--b{transform-origin:right center;
    animation:fbOutB .24s var(--ease-soft) both;
    box-shadow:20px 0 44px -20px rgba(18,20,14,.5)}
  .fb__stage.in--f{transform-origin:right center;
    animation:fbInF .38s var(--ease-out) both;
    box-shadow:20px 0 44px -20px rgba(18,20,14,.4)}
  .fb__stage.in--b{transform-origin:left center;
    animation:fbInB .38s var(--ease-out) both;
    box-shadow:-20px 0 44px -20px rgba(18,20,14,.4)}
  .fb__side--l,.fb__side--r{border-radius:0}
  .fb__side--l{border-radius:var(--r-xl) var(--r-xl) 0 0}
  .fb__side--r{border-radius:0 0 var(--r-xl) var(--r-xl)}
  .fb__title{padding-block:clamp(3.4rem,11vw,4.6rem)}
  /* no room to pin anything on a short page: stacked, the card is a third of
     its desktop height and the corner tag was landing on the descenders of
     the stage name */
  .fb__rh{position:static;margin-bottom:clamp(1.3rem,4vw,2rem)}
  .fb__title .ph{position:static;margin:var(--s5) 0 0}
  .fb__leaf,.fb__spine{display:none}
  .fb__folio{position:static;transform:none;margin-top:var(--s5);text-align:right}
}

@media (prefers-reduced-motion:reduce){
  .fb__leaf.turning{transition:none}
  .fb__leaf.turning .fb__face::after,
  .fb__leaf.turning .fb__sheen,
  .fb__leaf.turning~.fb__spine{animation:none}
}

/* =========================================================== 7 · CLOSING */
.fin{position:relative;min-height:66svh;display:grid;align-items:center;isolation:isolate;
  overflow:hidden;padding:clamp(4rem,8vw,7rem) var(--gutter);color:var(--cream)}
.fin__media{position:absolute;inset:0;z-index:-2}
.fin__media img{width:100%;height:100%;object-fit:cover}
/* centred content, so the scrim pools evenly rather than favouring one side */
.fin__veil{position:absolute;inset:0;z-index:-1;background:
  radial-gradient(118% 82% at 50% 48%,rgba(20,22,15,.68),rgba(20,22,15,.91) 76%)}
.fin__in{max-width:52rem;margin-inline:auto;width:100%;display:grid;gap:var(--s4);
  justify-items:center;text-align:center}
.fin__h{font-family:var(--serif);font-weight:300;font-size:clamp(2.3rem,6.6vw,5.2rem);
  line-height:.98;letter-spacing:-.025em}
.fin__h span{display:block}
.fin__h span:nth-child(2){font-style:italic;color:var(--champagne)}
.fin__line{color:var(--on-dark-soft);font-size:var(--t-lede);max-width:26rem}
.fin__acts{display:flex;align-items:center;justify-content:center;gap:var(--s5);
  flex-wrap:wrap;margin-top:var(--s3)}
.fin__acts .cta--fill{background:var(--cream);color:var(--olive-950)}
.fin__acts .cta--fill::before{background:var(--champagne)}

/* -------------------------------------------------------------- NEWSLETTER */
/* A hairline, a label and one underlined field. No box, no panel. */
/* A single rounded field with the action sitting inside it, kept deliberately
   tight: this is the quietest thing in the section and should not eat the
   height the booking CTAs above it have earned. */
/* The rule above it was separating the newsletter from the two buttons that
   used to sit there. With those gone it would be a line under nothing, so it
   goes too and the spacing opens up instead. */
.nl{width:100%;max-width:25rem;margin-top:var(--s7);display:grid;gap:var(--s1);
  justify-items:center}
.nl__l{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  font-weight:500;color:var(--champagne)}
.nl__t{font-size:var(--t-sm);color:var(--on-dark-soft);text-align:center}
.nl__row{margin-top:var(--s3);width:100%;display:flex;align-items:center;gap:var(--s2);
  padding:.32rem .32rem .32rem 1.2rem;border-radius:var(--r-pill);
  /* this hairline is the only thing marking the edge of the control, so it has
     to clear 3:1 against the photograph behind it */
  border:1px solid rgba(243,239,230,.45);background:rgba(243,239,230,.08);
  transition:border-color var(--d) var(--ease),background var(--d) var(--ease)}
.nl__row:focus-within{border-color:var(--champagne);background:rgba(243,239,230,.13)}
.nl__row input{flex:1;min-width:0;background:none;border:0;padding:.6rem 0;
  color:var(--cream);font-size:.9rem;font-weight:300;letter-spacing:.02em}
.nl__row input:focus{outline:none}
.nl__row input::placeholder{color:rgba(243,239,230,.6);letter-spacing:.02em}
/* ghost by default so it does not compete with the booking button above,
   and it fills on hover */
.nl__go{flex:none;padding:.72em 1.3em;border-radius:var(--r-pill);
  color:var(--cream);background:rgba(243,239,230,.15);
  font:500 .8rem/1 var(--sans);letter-spacing:.006em;
  transition:background var(--d) var(--ease),color var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.nl__go:hover,.nl__go:focus-visible{background:var(--cream);color:var(--olive-950)}
.nl__go:active{transform:scale(.97)}
/* no reserved strip: nothing follows the newsletter, so the message can simply
   appear rather than holding a blank line open all the time */
.nl__msg{font-size:var(--t-sm);color:var(--champagne);min-height:0}
.nl__msg:not(:empty){margin-top:var(--s2)}
.nl.bad .nl__row{border-color:#C4876B}
.nl.bad .nl__msg{color:#DBA88C}
.nl.done .nl__row{opacity:.32;pointer-events:none}

/* =============================================================== 8 · FAQ */
.faq{padding:var(--bay) var(--gutter);background:var(--ivory)}
.faq__head{max-width:var(--maxw);margin:0 auto var(--s6);display:grid;gap:var(--s4)}
/* Each question is its own card rather than a row in a ruled list. Closed, it
   sits a shade deeper than the section ground; open, it rises to the lighter
   tone and takes a shadow, so opening one reads as the card lifting off the
   page rather than a panel unfolding below a line. */
.faq__list{max-width:min(var(--maxw),58rem);margin-inline:auto;display:grid;gap:var(--s3)}
.fq{--pad:clamp(1.15rem,2vw,1.75rem);--col:var(--s4);
  border-radius:var(--r-xl);background:var(--cream);
  box-shadow:inset 0 0 0 1px transparent;
  transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease),
             transform var(--d) var(--ease-out)}
.fq:hover{background:#EFEADF}
.fq.open{background:var(--ivory);transform:translateY(-1px);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.10),var(--sh-md)}

.fq__q{width:100%;display:grid;grid-template-columns:1fr auto;
  align-items:center;gap:var(--col);
  padding:clamp(1.1rem,1.9vw,1.5rem) var(--pad);text-align:left}
.fq__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.08rem,1.9vw,1.45rem);line-height:1.32;letter-spacing:-.008em;
  text-wrap:pretty;transition:color var(--d) var(--ease)}
.fq:hover .fq__t{color:var(--bronze)}
.fq.open .fq__t{color:var(--ink)}

/* the plus turns through 135 degrees into a cross and fills as it goes */
.fq__s{flex:none;position:relative;display:grid;place-items:center;
  width:clamp(30px,3.1vw,38px);aspect-ratio:1;border-radius:50%;
  background:rgba(65,68,55,.07);color:var(--ink-soft);
  transition:transform var(--d) var(--ease-out),background var(--d) var(--ease),
             color var(--d) var(--ease)}
.fq__s::before,.fq__s::after{content:'';position:absolute;
  width:clamp(11px,1.1vw,13px);height:1.5px;border-radius:1px;background:currentColor}
.fq__s::after{transform:rotate(90deg)}
.fq.open .fq__s{transform:rotate(135deg);background:var(--olive-700);color:var(--cream)}

.fq__a{overflow:hidden;height:0;transition:height var(--d) var(--ease-out)}
.fq__a-in{padding:0 var(--pad) clamp(1.25rem,2vw,1.65rem);
  max-width:52rem;color:var(--ink-soft);font-size:.95rem;line-height:1.66;
  text-wrap:pretty}

.faq__more{max-width:min(var(--maxw),58rem);margin:var(--s7) auto 0;text-align:center;
  font-size:var(--t-sm);color:var(--ink-muted)}
.faq__more-a{font:inherit;color:var(--bronze);position:relative;padding-bottom:2px}
.faq__more-a::after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;
  background:currentColor;opacity:.4;transition:opacity var(--d) var(--ease)}
.faq__more-a:hover::after,.faq__more-a:focus-visible::after{opacity:1}

@media (max-width:740px){
  .fq{--col:var(--s3)}
}

/* ------------------------------------------------- BEFORE / AFTER CAROUSEL */
/* The slider itself is unchanged; this only steps between several of them.
   Every transformation is in the DOM at once and cross-faded, so moving
   between them never reloads and each slider keeps the position it was
   dragged to. Only the visible one takes pointer events, or a hidden slide
   would swallow drags meant for the one on top. */
.cmpx{position:relative;display:grid;gap:var(--s5)}
.cmpx:focus-visible{outline:2px solid var(--olive-700);outline-offset:8px;
  border-radius:var(--r-lg)}
/* No width cap. It existed to stop a 4/3 frame running 972px tall; at 16/9
   the frame is 729px on a 1440 screen, the same as the featured project it
   is matching, and fits the window without help. */
.cmpx__stage{position:relative;aspect-ratio:var(--cmpx-ar,16/9);border-radius:var(--r-lg);
  overflow:hidden;background:var(--limestone-lt)}
.cmpx__s{position:absolute;inset:0;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .5s var(--ease-out),visibility 0s linear .5s}
.cmpx__s.on{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s}
.cmpx__s .cmp{position:absolute;inset:0;aspect-ratio:auto;border-radius:0;height:100%}

/* The controls sit above the frame, ranged right, rather than under it.
   Below a tall photograph they were past the fold on most screens, so people
   met the first transformation and never learned there were three. Above the
   frame the count is read before the picture, and it says how many there are
   before anyone decides to scroll on.

   They are filled rather than outlined for the same reason: on ivory, a cream
   disc with a hairline ring reads as decoration, and a control nobody
   recognises as a control is a control nobody presses. */
.cmpx__bar{display:flex;align-items:center;justify-content:space-between;
  gap:var(--s4) var(--s6);flex-wrap:wrap}
.cmpx__hint{font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-muted);margin:0}
/* auto rather than space-between alone, so the controls stay hard right even
   on the wrap, where the hint is no longer there to push them */
.cmpx__ctrl{display:flex;align-items:center;gap:var(--s4);margin-left:auto}
.cmpx__nav{width:48px;height:48px;display:grid;place-items:center;border-radius:50%;
  color:var(--cream);background:var(--olive-700);
  box-shadow:0 1px 2px rgba(20,22,15,.18),0 12px 24px -14px rgba(20,22,15,.65);
  transition:background var(--d) var(--ease),color var(--d) var(--ease),
             transform var(--d-fast) var(--ease),box-shadow var(--d) var(--ease)}
.cmpx__nav svg{width:20px;height:20px}
.cmpx__nav:hover{background:var(--olive-950);transform:translateY(-2px);
  box-shadow:0 2px 5px rgba(20,22,15,.22),0 18px 32px -16px rgba(20,22,15,.75)}
.cmpx__nav:active{transform:scale(.94)}
.cmpx__count{font:500 var(--t-xs)/1 var(--sans);letter-spacing:.2em;
  color:var(--ink-muted);font-variant-numeric:tabular-nums;min-width:5.5em;
  text-align:center}

.cmpx__cap{display:grid;gap:.35rem;justify-items:center;text-align:center}
.cmpx__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.15rem,2vw,1.5rem);line-height:1.15}
.cmpx__m{font-size:var(--t-sm);color:var(--ink-muted)}
.cmpx__n{margin-top:.35rem;font-size:var(--t-sm);color:var(--ink-muted);font-style:italic;
  max-width:34rem}

@media (max-width:740px){
  .cmpx__stage{aspect-ratio:4/5}
  .cmpx__bar{gap:var(--s4)}
}

/* ------------------------------------------------------------- PORTFOLIO */
/* The page opens on a full-bleed rotator rather than a grid, so arriving here
   reads as an introduction to the work rather than a contact sheet. Slides
   cross-fade and hold a slow scale, which is enough movement to feel alive
   without turning into a slideshow that demands attention. */
.pb{position:relative;isolation:isolate;overflow:hidden;
  /* 66vh, the same opening height the about banner uses, so arriving on
     either page feels like arriving on the same site */
  min-height:clamp(26rem,66vh,42rem);
  display:grid;place-items:center;
  padding:clamp(8rem,14vh,11rem) var(--gutter) clamp(4rem,8vh,6rem);
  color:var(--cream);text-align:center;background:var(--olive-950)}
.pb__stage{position:absolute;inset:0;z-index:-2}
.pb__s{position:absolute;inset:0;opacity:0;transform:scale(1.06);
  transition:opacity 1.1s var(--ease-out),transform 6s var(--ease-out)}
.pb__s.on{opacity:1;transform:scale(1)}
.pb__s>picture{width:100%;height:100%}
.pb__s img,.pb__s video{width:100%;height:100%;object-fit:cover;display:block}
@media (prefers-reduced-motion:reduce){
  .pb__s{transition:opacity .2s linear;transform:none}
  .pb__s.on{transform:none}
}
.pb__veil{position:absolute;inset:0;z-index:-1;background:
  radial-gradient(120% 120% at 50% 50%,rgba(18,20,14,0),rgba(18,20,14,.4)),
  linear-gradient(rgba(18,20,14,.56),rgba(18,20,14,.56))}
.pb__in{position:relative;max-width:44rem;display:grid;gap:var(--s4);justify-items:center}
.pb .eyebrow{color:var(--champagne)}
.pb__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.8rem,8vw,6rem);line-height:.96;letter-spacing:var(--track-mega)}
.pb__h em{color:var(--champagne)}
.pb__line{color:var(--cream);max-width:30rem;text-wrap:pretty}
.pb__h,.pb__line{text-shadow:0 1px 2px rgba(18,20,14,.4),0 6px 40px rgba(18,20,14,.6)}

.pb__dots{position:absolute;left:0;right:0;bottom:clamp(1.6rem,4vh,2.6rem);
  display:flex;justify-content:center;gap:.55rem;z-index:1}
.pb__d{width:44px;height:44px;display:grid;place-items:center;border-radius:50%}
.pb__d::after{content:'';width:7px;height:7px;border-radius:50%;
  background:rgba(243,239,230,.45);
  transition:background var(--d) var(--ease),transform var(--d) var(--ease)}
.pb__d:hover::after{background:rgba(243,239,230,.8)}
.pb__d.on::after{background:var(--champagne);transform:scale(1.35)}

/* ---- the tiles ---- */
.pg{padding:var(--bay) var(--gutter);background:var(--ivory)}
.pg__notice{max-width:var(--maxw);margin:0 auto var(--s7);text-align:center;
  font-size:var(--t-sm);color:var(--ink-muted);font-style:italic}
.pg__notice code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-style:normal;
  font-size:.92em;background:var(--cream);padding:.15em .45em;border-radius:var(--r-xs)}
.pg__grid{max-width:var(--maxw);margin-inline:auto;display:grid;gap:var(--s6)}
@media (min-width:701px){.pg__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1101px){.pg__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}

.pt{display:grid;gap:var(--s4)}
.pt__fig{position:relative;overflow:hidden;border-radius:var(--r-lg);aspect-ratio:4/3;
  background:var(--limestone-lt);box-shadow:var(--edge),var(--sh-sm);
  transition:box-shadow var(--d) var(--ease)}
.pt__fig>picture{width:100%;height:100%}
.pt__fig img{width:100%;height:100%;object-fit:cover;
  transform:scale(1);transition:transform 1.2s var(--ease-out)}
.pt:not(.pt--held):hover .pt__fig img,.pt:focus-visible .pt__fig img{transform:scale(1.045)}
.pt:not(.pt--held):hover .pt__fig{box-shadow:var(--edge),var(--sh-md)}
.pt__name{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.25rem,2.1vw,1.6rem);line-height:1.12;letter-spacing:-.01em;
  transition:color var(--d) var(--ease)}
.pt:not(.pt--held):hover .pt__name{color:var(--bronze)}
.pt__meta{margin-top:.3rem;font-size:var(--t-sm);color:var(--ink-muted)}

/* ---- the two bands ---- */
/* The client's list arrives in two groups, finished work and work still on
   site, and the page keeps that division rather than running seventeen tiles
   together. A rule, a label and a count: the same device a contents page uses,
   which is the right register for a portfolio and costs almost no ink. */
.pg__band{grid-column:1/-1;display:flex;align-items:center;
  gap:clamp(.9rem,2.2vw,1.5rem)}
.pg__band:not(:first-child){margin-top:var(--s5)}
.pg__band-t{order:0;font:500 var(--t-xs)/1 var(--sans);
  letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-soft)}
.pg__band::after{content:'';order:1;flex:1;height:1px;
  background:linear-gradient(90deg,rgba(125,95,58,.34),rgba(125,95,58,.05))}
/* lining figures: Cormorant sets oldstyle by default, and a tracked-in "10"
   runs the one into the nought */
.pg__band-n{order:2;font-family:var(--serif);font-weight:300;font-size:1.25rem;
  line-height:1;font-variant-numeric:lining-nums tabular-nums;
  letter-spacing:.02em;color:var(--bronze)}

/* ---- a project with no photography yet ---- */
/* It is a plate, not a picture, and not a link either. Nothing about it should
   invite a click that would open on an empty page. */
.pt--held{cursor:default}
.pt__fig>.rsv{position:absolute;inset:0}
/* The work still on site is marked by the printed rule turning dashed, which
   is how a provisional plate has always been marked, and by the plate's own
   wording. Deepening the ground was the first idea and it was wrong: it drove
   the label down to 4.01 against its own background, under the 4.5 it needs at
   11px. A dashed rule says the same thing and costs no contrast. */
.pt--soon .rsv::after{border-style:dashed}
.pt--soon .rsv__m{opacity:.22}

/* ---- the header with nothing to rotate ---- */
/* No photography has been supplied for the rotator yet. Rather than an empty
   black band, the emblem is held very faintly behind the title, and the veil
   stops darkening a ground that is already the darkest olive on the site. */
.pb--bare .pb__veil{background:
  radial-gradient(85% 85% at 50% 42%,rgba(243,239,230,.055),rgba(18,20,14,0) 72%)}
.pb--bare::before{content:'';position:absolute;z-index:-1;
  left:50%;top:50%;translate:-50% -50%;
  width:min(31rem,62vw);aspect-ratio:1/1;
  background:var(--cream);opacity:.05;pointer-events:none;
  -webkit-mask:url(../assets/img/mark.png) center/contain no-repeat;
          mask:url(../assets/img/mark.png) center/contain no-repeat;
  /* mark.png is opaque greyscale, white line on black, with no alpha channel,
     which is what lets the SVG symbol mask it by luminance. A CSS mask reads
     ALPHA by default, and an opaque file is alpha 1 everywhere, so the square
     came through whole. These two lines switch it to luminance, and they sit
     after the shorthand because the shorthand resets mask-mode. */
  -webkit-mask-source-type:luminance;
          mask-mode:luminance}

/* --------------------------------------------------------- ONE PROJECT */
.pj{padding:calc(var(--bay) + 4rem) var(--gutter) var(--bay);background:var(--ivory)}
.pj__head{max-width:var(--maxw);margin:0 auto var(--s8)}
.pj__back{display:inline-flex;align-items:center;gap:.6em;
  font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--ink-muted);padding:.6rem 0;transition:color var(--d) var(--ease)}
.pj__back:hover{color:var(--bronze)}
.pj__back-i{width:18px;height:18px;flex:none;transition:transform var(--d) var(--ease-out)}
.pj__back:hover .pj__back-i{transform:translateX(-4px)}
.pj__meta{margin-top:var(--s6);font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--bronze)}
.pj__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.2rem,5.4vw,4rem);line-height:1.02;letter-spacing:-.022em;
  margin-top:var(--s3)}
.pj__body{max-width:var(--maxw);margin-inline:auto}
.pj__none{color:var(--ink-muted)}
.pj__none a{color:var(--bronze);text-decoration:underline}

.pj__b{margin-top:var(--bay)}
.pj__b:first-child{margin-top:0}
.pj__bt{font:500 var(--t-xs)/1 var(--sans);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-soft);
  padding-bottom:var(--s4);border-bottom:1px solid var(--rule);
  margin-bottom:var(--s6);position:relative}
.pj__bt::after{content:'';position:absolute;left:0;bottom:-1px;width:30px;height:1px;
  background:var(--bronze)}
.pj__story{max-width:40rem;color:var(--ink-muted);line-height:1.7;text-wrap:pretty}
.pj__hint{margin-top:var(--s4);font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-muted);text-align:center}
.pj__video{border-radius:var(--r-xl);overflow:hidden;box-shadow:var(--edge),var(--sh-md);
  background:var(--limestone-lt)}
.pj__video video{width:100%;height:auto;display:block}

.pj__grid{display:grid;gap:var(--s5)}
@media (min-width:901px){
  .pj__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pj__f--wide{grid-column:1 / -1}
}
.pj__f{overflow:hidden;border-radius:var(--r-lg);aspect-ratio:4/3;
  background:var(--limestone-lt);box-shadow:var(--edge),var(--sh-sm)}
.pj__f--wide{aspect-ratio:16/9}
.pj__f>picture{width:100%;height:100%}
.pj__f img{width:100%;height:100%;object-fit:cover}

/* a real project reached by its URL before anything has been published on it */
.pj__held{display:grid;gap:var(--s6);justify-items:center;text-align:center}
/* a held plate is a note, not a gallery. Run full width at 16/9 and it is a
   grey slab the size of a photograph that does not exist yet. */
.pj__held>.rsv{width:min(100%,26rem);aspect-ratio:4/3;border-radius:var(--r-lg);
  overflow:hidden;box-shadow:var(--edge),var(--sh-sm)}
.pj__soon{color:var(--ink-muted);max-width:34rem;text-wrap:pretty}

.pj__next{margin-top:var(--bay);padding-top:var(--s7);border-top:1px solid var(--rule);
  text-align:center}
.pj__next a{display:inline-grid;gap:.4rem;padding:.6rem 0}
.pj__next-l{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--ink-muted)}
.pj__next-n{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.5rem,3vw,2.2rem);line-height:1.1;letter-spacing:-.015em;
  transition:color var(--d) var(--ease)}
.pj__next a:hover .pj__next-n{color:var(--bronze)}

/* the homepage now offers the portfolio first and Instagram second */
.pf__foot{flex-wrap:wrap;gap:var(--s4)}

/* -------------------------------------------------------- SERVICES BANNER */
/* The services page opens the way the homepage does: a full-bleed photograph
   with the type over it, so arriving here does not feel like dropping into a
   plain document. The scrim is even rather than pooled, because this type is
   centred and the photograph is bright right across the frame. */
.spb{position:relative;isolation:isolate;overflow:hidden;
  min-height:clamp(24rem,52vh,34rem);
  display:grid;place-items:center;
  padding:clamp(8rem,14vh,11rem) var(--gutter) clamp(3.5rem,7vh,5rem);
  color:var(--cream);text-align:center}
.spb__media{position:absolute;inset:0;z-index:-2;width:100%;height:100%}
.spb__media img{width:100%;height:100%;object-fit:cover}
/* an even wash for the centred type, plus a vignette so the edges stay rich */
/* 64%, because the tub fills the middle of the frame and reads close to
   white: at 52% the champagne italic came out at 2.69:1 and the supporting
   line at 3.06:1. The photograph still shows through clearly. */
.spb__veil{position:absolute;inset:0;z-index:-1;background:
  radial-gradient(120% 120% at 50% 50%,rgba(18,20,14,0),rgba(18,20,14,.34)),
  linear-gradient(rgba(18,20,14,.64),rgba(18,20,14,.64))}

.spb__in{position:relative;max-width:44rem;display:grid;gap:var(--s4);
  justify-items:center}
.spb .eyebrow{color:var(--champagne)}
.spb .eyebrow::after{background:currentColor}
.spb__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.6rem,7vw,5.2rem);line-height:.98;letter-spacing:var(--track-mega)}
.spb__h em{color:var(--champagne)}
.spb__line{color:var(--cream);max-width:32rem;text-wrap:pretty}
.spb__act{margin-top:var(--s3)}
/* the same halo the hero type carries, for the same reason */
.spb__h,.spb__line{text-shadow:0 1px 2px rgba(18,20,14,.4),0 6px 40px rgba(18,20,14,.6)}

/* the page body starts below the banner and needs no top run-up of its own */
.sp{padding-top:var(--bay)}

/* ---------------------------------------------------------- SERVICES PAGE */
/* Five services down one page is a long read, so it is set as five chapters
   rather than five stacked cards: an oversized numeral opening each one, the
   photograph holding its place while the detail scrolls past it, and a
   specification list set against hairlines instead of bullets.

   The index at the top sticks under the navigation and marks where you are,
   which is the difference between five services and one endless column. */
.sp{padding:0 0 var(--bay);background:var(--ivory);position:relative}

/* ---- the sticky index ---- */
/* A shelf of frosted glass rather than a plain translucent strip: a highlight
   along its top edge, a warm hairline along the bottom, and just enough shadow
   under it that the page reads as passing beneath it. */
/* THE SHELF HAS TO BE OPAQUE.
   .985 still let the page text ghost through on a bright image behind it,
   so the shelf reads as a window. Solid cream, no backdrop blur: nothing
   underneath has anywhere to show through from. The bottom padding also
   stays non-zero so type passing below cannot touch the rail. */
.sp__jump{position:sticky;top:clamp(4.6rem,9vh,6.4rem);z-index:20;
  padding:var(--s3) var(--gutter) var(--s2);
  background:var(--cream);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
             0 1px 0 rgba(125,95,58,.18),
             0 14px 26px -22px rgba(20,22,15,.55)}
/* five full service names never fit one line, so the rail scrolls. The fade
   at each end is the only thing that says so, and js keeps the active item
   inside the visible part as you read down the page. The fade is deeper than
   it was, because at 24px the last name was being cut off mid-letter and
   reading as a layout that had run out of room rather than as a rail. */
/* THE ENTRIES ARE NEVER SLICED ANY MORE.
   The fade used to run from both ends, so whatever entry happened to sit at
   the left edge was cut through mid word: "01" rendered as a stump and the
   name beside it began halfway. Read quickly that does not look like a rail
   that scrolls, it looks like the page's words running through the shelf,
   which is exactly what the client reported twice.

   Two changes. The fade is on the right only, so the entry you are reading
   always starts whole at the left edge. And the rail snaps, so scrolling can
   only ever come to rest with an entry flush against that edge rather than
   halfway through one. */
.sx__ix{position:relative;max-width:var(--maxw);margin:0 auto;
  display:flex;gap:0;
  overflow-x:auto;scrollbar-width:none;scroll-behavior:smooth;
  scroll-snap-type:x proximity;
  -webkit-mask-image:linear-gradient(to right,#000 0,
    #000 calc(100% - 56px),transparent 100%);
  mask-image:linear-gradient(to right,#000 0,
    #000 calc(100% - 56px),transparent 100%)}
.sx__ix::-webkit-scrollbar{display:none}

/* No pill. A filled lozenge sitting among plain text made the current service
   the heaviest object on the page, and it gave the rail a lumpy rhythm,
   because the one entry you were meant to read was suddenly a different shape
   from all of its neighbours. An index in a book marks its place with a rule,
   so this one does too, and the rule travels. */
.sx__ixa{position:relative;flex:0 0 auto;display:flex;align-items:baseline;
  scroll-snap-align:start;
  gap:.7em;min-height:46px;
  padding:.75rem clamp(.9rem,1.6vw,1.45rem) .85rem;
  white-space:nowrap;transition:color var(--d) var(--ease)}
/* the hairline between entries, which is what gives a printed index its
   rhythm. It sits on the entry rather than in a gap, so the spacing holds
   whatever length the names run to. */
.sx__ixa::after{content:'';position:absolute;right:0;top:50%;
  transform:translateY(-50%);width:1px;height:13px;
  background:rgba(65,68,55,.18)}
.sx__ixa:last-child::after{display:none}
.sx__ixa:focus-visible{outline:2px solid var(--olive-700);outline-offset:-3px;
  border-radius:4px}

/* lining, tabular figures: Cormorant sets old style by default, and at this
   size the zero and the one of 01 ran together into something like an O */
/* Full strength, not .75. Dimmed it came out at 3.32:1 on the ivory bar,
   and the active and inactive states are told apart by colour anyway. */
.sx__ixn{font-family:var(--serif);font-weight:300;font-size:.86rem;
  letter-spacing:.06em;color:var(--bronze);line-height:1;
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1;
  transition:color var(--d) var(--ease),opacity var(--d) var(--ease)}
.sx__ixt{font-size:var(--t-xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-muted);
  transition:color var(--d) var(--ease)}

.sx__ixa:hover .sx__ixt{color:var(--ink)}
.sx__ixa:hover .sx__ixn{color:#5E4526}
.sx__ixa.on .sx__ixt{color:var(--ink)}
/* deeper than --bronze, which does not make 4.5:1 at this size on ivory */
.sx__ixa.on .sx__ixn{color:#5E4526}

/* The travelling rule. A width transition redraws the bar every frame; a
   scaled transform is composited, so it stays smooth while the rail is being
   scrolled underneath it at the same time. */
.sx__ind{position:absolute;left:0;bottom:0;width:1px;height:2px;
  background:#5E4526;border-radius:2px;pointer-events:none;
  transform:translateX(0) scaleX(0);transform-origin:left center;
  transition:transform .55s var(--ease-out)}
@media (prefers-reduced-motion:reduce){
  .sx__ind{transition:none}
  .sx__ix{scroll-behavior:auto}
}

/* ---- the placeholder notice, as a deliberate band ---- */
.sp__notice{max-width:var(--maxw);margin:var(--s7) auto 0;
  display:flex;align-items:flex-start;gap:var(--s4);flex-wrap:wrap;
  padding:var(--s4) var(--s5);margin-inline:auto;width:calc(100% - var(--gutter) * 2);
  border-radius:var(--r-md);
  background:rgba(125,95,58,.06);
  box-shadow:inset 0 0 0 1px rgba(125,95,58,.18);
  font-size:var(--t-sm);color:var(--ink-soft);line-height:1.6}
.sx__nt{flex:none;font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--cream);background:var(--bronze);
  padding:.35em .8em;border-radius:var(--r-pill)}
.sp__notice code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.92em;padding:.15em .45em;border-radius:5px;
  background:rgba(65,68,55,.1);color:var(--ink)}

.sp__list{max-width:var(--maxw);margin-inline:auto;padding:0 var(--gutter);
  display:grid;gap:clamp(5rem,12vw,9rem);margin-top:clamp(4rem,9vw,7rem)}

/* ---- the chapter opener ---- */
.sx{scroll-margin-top:clamp(8rem,16vh,11rem)}
.sx__open{display:grid;gap:var(--s5);align-items:start;
  padding-bottom:var(--s6);margin-bottom:clamp(2rem,5vw,3.5rem);
  border-bottom:1px solid var(--rule)}
/* Lining, tabular figures with the tracking opened out. At -.05em Cormorant
   ran the zero and the one of 01 together and the standing numeral beside the
   service name read as the word OI. */
.sx__n{font-family:var(--serif);font-weight:300;
  font-size:clamp(3.4rem,9vw,7rem);line-height:.74;letter-spacing:.04em;
  color:var(--bronze);opacity:.28;
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.sx__name{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.9rem,4.6vw,3.4rem);line-height:1.04;letter-spacing:-.025em;
  text-wrap:balance}
/* the tag is sized for body copy, so against a 3.4rem title it needs to sit
   off the baseline and keep its distance rather than butting the last word */
.sx__name .ph{vertical-align:middle;margin-left:.6em;transform:translateY(-.15em)}
.sx__lead{margin-top:var(--s4);font-size:var(--t-lede);color:var(--ink-soft);
  line-height:1.6;max-width:36ch;text-wrap:pretty}

/* ---- the body ---- */
.sx__grid{display:grid;gap:clamp(2rem,5vw,4.5rem);align-items:start}
/* A picture at 4/5 in a column this wide came out 902px tall on a laptop,
   which is taller than the window it is sitting in, and a sticky figure you
   cannot see all of is not doing its job. It is a shorter portrait now, and
   capped, so the eye reaches the writing beside it. */
/* a headed entry: the claim in small caps, the sentence under it */
.sx__li--pair{display:grid;gap:.3rem}
.sx__li-h{font-weight:500;font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink)}
.sx__li-p{color:var(--ink-muted);line-height:1.7}
/* the sentence that introduces a list rather than belonging to it */
.sx__lead-in{color:var(--ink-muted);line-height:1.7;margin-bottom:var(--s4);
  max-width:46ch}
/* Nineteen inclusions in one column is a scroll, not a list, so past eight
   entries it runs in more than one.

   A COLUMN WIDTH, NOT A COLUMN COUNT. `columns:2` past 640px asked for two
   columns whatever the container happened to be, and inside a narrow track it
   produced two 90px columns. A width tells the browser how narrow a column is
   allowed to get and it fits as many as it can, so this can never split a
   container that has no room to be split. */
.sx__ul--two{columns:17rem;column-gap:var(--s6)}
.sx__ul--two li{break-inside:avoid}

/* Landscape now, to match the photographs. The max-height that was capping
   an upright picture goes with it: a 3/2 in this column never needed one. */
.sx__figin{position:relative;border-radius:var(--r-xl);overflow:hidden;
  aspect-ratio:3/2;
  background:var(--limestone-lt);
  box-shadow:var(--sh-md)}
.sx__figin>picture{display:block;width:100%;height:100%}
.sx__figin img{width:100%;height:100%;object-fit:cover;display:block}

.sx__what{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.12rem,2.1vw,1.45rem);line-height:1.58;color:var(--ink);
  max-width:40ch;text-wrap:pretty}

/* ---- the specification list ---- */
/* Label in its own narrow column against a hairline, the way a specification
   sheet sets one. It reads as considered rather than as a bulleted list with
   a heading over it. */
.sx__spec{margin-top:clamp(2rem,4vw,3rem);display:grid}
.sx__row{display:grid;gap:.6rem;padding:var(--s5) 0;
  border-top:1px solid var(--rule)}
.sx__row:last-child{border-bottom:1px solid var(--rule)}
.sx__dt{font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-muted);padding-top:.15em}
.sx__ul{display:grid;gap:.55rem}
.sx__ul li{position:relative;padding-left:1.1rem;color:var(--ink-soft);
  line-height:1.65;text-wrap:pretty}
.sx__ul li::before{content:'';position:absolute;left:0;top:.68em;
  width:5px;height:1px;background:var(--bronze);opacity:.8}

/* ---- how it works ---- */
.sx__steps{margin-top:clamp(2.2rem,4.5vw,3.2rem)}
.sx__st{font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s5)}
.sx__ol{display:grid;gap:.25rem;counter-reset:none}
.sx__ol li{display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:var(--s5);align-items:baseline;
  padding:var(--s4) 0;border-top:1px solid rgba(65,68,55,.08)}
.sx__ol li:first-child{border-top:0}
.sx__sn{font-family:var(--serif);font-weight:300;font-size:1.35rem;line-height:1;
  color:var(--bronze);letter-spacing:-.02em;min-width:2ch}
.sx__sl{color:var(--ink-soft);line-height:1.65;text-wrap:pretty}

.sx__act{margin-top:clamp(2.2rem,4.5vw,3.2rem)}

@media (min-width:860px){
  /* the numeral sits out to the side of the title, the way a chapter number
     does in a printed contents page */
  .sx__open{grid-template-columns:auto minmax(0,1fr);gap:clamp(1.5rem,4vw,3rem);
    align-items:baseline}
  .sx__row{grid-template-columns:minmax(0,11rem) minmax(0,1fr);gap:var(--s5)}
}
@media (min-width:1000px){
  /* the writing takes the larger share: this is a page of descriptions, and
     it was reading as a column of photographs with notes attached */
  .sx__grid{grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr)}
  /* the photograph holds its place while the detail scrolls past it */
  .sx__fig{position:sticky;top:clamp(9rem,18vh,12rem)}
  /* And the side it sits on alternates, so five chapters have a rhythm.
     `order` moves the figure into the second SLOT but the tracks keep their
     sizes, so on every even service the writing was landing in the narrow
     .72fr track meant for the photograph: a 190px column that wrapped her
     sentences to three words a line. The tracks have to swap with it. */
  .sx:nth-child(even) .sx__fig{order:2}
  .sx:nth-child(even) .sx__grid{grid-template-columns:minmax(0,1.28fr) minmax(0,.72fr)}
}
@media (max-width:999px){
  .sx__figin{aspect-ratio:16/10;max-height:none}
  .sx__body{margin-top:var(--s5)}
}
@media (prefers-reduced-motion:reduce){
  .sx__fig{position:static}
}

/* ------------------------------------------------------------------- QUIZ */
/* One set of styles, two homes: mounted inside the dark "Ready to start?"
   section on the homepage, and inside a dialog panel anywhere else. The inner
   pieces are identical; only the shell differs. */
.st__quiz{max-width:46rem;margin:var(--s7) auto 0}
.qz__intro{display:flex;justify-content:center}
.qz__arr{width:19px;height:19px;flex:none;margin-right:-.15em;
  transition:transform var(--d) var(--ease-out)}
.cta:hover .qz__arr{transform:translateX(5px)}

.qz__bar{height:2px;border-radius:2px;background:rgba(243,239,230,.14);overflow:hidden}
.qz__bar span{display:block;height:100%;background:var(--champagne);
  transition:width var(--d-slow) var(--ease-out)}
.qz__count{margin-top:var(--s5);font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--on-dark-mute)}
.qz__q{font-family:var(--serif);font-weight:300;font-size:clamp(1.35rem,2.8vw,2rem);
  line-height:1.16;letter-spacing:-.01em;margin-top:var(--s3)}
.qz__opts{margin-top:var(--s5);display:grid;gap:.6rem}
.qz__o{display:flex;align-items:center;gap:var(--s4);width:100%;text-align:left;
  padding:1.05rem 1.3rem;border-radius:var(--r-md);color:var(--cream);
  border:1px solid rgba(243,239,230,.18);background:rgba(243,239,230,.03);
  transition:border-color var(--d) var(--ease),background var(--d) var(--ease)}
.qz__o:hover{border-color:rgba(243,239,230,.42);background:rgba(243,239,230,.07)}
.qz__o.on{border-color:var(--champagne);background:rgba(217,201,169,.12)}
.qz__dot{flex:none;width:16px;height:16px;border-radius:50%;
  border:1px solid rgba(243,239,230,.45);position:relative}
.qz__o.on .qz__dot{border-color:var(--champagne)}
.qz__o.on .qz__dot::after{content:'';position:absolute;inset:3px;border-radius:50%;
  background:var(--champagne)}
.qz__nav{margin-top:var(--s4)}

/* ---- the result ---- */
.qz__res{text-align:center}
.qz__res-lead{margin-top:var(--s6);font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--on-dark-mute)}
.qz__res-name{font-family:var(--serif);font-weight:300;font-size:clamp(1.9rem,4.4vw,3rem);
  line-height:1.04;letter-spacing:-.02em;margin-top:var(--s3);color:var(--champagne)}
.qz__res-line{margin-top:var(--s4);color:var(--on-dark-soft);max-width:32rem;
  margin-inline:auto;text-wrap:pretty}

/* the explanation is built from the visitor's own answers, so it is specific
   without asserting anything the studio has not said */
.qz__why{margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid var(--rule-dark)}
.qz__why-t{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--on-dark-mute)}
.qz__chips{margin-top:var(--s4);display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center}
.qz__chips li{font-size:var(--t-sm);color:var(--cream);
  padding:.45em 1em;border-radius:var(--r-pill);
  border:1px solid rgba(217,201,169,.34);background:rgba(217,201,169,.08)}

.qz__res-acts{margin-top:var(--s6);display:flex;flex-wrap:wrap;gap:var(--s4);
  justify-content:center}
.qz__res-acts .cta--fill{background:var(--cream);color:var(--olive-950)}
.qz__res-acts .cta--fill::before{background:var(--champagne)}
.qz__again{margin-top:var(--s4);color:var(--on-dark-mute)}

/* ---- the dialog shell, used everywhere except the homepage ---- */
.qz--dlg{position:fixed;inset:0;z-index:var(--z-curtain);display:grid;place-items:center;
  padding:var(--gutter);background:rgba(14,15,10,.6);opacity:0;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:opacity var(--d) var(--ease)}
.qz--dlg.open{opacity:1}
.qz__panel{position:relative;width:min(40rem,100%);max-height:min(92svh,44rem);overflow-y:auto;
  background:var(--olive-950);color:var(--cream);border-radius:var(--r-xl);
  padding:var(--s8) clamp(1.5rem,3.5vw,3rem) var(--s7);
  box-shadow:inset 0 0 0 1px rgba(217,201,169,.2),0 40px 90px -30px rgba(20,22,15,.9);
  transform:translateY(1.5rem) scale(.99);
  transition:transform var(--d-slow) var(--ease-out)}
.qz--dlg.open .qz__panel{transform:none}
.qz__close{position:absolute;top:1rem;right:1rem;width:44px;height:44px;color:var(--cream);
  opacity:.7;transition:opacity var(--d) var(--ease)}
.qz__close:hover{opacity:1}
.qz__close span[aria-hidden]{display:block;position:relative;width:18px;height:18px;margin:0 auto}
.qz__close span[aria-hidden]::before,.qz__close span[aria-hidden]::after{
  content:'';position:absolute;inset:50% 0 auto 0;height:1px;background:currentColor}
.qz__close span[aria-hidden]::before{transform:rotate(45deg)}
.qz__close span[aria-hidden]::after{transform:rotate(-45deg)}
.qz--dlg .eyebrow{color:var(--champagne)}
.qz__title{font-family:var(--serif);font-weight:300;font-size:clamp(1.6rem,3.4vw,2.3rem);
  line-height:1.06;letter-spacing:-.015em;margin-top:var(--s3)}
.qz__body{margin-top:var(--s6)}
.qz--dlg .qz__res-lead{margin-top:var(--s5)}

/* ---- the prompt under the services list, which only points here ---- */
.ss__prompt{margin-top:var(--s6);font-size:var(--t-sm);color:var(--ink-muted)}
.ss__prompt-a{color:var(--bronze);position:relative;padding-bottom:2px;white-space:nowrap}
.ss__prompt-a::after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;
  background:currentColor;opacity:.4;transition:opacity var(--d) var(--ease)}
.ss__prompt-a:hover::after,.ss__prompt-a:focus-visible::after{opacity:1}

/* ----------------------------------------------------------------- FOOTER */
/* =========================================================== 9 . CONTACT */
/* One card, two halves: everything about reaching the studio on the left,
   where the studio is on the right. It sits on limestone rather than the
   ivory the questions above it use, so the page steps down in tone once
   before it reaches the dark of the footer instead of falling into it. */
.ct{padding:var(--bay) var(--gutter);background:var(--limestone-lt)}
/* The writing takes the larger half, not the map. At .95 against 1.05 each
   of the two week columns came out 236px wide, and a day, a Today chip and
   an opening time need about 240 between them, so today's row was a line and
   a half. The map at 570px is still a map; the week at 297 a column is a
   week. */
.ct__card{max-width:var(--maxw);margin-inline:auto;
  display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
  background:var(--ivory);border-radius:var(--r-xl);overflow:hidden;
  box-shadow:0 40px 90px -46px rgba(18,20,14,.45)}
/* with no address in the config there is no map, so the writing takes it all */
.ct__card--solo{grid-template-columns:minmax(0,1fr)}
.ct__side{padding:clamp(1.7rem,3.6vw,3.2rem)}
/* the title at full section scale is too loud inside a card, where it is one
   of two headings rather than the only thing on the screen */
.ct .title{font-size:clamp(1.65rem,2.9vw,2.45rem)}
/* the short hairline the client's reference sets its eyebrows with, which is
   the same kicker the hero uses over each fact */
.ct .eyebrow{display:flex;align-items:center;gap:.8rem;margin-bottom:var(--s3)}
.ct .eyebrow::before{content:'';width:26px;height:1px;background:var(--bronze);
  flex:none;opacity:.7}
.ct__second{margin-top:clamp(2.2rem,4.4vw,3.2rem)}

/* ---- the details ---- */
.ct__list{list-style:none;margin:clamp(1.4rem,2.6vw,2rem) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));
  gap:clamp(1.15rem,2.2vw,1.7rem)}
.ct__i{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.9rem;
  align-items:start}
.ct__ico{display:grid;place-items:center;flex:none;
  width:2.55rem;height:2.55rem;border-radius:50%;
  background:var(--cream);color:var(--bronze);
  box-shadow:inset 0 0 0 1px rgba(125,95,58,.16)}
.ct__ico svg{width:19px;height:19px}
.ct__k{display:block;font-size:var(--t-xs);font-weight:500;
  letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--ink-muted);margin-bottom:.34rem}
.ct__v{display:block;font-family:var(--serif);font-size:1.08rem;line-height:1.4;
  color:var(--ink);
  /* two phone numbers, and Cormorant sets oldstyle figures unless told */
  font-variant-numeric:lining-nums;font-feature-settings:'lnum' 1}
/* the underline is on the link, not the whole value, so the second phone
   number does not look like a continuation of the first */
.ct__v a{color:inherit;text-decoration:none;
  border-bottom:1px solid rgba(125,95,58,.32);
  transition:color var(--d-fast) var(--ease-out),border-color var(--d-fast) var(--ease-out)}
.ct__v a:hover{color:var(--bronze);border-bottom-color:var(--bronze)}
/* a button that has to read as the same kind of thing as the links above it */
.ct__go{appearance:none;background:none;border:0;padding:0;cursor:pointer;
  font:inherit;color:var(--bronze);
  border-bottom:1px solid rgba(125,95,58,.32)}
.ct__go:hover{border-bottom-color:var(--bronze)}

/* ---- the week ---- */
/* Two columns of days, which is how a week is read at a glance, and a broken
   rule under each so the eye can travel from the day to the time without the
   solid line of a timetable. */
.ch{list-style:none;margin:clamp(1.2rem,2.4vw,1.8rem) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));
  column-gap:clamp(1rem,2vw,1.8rem)}
/* FLEX, NOT A THREE TRACK GRID, and the reason is worth writing down.
   As a grid the middle track was minmax(0,1fr) and the time track was auto,
   so the time took its content width first and left the middle track 10px.
   The chip does not shrink, so on today's row it spilled 38px across the
   opening time. Every other row looked fine, which is how it went unnoticed.
   In a flex row nothing can be laid on top of anything: the time is pushed
   to the end with an auto margin and never shrinks, and if the three of them
   ever will not fit, the line wraps instead of overlapping. */
.ch__i{display:flex;align-items:baseline;flex-wrap:wrap;gap:.45rem .6rem;
  padding:.62rem .7rem;border-bottom:1px dashed rgba(58,61,50,.22)}
.ch__d{flex:none;min-width:2.6rem;font-family:var(--serif);font-style:italic;
  font-size:1.02rem;color:var(--ink-soft)}
.ch__t{flex:none;margin-left:auto;white-space:nowrap;
  font-size:.9rem;color:var(--ink-muted);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
/* the chip only exists on the day being lived through */
.ch__now{flex:none;display:none;
  padding:.24em .7em;border-radius:var(--r-pill);
  background:var(--bronze);color:var(--ivory);
  font-size:.62rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase}
.ch__i.is-today{background:var(--cream);border-radius:var(--r-sm);
  border-bottom-color:transparent}
.ch__i.is-today .ch__d{color:var(--ink)}
.ch__i.is-today .ch__now{display:inline-block}
.ch__i.is-today .ch__t{color:var(--ink-soft)}

/* ---- the map ---- */
.ct__map{position:relative;min-height:clamp(21rem,40vw,33rem);
  background:var(--limestone)}
.ct__frame,.ct__frame iframe{position:absolute;inset:0;width:100%;height:100%}
.ct__frame iframe{border:0;display:block}
/* the same open or closed state the hero carries, said again where someone
   is deciding whether to drive over */
.ct__status{position:absolute;z-index:1;
  top:clamp(.85rem,1.8vw,1.25rem);right:clamp(.85rem,1.8vw,1.25rem);
  display:inline-flex;align-items:center;gap:.58rem;
  margin:0;padding:.56em 1.1em;border-radius:var(--r-pill);
  background:rgba(20,22,15,.9);color:var(--cream);
  font-size:var(--t-xs);font-weight:500;letter-spacing:.17em;text-transform:uppercase;
  box-shadow:0 14px 34px -14px rgba(18,20,14,.7)}
.ct__status[hidden]{display:none}
.ct__sdot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--champagne)}
.ct__status.is-open .ct__sdot{background:#78B47A;
  box-shadow:0 0 12px rgba(120,180,122,.9)}

.ct__place{position:absolute;z-index:1;
  left:clamp(.85rem,1.8vw,1.35rem);right:clamp(.85rem,1.8vw,1.35rem);
  bottom:clamp(.85rem,1.8vw,1.35rem);
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  gap:clamp(.8rem,1.6vw,1.15rem);align-items:center;
  padding:clamp(.75rem,1.5vw,1.05rem) clamp(.95rem,1.8vw,1.35rem);
  background:rgba(251,249,244,.93);backdrop-filter:blur(10px);
  border-radius:var(--r-lg);text-decoration:none;color:var(--ink);
  box-shadow:0 22px 50px -26px rgba(18,20,14,.6);
  transition:transform var(--d-fast) var(--ease-out),background var(--d-fast) var(--ease-out)}
.ct__place:hover{transform:translateY(-2px);background:rgba(251,249,244,.98)}
.ct__pico{display:grid;place-items:center;flex:none;
  width:2.5rem;height:2.5rem;border-radius:50%;
  background:var(--bronze);color:var(--ivory)}
.ct__pico svg{width:18px;height:18px}
.ct__pk{display:block;font-size:var(--t-xs);font-weight:500;
  letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-muted)}
.ct__pv{display:block;font-family:var(--serif);font-size:1.05rem;line-height:1.3;
  color:var(--ink);font-variant-numeric:lining-nums;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ct__pgo{flex:none;font-size:var(--t-xs);font-weight:500;
  letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--bronze);
  border-bottom:1px solid rgba(125,95,58,.4);padding-bottom:.15rem}

@media (max-width:980px){
  /* the map goes under the writing rather than beside it, at a height that
     still shows the streets either side of the pin */
  .ct__card{grid-template-columns:minmax(0,1fr)}
  .ct__map{min-height:clamp(17rem,52vw,24rem)}
}
/* only one of the two weeks is ever on */
.ch--brief{display:none}

@media (max-width:560px){
  /* the directions label drops off the card before the address has to wrap:
     the whole card is the link, so nothing is lost with it */
  .ct__place{grid-template-columns:auto minmax(0,1fr)}
  .ct__pgo{display:none}
  .ch__i{padding-inline:.45rem}

  /* ---- THE DETAILS GO ONTO ONE LINE EACH ----
     Measured at 281px: side by side leaves 78px for a value and the
     shortest needs 103, so pairing does not fit. Label left, value right
     does, with room to spare on every one of them, and it turns five items
     of two lines into five of one. The icons come off to buy that width;
     the labels were always the thing carrying the meaning. */
  .ct__list{grid-template-columns:minmax(0,1fr);gap:0;
    border-top:1px solid rgba(58,61,50,.14)}
  .ct__ico{display:none}
  .ct__i{grid-template-columns:minmax(0,1fr);padding:.6rem .1rem;
    border-bottom:1px solid rgba(58,61,50,.14)}
  .ct__b{display:flex;align-items:baseline;justify-content:space-between;
    gap:.9rem;flex-wrap:wrap}
  .ct__k{margin-bottom:0;flex:none}
  .ct__v{text-align:right;font-size:1rem}

  /* ---- and the week becomes the short one ---- */
  .ch--full{display:none}
  .ch--brief{display:grid}
  .ch--brief .ch__i{padding-inline:.1rem}
}
@media (prefers-reduced-motion:reduce){
  .ct__place:hover{transform:none}
}

/* ====================================================== THE DATE PICKER */
/* It replaced the browser's own date box and a dropdown of hours, which are
   the two controls on this site that looked like somebody else's software.
   Built from js/calendar.js. The real input and select are still in here,
   named and read exactly as before, only out of sight, so the form does not
   know the difference and works without any of this. */
.cal__hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.cal__wrap{margin-top:var(--s5)}

.cal{display:grid;gap:clamp(.9rem,2vw,1.4rem);
  grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);align-items:start}
.cal__grid,.cal__side{border-radius:var(--r-lg);
  border:1px solid rgba(243,239,230,.12);background:rgba(243,239,230,.035);
  padding:clamp(.9rem,2vw,1.3rem)}
/* validation focuses a control nobody can see, so the grid takes the hint */
.cal.is-asked .cal__grid,.cal.is-asked .cal__side{
  border-color:rgba(217,201,169,.55);box-shadow:0 0 0 3px rgba(217,201,169,.1)}

/* ---- the month ---- */
.cal__head{display:flex;align-items:center;gap:.6rem;margin-bottom:var(--s4)}
.cal__month{flex:1;margin:0;text-align:center;font-family:var(--serif);
  font-size:1.32rem;line-height:1;color:var(--cream);
  font-variant-numeric:lining-nums tabular-nums}
.cal__month em{font-style:italic;color:var(--champagne)}
.cal__arrow{flex:none;width:36px;height:36px;border-radius:50%;
  border:1px solid rgba(243,239,230,.18);background:none;color:var(--cream);
  display:grid;place-items:center;cursor:pointer;
  transition:border-color var(--d) var(--ease),background var(--d) var(--ease)}
.cal__arrow svg{width:17px;height:17px}
.cal__arrow:hover:not([disabled]){border-color:var(--champagne);
  background:rgba(217,201,169,.12)}
.cal__arrow[disabled]{opacity:.24;cursor:default}

.cal__dows{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;
  margin-bottom:.3rem}
.cal__dows span{text-align:center;font-size:9.5px;font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(243,239,230,.42)}

.cal__days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal__d{aspect-ratio:1;min-height:38px;display:grid;place-items:center;
  border:0;border-radius:50%;background:none;color:var(--cream);cursor:pointer;
  font-family:var(--serif);font-size:1.02rem;line-height:1;
  font-variant-numeric:lining-nums;position:relative;
  transition:background var(--d-fast) var(--ease),color var(--d-fast) var(--ease),
             box-shadow var(--d-fast) var(--ease)}
.cal__d--pad{visibility:hidden;cursor:default}
.cal__d:hover:not([disabled]):not(.is-on){background:rgba(243,239,230,.09);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.2)}
.cal__d:focus-visible{outline:2px solid var(--champagne);outline-offset:1px}
/* chosen: filled, the way the rest of the site marks a chosen thing */
.cal__d.is-on{background:var(--champagne);color:var(--olive-950);font-weight:500}
/* today gets a mark under the numeral, not a ring, so it cannot be mistaken
   for the day that has been chosen */
.cal__d.is-today::after{content:'';position:absolute;bottom:5px;
  width:3px;height:3px;border-radius:50%;background:var(--champagne)}
.cal__d.is-on.is-today::after{background:var(--olive-950)}
/* Closed. Hatched rather than merely faded, because faded on a dark ground
   reads as low contrast text rather than as a day you cannot have. */
.cal__d.is-off{color:rgba(243,239,230,.26);cursor:default;
  background:repeating-linear-gradient(-45deg,
    rgba(243,239,230,.07) 0 1px,transparent 1px 5px)}

.cal__key{list-style:none;display:flex;flex-wrap:wrap;gap:1rem;
  margin:var(--s4) 0 0;padding:var(--s4) 0 0;
  border-top:1px solid rgba(243,239,230,.1)}
.cal__key li{display:flex;align-items:center;gap:.45rem;font-size:9.5px;
  font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(243,239,230,.5)}
.cal__sw{width:13px;height:13px;border-radius:50%;flex:none}
.cal__sw--open{box-shadow:inset 0 0 0 1px rgba(243,239,230,.34)}
.cal__sw--on{background:var(--champagne)}
.cal__sw--off{background:repeating-linear-gradient(-45deg,
  rgba(243,239,230,.24) 0 1px,transparent 1px 4px);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.14)}

/* ---- the times ---- */
.cal__side{min-height:100%;display:grid;align-content:start;gap:.2rem}
.cal__pick{margin:0;font-family:var(--serif);font-size:1.3rem;line-height:1.2;
  color:var(--cream)}
.cal__sub{margin:.15rem 0 var(--s4);font-size:var(--t-xs);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--champagne)}
.cal__times{display:grid;gap:.45rem;
  grid-template-columns:repeat(auto-fill,minmax(6.4rem,1fr))}
.cal__t{padding:.62rem .5rem;border-radius:var(--r-sm);
  border:1px solid rgba(243,239,230,.16);background:rgba(243,239,230,.03);
  color:var(--cream);font-size:.86rem;cursor:pointer;
  font-variant-numeric:lining-nums tabular-nums;
  transition:border-color var(--d-fast) var(--ease),
             background var(--d-fast) var(--ease),color var(--d-fast) var(--ease)}
.cal__t:hover{border-color:rgba(243,239,230,.4);background:rgba(243,239,230,.08)}
.cal__t.is-on{background:var(--champagne);border-color:var(--champagne);
  color:var(--olive-950);font-weight:500}
.cal__t:focus-visible{outline:2px solid var(--champagne);outline-offset:2px}
.cal__none{margin:0;font-size:var(--t-sm);font-style:italic;
  color:var(--on-dark-mute)}

/* before a day is chosen, the panel is not empty, it is an instruction */
.cal__blank{display:grid;justify-items:center;text-align:center;gap:.4rem;
  padding:clamp(1.2rem,3vw,2.2rem) .6rem}
.cal__mark{display:block;width:34px;height:34px;color:var(--champagne);
  opacity:.75;margin-bottom:.2rem}
.cal__mark svg{width:100%;height:100%}
.cal__blank-h{margin:0;font-family:var(--serif);font-size:1.22rem;
  color:var(--cream)}
.cal__blank-p{margin:0;max-width:19rem;font-size:var(--t-sm);line-height:1.55;
  color:var(--on-dark-mute)}
.cal__blank-p strong{color:var(--champagne);font-weight:400}

@media (max-width:760px){
  /* one under the other, and the grid keeps its tap targets rather than
     shrinking them to fit a phone */
  .cal{grid-template-columns:minmax(0,1fr)}
  .cal__d{min-height:40px;font-size:1.06rem}
  .cal__side{min-height:0}
}
@media (prefers-reduced-motion:reduce){
  .cal__d,.cal__t,.cal__arrow{transition:none}
}

/* ======================================================== LISTEN TO THIS */
/* THE CONTROL LIVES IN THE META LINE.
   It was a panel of its own between the cover and the first paragraph,
   which read as a widget bolted onto a page that has no other widgets. It
   sits beside "2 min read" now, because "listen, 3 min" is the same kind of
   fact told to the same person at the same moment. Nothing is added to the
   page while it plays either: the control fills up rather than growing a
   bar underneath it. */
.lsn{display:inline-flex;align-items:center;gap:.5rem}
.lsn__go{position:relative;overflow:hidden;isolation:isolate;
  display:inline-flex;align-items:center;gap:.42rem;
  padding:.38em .9em .38em .72em;border-radius:var(--r-pill);
  border:1px solid rgba(125,95,58,.4);background:none;color:var(--bronze);
  font:inherit;font-size:inherit;letter-spacing:inherit;text-transform:inherit;
  cursor:pointer;white-space:nowrap;
  transition:border-color var(--d-fast) var(--ease),
             background var(--d-fast) var(--ease)}
.lsn__go:hover{border-color:var(--bronze);background:rgba(125,95,58,.08)}
.lsn__go:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}
/* the progress, as the control filling from the left */
.lsn__fill{position:absolute;z-index:-1;inset:0 auto 0 0;width:0;
  background:rgba(125,95,58,.16);transition:width .2s linear}
.lsn__ico{display:grid;place-items:center;flex:none;width:13px;height:13px}
.lsn__ico svg{width:100%;height:100%}
.lsn__pause{display:none}
.lsn.is-playing .lsn__play{display:none}
.lsn.is-playing .lsn__pause{display:block}
.lsn.is-playing .lsn__go{border-color:var(--bronze)}
.lsn__l{display:block}

.lsn__rate{padding:.3em .55em;border-radius:var(--r-pill);
  border:1px solid rgba(58,61,50,.22);background:none;color:var(--ink-muted);
  font:inherit;font-size:inherit;letter-spacing:inherit;cursor:pointer;
  font-variant-numeric:lining-nums tabular-nums;
  transition:border-color var(--d-fast) var(--ease),color var(--d-fast) var(--ease)}
.lsn__rate[hidden]{display:none}
.lsn__rate:hover{border-color:var(--bronze);color:var(--bronze)}

/* ---- and the mark on each card in the list ---- */
.pc__lsn{display:inline-flex;align-items:center;gap:.34rem;color:var(--bronze)}
.pc__lsn svg{width:11px;height:11px;flex:none}
/* the card is a link, so the mark follows it on hover rather than sitting
   there looking like a second thing to press */
.pc:hover .pc__lsn{color:var(--ink)}

@media (prefers-reduced-motion:reduce){
  .lsn__fill{transition:none}
}

.ft{background:var(--olive-950);color:var(--cream);padding:var(--s9) var(--gutter) var(--s6)}
/* One oversized italic line travelling across the footer, edge to edge, with
   the ends feathered so it reads as coming from off-screen. */
.ft__marquee{margin:0 calc(var(--gutter) * -1) var(--s8);overflow:hidden;
  -webkit-mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);
  mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent)}
.ft__track{display:flex;align-items:center;width:max-content;will-change:transform}
.ft__s{font-family:var(--serif);font-weight:300;font-style:italic;
  font-size:clamp(2.6rem,10vw,9rem);line-height:1.1;letter-spacing:-.025em;
  color:var(--champagne);white-space:nowrap}
.ft__dot{flex:none;width:clamp(6px,.7vw,11px);aspect-ratio:1;border-radius:50%;
  background:var(--olive-500);margin:0 clamp(1.4rem,3.4vw,3.2rem)}
.ft__grid{max-width:var(--maxw);margin-inline:auto;display:grid;gap:var(--s6);
  padding-top:var(--s7);border-top:1px solid var(--rule-dark-sf)}
/* The same wordmark the bar carries, so the name is set identically at both
   ends of the page. It has a real alpha channel, unlike the artwork this
   replaces, so it no longer needs the `screen` blend that was dropping the
   old file's baked-in black. */
.ft__brand{isolation:isolate}
.ft__logo{display:block;height:78px;width:auto;margin-bottom:var(--s4)}
.ft__legal{font-size:var(--t-xs);letter-spacing:.22em;text-transform:uppercase;color:var(--on-dark-mute)}
.ft__tag{font-family:var(--serif);font-style:italic;font-size:1.05rem;color:var(--champagne);margin-top:.5rem}
.ft__col h3{font:500 var(--t-xs)/1 var(--sans);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--olive-300);margin-bottom:var(--s4)}
.ft__col ul{display:grid;gap:.5rem}
.ft__col a,.ft__col li{font-size:var(--t-sm);color:var(--on-dark-soft)}
.ft__col a:hover{color:var(--cream)}
.ft__base{max-width:var(--maxw);margin:var(--s7) auto 0;padding-top:var(--s4);
  border-top:1px solid var(--rule-dark-sf);
  display:flex;justify-content:center;align-items:center;gap:var(--s4);
  flex-wrap:wrap;text-align:center;
  font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--on-dark-mute)}
/* a small separator between the notice and the location, dropped when the row
   wraps onto two lines so nothing dangles */
.ft__dot-s{width:3px;height:3px;border-radius:50%;background:currentColor;opacity:.55}

/* ------------------------------------------------- OPEN HOURS, ON THE HERO */
/* The same live state as the footer, said in one line, opening the type block
   above the headline.

   It carries its own ground rather than sitting bare on the photograph, and
   that is a contrast decision before it is a style one: this sits high in the
   frame where the veil has thinned almost to nothing, and bare type there
   would be at the mercy of whatever the film happens to be showing. The glass
   is the material the bar, the back button and the WhatsApp pill are already
   made of, so it reads as part of the furniture rather than a badge stuck on.

   The champagne rim is what separates it from the reference it came from,
   which is a green dot and a clock icon on bare photography. */
/* Ranged top right, clear of the bar above it. The right edge lines up with
   the content column rather than the window, so it sits on the same measure
   as everything else on the page.

   The tint is back down to .46, which is as sheer as this can be made. What
   pays for it is the accent: at .46 the backdrop behind the glass reads about
   102 of 255 up here, and --champagne on that is 3.70:1, which is not
   readable. A lighter warm tone carries 4.73 on the same ground, so the open
   state takes that instead and the glass gets to stay thin. */
/* Printed onto the hero, not floated over it.
   It used to be a glass capsule: a tinted, blurred, champagne rimmed pill
   that read as an object sitting on the page. The client wanted it to feel
   part of the page instead, so the capsule is gone entirely. What holds it
   now is a hairline under the words, the way a caption is ruled off, and a
   shadow on the type itself rather than a plate behind it.
   Dropped a little and brought in from the edge at the same time. */
.hs{position:absolute;z-index:2;
  top:clamp(8.2rem,16vh,11rem);
  /* the fallback, until placeHours() in js/app.js lines it up with the gap
     between About and FAQ in the bar. It is also what a phone keeps. */
  right:calc(max(var(--gutter),calc((100% - var(--maxw)) / 2))
             + clamp(.75rem,2.4vw,2.2rem));
  display:inline-flex;align-items:center;gap:.8rem;
  padding:0 0 .6rem;
  border-bottom:1px solid rgba(217,201,169,.5);
  isolation:isolate;
  text-shadow:0 1px 2px rgba(18,20,14,.8),0 2px 9px rgba(18,20,14,.95),
              0 10px 34px rgba(18,20,14,.85)}

/* No plate, and no pool behind it either. An ellipse sized to the writing
   was legible but it read as a smudge on the photograph, which the client
   saw straight away. What it was doing has moved into the crown on the veil
   instead: one gradient, the full width of the frame, no edge anywhere to
   notice. See .hero__veil. */
.hs[hidden]{display:none}

/* Closed is champagne, not olive. Olive on a dark photograph is a hole in
   the page, and the whole job of the dot is to be seen. Open is still the
   one that turns green and breathes. */
.hs__dot{position:relative;flex:none;width:8px;height:8px;border-radius:50%;
  background:var(--champagne);box-shadow:0 0 0 1px rgba(18,20,14,.5)}
.hs.is-open .hs__dot{background:#78B47A;
  box-shadow:0 0 0 1px rgba(120,180,122,.4),0 0 14px rgba(120,180,122,.85)}
/* the ring only runs while the studio is open; a pulse on a closed sign is
   movement that means nothing */
.hs.is-open .hs__dot::after{content:'';position:absolute;inset:0;border-radius:50%;
  box-shadow:0 0 0 1px rgba(120,180,122,.85);
  animation:hsPulse 2.4s var(--ease-out) infinite}
@keyframes hsPulse{
  0%  {transform:scale(1);opacity:.9}
  70% {transform:scale(3.4);opacity:0}
  100%{transform:scale(3.4);opacity:0}
}

.hs__s{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:1.22rem;line-height:1;color:var(--cream);white-space:nowrap}
/* lighter than --champagne so it survives the thinner glass; still warm, so
   the open state is still the one that turns gold */
.hs.is-open .hs__s{color:#EDE3CE}
/* a hairline, not a bullet: the same rule the rest of the page divides with */
.hs__r{flex:none;width:1px;height:17px;background:rgba(217,201,169,.45)}
/* full strength: dimmed to .88 it came out at 4.46 against the thinner glass.
   The hairline and the change of face already separate it from the status, so
   it does not need to be quieter as well. */
.hs__n{font-size:.78rem;font-weight:500;letter-spacing:.17em;
  text-transform:uppercase;color:var(--cream);white-space:nowrap}

@media (max-width:740px){
  /* dropped to sit just above the lamp in the photograph rather than up
     under the bar. The crown below is stretched to follow it. */
  .hs{gap:.62rem;padding:0 0 .45rem;
    top:clamp(8rem,17vh,10.5rem)}
  .hs__s{font-size:1.02rem}
  .hs__n{letter-spacing:.1em;font-size:11px}
  .hs__r{height:13px}
}
@media (prefers-reduced-motion:reduce){
  .hs.is-open .hs__dot::after{animation:none;opacity:.5}
}

/* -------------------------------------------------------------- OPEN HOURS */
/* The live badge, under the phone numbers, which is the moment someone is
   deciding whether to call. It says more than the reference it came from: as
   well as open or closed it says what happens next, so "Closed" is never a
   dead end, it is "Closed, opens tomorrow 8:30am".

   The dot is the only true green on the site. It is pulled well towards olive
   so it belongs here rather than looking like a borrowed status light, and it
   breathes: a ring expands out of it and fades, which is what makes the badge
   read as something running rather than a printed line. */
.oh{margin-top:var(--s6);display:grid;gap:var(--s4);
  padding-top:var(--s5);border-top:1px solid var(--rule-dark-sf)}

.oh__now{display:flex;align-items:baseline;flex-wrap:wrap;gap:.5rem .7rem;
  margin:0}
.oh__dot{position:relative;flex:none;align-self:center;
  width:8px;height:8px;border-radius:50%;
  background:var(--olive-500);box-shadow:0 0 0 1px rgba(243,239,230,.18)}
.oh__now.is-open .oh__dot{background:#6FA871;
  box-shadow:0 0 0 1px rgba(111,168,113,.35),0 0 12px rgba(111,168,113,.7)}
/* the ring only runs while the studio is actually open: a pulse on a closed
   sign would be movement that means nothing */
.oh__now.is-open .oh__dot::after{content:'';position:absolute;inset:0;
  border-radius:50%;box-shadow:0 0 0 1px rgba(111,168,113,.8);
  animation:ohPulse 2.4s var(--ease-out) infinite}
@keyframes ohPulse{
  0%  {transform:scale(1);opacity:.9}
  70% {transform:scale(3.2);opacity:0}
  100%{transform:scale(3.2);opacity:0}
}
/* --on-dark-mute and --on-dark-soft are the same value in the token file, so
   "muted" was not dimming anything and Closed was coming out brighter than
   Open, which is backwards. The closed state is dialled back with opacity
   instead: 8.2:1, still well clear, and now quieter than the champagne it
   turns for when the studio is actually open. */
.oh__s{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:1.15rem;line-height:1;color:var(--on-dark-soft);opacity:.7}
.oh__now.is-open .oh__s{color:var(--champagne);opacity:1}
.oh__note{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--on-dark-soft)}

/* the schedule itself, set as a small table rather than one run-on line, so
   the two different days are read at a glance instead of parsed */
.oh__list{list-style:none;margin:0;padding:0;display:grid;gap:.45rem}
.oh__list li{display:flex;align-items:baseline;gap:var(--s4);
  font-size:var(--t-xs);letter-spacing:.1em}
/* the day sits behind the time rather than beside it at equal weight, which
   is the difference between a table you scan and two columns you read */
.oh__d{text-transform:uppercase;color:var(--on-dark-soft);opacity:.62;
  letter-spacing:var(--track-caps);flex:none;min-width:6.4rem}
.oh__t{color:var(--on-dark-soft);font-variant-numeric:tabular-nums;
  margin-left:auto;text-align:right}

@media (prefers-reduced-motion:reduce){
  .oh__now.is-open .oh__dot::after{animation:none;opacity:.45}
}

/* ------------------------------------------------------------ PAGE CURTAIN */
/* The site changes page behind a set of vertical slats, which is the one piece
   of furniture the studio's own mark is drawn around: there are blinds in the
   emblem, so the transition is made of blinds.

   It opens on its own, in CSS, with nothing asked of the script. That matters.
   A transition that waits to be told to go away leaves the page unreadable if
   the script fails; this one lifts regardless, and js only has to handle the
   closing half on the way out.

   The slats close downward from the top and then keep going downward as they
   open, so the curtain passes through the page in one direction rather than
   retracting back the way it came. */
.curtain{position:fixed;inset:0;z-index:var(--z-page);pointer-events:none;
  display:grid;grid-template-columns:repeat(6,1fr)}
.curtain__s{transform-origin:50% 100%;
  background:linear-gradient(176deg,#282B1B 0%,var(--olive-950) 100%);
  animation:curtainOut .58s var(--ease-out) both;
  animation-delay:calc(var(--i,0) * .045s)}
/* the stagger reads left to right, the way a blind is drawn */
.curtain__s:nth-child(1){--i:0}
.curtain__s:nth-child(2){--i:1}
.curtain__s:nth-child(3){--i:2}
.curtain__s:nth-child(4){--i:3}
.curtain__s:nth-child(5){--i:4}
.curtain__s:nth-child(6){--i:5}
@keyframes curtainOut{from{transform:scaleY(1)}to{transform:scaleY(0)}}

.curtain__mark{position:absolute;inset:0;display:grid;place-items:center;
  color:var(--champagne);
  animation:curtainMarkOut .42s var(--ease) .12s both}
.curtain__mark svg{width:clamp(66px,9vw,108px);height:clamp(66px,9vw,108px);
  display:block}
@keyframes curtainMarkOut{
  from{opacity:1;transform:scale(1)}
  to  {opacity:0;transform:scale(1.1)}
}

/* ---- closing, on the way out ---- */
/* the delay has to be restated: the shorthand above it resets
   animation-delay to 0, which closed all six slats in one flat move and threw
   away the stagger that makes it read as a blind being drawn */
.curtain--close .curtain__s{transform-origin:50% 0;
  animation:curtainIn .44s var(--ease) both;
  animation-delay:calc(var(--i,0) * .04s)}
@keyframes curtainIn{from{transform:scaleY(0)}to{transform:scaleY(1)}}
/* the overshoot in the curve is the pop: the mark arrives a shade past full
   size and settles, which is what makes it land rather than simply appear */
/* it has to have landed before the link is followed at 680ms, so it settles
   at 600 and the slats finish at 640 */
.curtain--close .curtain__mark{
  animation:curtainMarkIn .44s cubic-bezier(.22,1.5,.36,1) .16s both}
@keyframes curtainMarkIn{
  from{opacity:0;transform:scale(.66)}
  to  {opacity:1;transform:scale(1)}
}

@media (prefers-reduced-motion:reduce){
  .curtain{display:none}
}

/* ------------------------------------------------------------ BACK BUTTON */
/* Bottom left, facing the WhatsApp button, so the two floating controls read
   as a pair rather than as clutter. It is not up under the bar because the
   bar takes itself off screen on the way down the page, and because the
   services page already has its sticky index sitting there.

   Unlike the WhatsApp pill this one keeps its label out at all times. A
   control that only says where it goes once you hover it is no use to the
   person who did not know there was a way back. */
.backb{position:fixed;left:clamp(1rem,2.5vw,2rem);bottom:clamp(1rem,2.5vw,2rem);
  z-index:var(--z-float);
  display:inline-flex;align-items:center;gap:.7rem;height:50px;
  padding:0 1.2rem 0 .85rem;border-radius:999px;color:var(--cream);
  background:
    linear-gradient(180deg,rgba(255,255,255,.08),rgba(255,255,255,0) 54%),
    rgba(26,24,21,.74);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 0 0 1px rgba(255,255,255,.16),
    0 16px 32px -18px rgba(20,22,15,.85);
  transform:translateY(160%);
  transition:transform var(--d) var(--ease-out),background var(--d) var(--ease)}
.backb.in{transform:translateY(0)}
.backb__ico{flex:none;width:26px;height:26px;display:grid;place-items:center;
  border-radius:50%;color:var(--champagne);
  box-shadow:inset 0 0 0 1px rgba(203,176,125,.45);
  transition:transform var(--d) var(--ease-out),background var(--d) var(--ease)}
.backb__ico svg{width:14px;height:14px}
.backb__t{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  font-weight:500;white-space:nowrap}
.backb:hover{background:
    linear-gradient(180deg,rgba(255,255,255,.1),rgba(255,255,255,0) 54%),
    rgba(26,24,21,.88)}
.backb:hover .backb__ico{transform:translateX(-3px);background:rgba(203,176,125,.16)}
.backb:focus-visible{outline:2px solid var(--champagne);outline-offset:4px}
.backb:active{transform:scale(.97)}
@media (prefers-reduced-motion:reduce){
  .backb,.backb__ico{transition:none}
  .menu,.menu__links a,.menu__foot > *{transition:none}
  .menu__links a,.menu__foot > *{opacity:1;transform:none}
}

/* --------------------------------------------------------------- WHATSAPP */
.wa{position:fixed;right:clamp(1rem,2.5vw,2rem);bottom:clamp(1rem,2.5vw,2rem);z-index:var(--z-float);
  display:inline-flex;align-items:center;gap:0;height:50px;padding:0 15px;
  background:var(--olive-800);color:var(--cream);border:1px solid var(--rule-dark);border-radius:999px;
  transform:translateY(160%);
  transition:gap var(--d) var(--ease),background var(--d) var(--ease),transform var(--d) var(--ease-out)}
.wa.in{transform:translateY(0)}
.wa__ico{width:22px;height:22px;flex:none}
.wa__txt{max-width:0;overflow:hidden;white-space:nowrap;font-size:var(--t-xs);
  letter-spacing:.2em;text-transform:uppercase;font-weight:500;transition:max-width var(--d) var(--ease)}
.wa:hover,.wa:focus-visible{background:var(--olive-700);gap:10px}
.wa:hover .wa__txt,.wa:focus-visible .wa__txt{max-width:11rem}
.sticky-cta{display:none}

/* ------------------------------------------------------------------ GRAIN */
.grain{position:fixed;inset:0;z-index:998;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.05'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ------------------------------------------------------------- INQUIRY UI */
.inq{position:fixed;inset:0;z-index:1000;display:grid;place-items:stretch;
  background:rgba(20,22,15,.62);opacity:0;transition:opacity var(--d) var(--ease)}
.inq.open{opacity:1}
.inq__panel{position:relative;background:var(--olive-950);color:var(--cream);overflow-y:auto;
  padding:var(--s8) var(--gutter) var(--s7);display:flex;flex-direction:column;
  transform:translateY(2rem);transition:transform var(--d-slow) var(--ease-out);
  /* A scroll that stops at the edge of the panel. Without this, running out
     of panel hands the wheel to the page behind, which is locked, so the
     whole thing just stops dead under your finger. */
  overscroll-behavior:contain;
  /* and a bar that belongs to this page rather than the operating system:
     the stock one is a light grey slab down a dark panel */
  scrollbar-width:thin;scrollbar-color:rgba(217,201,169,.38) transparent}
.inq__panel::-webkit-scrollbar{width:11px}
.inq__panel::-webkit-scrollbar-track{background:transparent}
.inq__panel::-webkit-scrollbar-thumb{background:rgba(217,201,169,.3);
  border:3px solid transparent;background-clip:content-box;border-radius:999px}
.inq__panel::-webkit-scrollbar-thumb:hover{background:rgba(217,201,169,.6);
  border:3px solid transparent;background-clip:content-box}
.inq{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.inq.open .inq__panel{transform:none}
.inq__close{position:absolute;top:1.2rem;right:var(--gutter);width:44px;height:44px;color:var(--cream)}
.inq__close span[aria-hidden]{display:block;position:relative;width:20px;height:20px;margin:0 auto}
.inq__close span[aria-hidden]::before,.inq__close span[aria-hidden]::after{
  content:'';position:absolute;top:50%;left:0;width:100%;height:1px;background:currentColor}
.inq__close span[aria-hidden]::before{transform:rotate(45deg)}
.inq__close span[aria-hidden]::after{transform:rotate(-45deg)}

.inq__top{max-width:52rem;margin:0 auto var(--s7);width:100%;display:grid;gap:var(--s4)}
.inq__rail{display:flex;gap:var(--s2);flex-wrap:wrap}
.inq__rail li{display:flex;align-items:center;gap:var(--s2);font-size:var(--t-xs);
  letter-spacing:.16em;text-transform:uppercase;color:rgba(243,239,230,.55);
  transition:color var(--d) var(--ease)}
.inq__rail li::after{content:'';width:16px;height:1px;background:currentColor;opacity:.6}
.inq__rail li:last-child::after{display:none}
.inq__rail li.on{color:var(--cream)}
.inq__rail li.done{color:var(--champagne)}

.inq__form{max-width:52rem;margin-inline:auto;width:100%;flex:1;display:flex;flex-direction:column}
.inq__steps{flex:1}
/* fieldset carries a UA border and padding, reset it, and min-width:0 keeps
   it from blowing out its flex parent */
.step{display:none;border:0;padding:0;margin:0;min-width:0}
.step.on{display:block;animation:stepIn .45s var(--ease-out)}
@keyframes stepIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.step__h{font-family:var(--serif);font-weight:300;font-size:clamp(1.6rem,3.6vw,2.5rem);
  line-height:1.05;margin-bottom:var(--s6)}

.step__note{margin-top:var(--s4);font-size:var(--t-sm);color:var(--champagne);font-style:italic}
/* an intro line sits right on top of the first label without this */
.step__note+.flds,.step__note+.rev,.step__note+.fld{margin-top:var(--s5)}
.opts{display:grid;gap:.55rem}
.opt{display:flex;align-items:flex-start;gap:var(--s4);width:100%;text-align:left;
  padding:1.05rem 1.35rem;border-radius:var(--r-md);
  border:1px solid rgba(243,239,230,.13);background:rgba(243,239,230,.03);color:inherit;
  transition:border-color var(--d) var(--ease),background var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.opt:hover{border-color:rgba(243,239,230,.34);background:rgba(243,239,230,.07)}
.opt:active{transform:scale(.993)}
.opt[aria-checked="true"]{border-color:var(--champagne);background:rgba(217,201,169,.11)}
.opt__dot{flex:none;width:12px;height:12px;margin-top:.5em;border-radius:50%;
  border:1px solid rgba(243,239,230,.5);position:relative}
.opt[aria-checked="true"] .opt__dot{border-color:var(--champagne)}
.opt[aria-checked="true"] .opt__dot::after{content:'';position:absolute;inset:2px;border-radius:50%;
  background:var(--champagne)}
.opt__m{display:grid;gap:2px}
.opt__l{font-family:var(--serif);font-size:1.18rem;line-height:1.25}
.opt__n{font-size:var(--t-sm);color:var(--champagne)}
.opt__n.quote{color:var(--on-dark-mute);font-style:italic}

.flds{display:grid;gap:var(--s5)}
.fld{display:grid;gap:.45rem}
.fld--w{grid-column:1/-1}
.fld label,.fld>span{font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--on-dark-mute)}
.fld label i{color:var(--champagne);font-style:normal}
.fld input,.fld select,.fld textarea{background:none;border:0;border-bottom:1px solid var(--rule-dark);
  padding:.65rem 0;color:var(--cream);font-size:1rem;font-weight:300;border-radius:0;
  transition:border-color var(--d) var(--ease)}
.fld textarea{border:1px solid rgba(243,239,230,.14);border-radius:var(--r-sm);padding:.8rem .9rem}
.fld textarea:focus{border-color:var(--champagne)}
.fld textarea{resize:vertical}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:none;border-bottom-color:var(--champagne)}
.fld input::placeholder,.fld textarea::placeholder{color:rgba(243,239,230,.45)}
/* The chevron for every select, drawn as a CSS triangle on the .fld
   wrapper. No background image anywhere, so nothing can tile. :has() is
   supported on every current browser; where it is not, the select simply
   shows the native OS arrow, which is fine. */
.fld{position:relative}
.fld:has(select)::after{content:'';position:absolute;pointer-events:none;
  /* Anchored to the bottom of the field, because top:50% would put it in
     the middle of (label + select) and the field is label on top with the
     control below. The select itself is around 48-56px tall after padding;
     this lands the chevron on its visible centre. */
  right:1rem;bottom:1.1rem;width:9px;height:9px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(45deg);opacity:.6}
/* currentColor is enough: the dialog cascades --ink (cream ground) or
   --cream (dark ground) via .inq__panel, so the arrow follows the text
   contrast without a special rule either way. */
.fld select{appearance:-webkit-appearance:none;appearance:none;
  /* The arrow is drawn as a CSS pseudo-element on .fld below rather than
     as a background image. Three different versions of this rule layered
     background-images on top of each other, and on at least one browser
     the end result tiled the chevron across the whole field. A pseudo
     element cannot repeat and cannot be confused with another. */
  padding-right:2.6rem}
.fld select option{background:var(--olive-950);color:var(--cream)}
.fld.bad input{border-bottom-color:#C4876B}
.fld__e{font-size:var(--t-xs);color:#DBA88C;letter-spacing:.04em}

.chips{display:flex;gap:.5rem;flex-wrap:wrap}
.chip{padding:.7em 1.5em;border-radius:var(--r-pill);
  border:1px solid rgba(243,239,230,.16);font-size:var(--t-sm);
  transition:background var(--d) var(--ease),border-color var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.chip:hover{border-color:rgba(243,239,230,.42);background:rgba(243,239,230,.06)}
.chip:active{transform:scale(.97)}
.chip[aria-checked="true"]{background:var(--cream);color:var(--olive-950);border-color:var(--cream)}

.sumry{display:grid;gap:.55rem;padding:var(--s5);border-radius:var(--r-md);
  border:1px solid rgba(243,239,230,.12);background:rgba(243,239,230,.03);margin-bottom:var(--s5)}
.sumry__r{display:flex;justify-content:space-between;gap:var(--s5);font-size:var(--t-sm);
  padding-bottom:.45rem;border-bottom:1px solid var(--rule-dark-sf)}
.sumry__r:last-child{border-bottom:0}
.sumry__r span:first-child{color:var(--on-dark-mute);letter-spacing:.06em}
.sumry__r span:last-child{text-align:right}
.sumry__r.total span:last-child{font:400 1.3rem/1 var(--serif);color:var(--champagne)}

.send{display:grid;gap:.75rem}
.send .cta--fill{background:var(--cream);color:var(--olive-950);justify-content:center}
.send .cta--fill::before{background:var(--champagne)}
.send .cta--line{justify-content:center;border-radius:var(--r-pill);
  border:1px solid rgba(243,239,230,.2);padding:calc(1.05em - 1px) calc(1.9em - 1px)}
.send .cta--line::after{display:none}
.send .cta--line:hover{background:rgba(243,239,230,.09);border-color:rgba(243,239,230,.45)}
.send__n{font-size:var(--t-sm);color:var(--on-dark-mute);margin-top:var(--s4)}

/* ------------------------------------------------- BOOKING, ADDED FIELDS */
/* The questionnaire, the optional inspiration step and the review screen.
   Everything here sits inside the dialog, which is a dark olive ground, so
   the borders are cream at low alpha rather than the ink rules used on the
   page itself. */

.fld.bad input,.fld.bad select,.fld.bad textarea{border-color:#C4876B}
/* a group of chips has no border to redden, so the question itself carries the
   error state. The hint and the message under it are exempt. */
.fld.bad>label,.fld.bad>span:not(.fld__hint):not(.fld__e){color:#DBA88C}
/* beats `.fld>span`, which would otherwise put the hint in tracked-out caps */
.fld>.fld__hint{font-size:var(--t-xs);color:var(--on-dark-mute);letter-spacing:.04em;
  line-height:1.55;text-transform:none;font-weight:400}
/* same reason: an error message appended to a `.fld` is a direct child span,
   so without this it inherits the label's caps and loses its warning colour */
.fld>.fld__e{color:#DBA88C;letter-spacing:.04em;text-transform:none;line-height:1.55}
.step__opt{font-family:var(--sans);font-style:normal;font-size:var(--t-xs);
  letter-spacing:.18em;text-transform:uppercase;color:var(--champagne);
  vertical-align:middle;margin-left:.6em}
/* the one note on the flow that has to be read, not skimmed */
.step__note--flag{font-style:normal;color:var(--on-dark-mute);
  padding:var(--s4) var(--s5);margin-top:var(--s5);
  border-radius:var(--r-md);border:1px solid rgba(243,239,230,.14);
  border-left:2px solid var(--champagne);line-height:1.65}

/* ---- multi-select chips ---- */
.chips--multi{gap:.45rem}
.chip--box{display:inline-flex;align-items:center;gap:.6em;padding-left:1.1em}
.chip__tick{flex:none;width:15px;height:15px;border-radius:4px;
  border:1px solid rgba(243,239,230,.34);position:relative;
  transition:background var(--d) var(--ease),border-color var(--d) var(--ease)}
.chip__tick::after{content:'';position:absolute;left:4px;top:1px;
  width:4px;height:8px;border:solid var(--olive-950);border-width:0 1.5px 1.5px 0;
  transform:rotate(45deg) scale(.4);opacity:0;
  transition:opacity var(--d-fast) var(--ease),transform var(--d-fast) var(--ease)}
.chip[aria-pressed="true"]{background:var(--cream);color:var(--olive-950);
  border-color:var(--cream)}
.chip[aria-pressed="true"] .chip__tick{background:var(--olive-950);
  border-color:var(--olive-950)}
.chip[aria-pressed="true"] .chip__tick::after{opacity:1;transform:rotate(45deg) scale(1)}

/* A grid or flex item's automatic minimum size is its min-content, so one long
   filename set in `nowrap` will widen every track above it and push the whole
   step off a phone screen. `min-width:0` all the way down the chain is what
   lets the ellipsis in `.fl__n` actually do its job. */
.fld,.lnks,.lnk,.fls,.fl{min-width:0}

/* ---- inspiration links ---- */
.lnks{display:grid;gap:.5rem}
.lnk{display:flex;align-items:center;gap:.5rem}
.lnk input{flex:1;min-width:0}
.lnk__x{flex:none;width:32px;height:32px;display:grid;place-items:center;
  border-radius:50%;color:var(--on-dark-mute);
  transition:background var(--d) var(--ease),color var(--d) var(--ease)}
.lnk__x svg{width:14px;height:14px}
.lnk__x:hover{background:rgba(243,239,230,.1);color:var(--cream)}
.addln{justify-self:start;position:relative;margin-top:.3rem;padding:.5em 0;
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--champagne);border-bottom:1px solid rgba(203,176,125,.4);
  transition:border-color var(--d) var(--ease)}
.addln:hover{border-bottom-color:var(--champagne)}

/* ---- photographs ---- */
.drop{display:grid;gap:.3rem;justify-items:center;text-align:center;
  padding:var(--s5);border-radius:var(--r-md);cursor:pointer;
  border:1px dashed rgba(243,239,230,.24);
  transition:border-color var(--d) var(--ease),background var(--d) var(--ease)}
.drop:hover{border-color:var(--champagne);background:rgba(243,239,230,.04)}
.drop__l{font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--cream)}
.drop__n{font-size:var(--t-xs);color:var(--on-dark-mute);text-transform:none;
  letter-spacing:.04em}
#iqPhotos:focus-visible+.fls,.drop:has(+#iqPhotos:focus-visible){outline:2px solid var(--champagne);
  outline-offset:3px}
.fls{display:grid;gap:.35rem;margin-top:.6rem}
.fl{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;
  border-radius:var(--r-sm);background:rgba(243,239,230,.05);
  font-size:var(--t-sm)}
.fl__n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fl__x{flex:none;width:26px;height:26px;display:grid;place-items:center;
  border-radius:50%;color:var(--on-dark-mute);
  transition:background var(--d) var(--ease),color var(--d) var(--ease)}
.fl__x svg{width:12px;height:12px}
.fl__x:hover{background:rgba(243,239,230,.12);color:var(--cream)}

/* ---- review ---- */
.rev{display:grid;gap:.75rem;margin-top:var(--s5)}
.rev__g{border-radius:var(--r-md);padding:var(--s5);
  background:rgba(243,239,230,.04);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.09)}
.rev__h{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s4);margin-bottom:var(--s4)}
.rev__h h3{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--champagne);font-weight:400}
.rev__h em{font-style:normal;color:var(--on-dark-mute);letter-spacing:.14em;
  font-size:.85em;margin-left:.7em;opacity:.85}
.rev__e{flex:none;position:relative;font-size:var(--t-xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--on-dark-mute);border-bottom:1px solid transparent;
  transition:color var(--d) var(--ease),border-color var(--d) var(--ease)}
.rev__e:hover{color:var(--cream);border-bottom-color:rgba(243,239,230,.5)}
.rev__l{display:grid;gap:.4rem}
.rev__r{display:grid;grid-template-columns:minmax(0,9rem) minmax(0,1fr);
  gap:var(--s4);font-size:var(--t-sm);align-items:baseline}
.rev__r dt{color:var(--on-dark-mute);letter-spacing:.06em}
/* answers are printed as typed, so a pasted link or a paragraph of vision
   keeps its line breaks instead of running together */
.rev__r dd{white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.6}

@media (max-width:560px){
  .rev__r{grid-template-columns:1fr;gap:.1rem}
  .rev__r dt{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase}
}
/* ------------------------------------------------------------- SITE VISIT */
/* Shares the booking dialog's shell and fields. Only the access gate, the
   package cards and the add-on rows are new. */

/* ---- the access gate ---- */
.gate{margin-top:var(--s5);padding:var(--s4) var(--s5);border-radius:var(--r-md);
  font-size:var(--t-sm);line-height:1.65;color:var(--on-dark-mute);
  border:1px solid rgba(243,239,230,.14);border-left:2px solid var(--champagne)}
.gate strong{color:var(--cream);font-weight:400}
.gate--ok{border-left-color:#8FA97B;color:var(--cream)}
.gate--warn{border-left-color:#C4876B}
.gate--wait{opacity:.7}
/* a button that has to read as a link because it sits inside a sentence */
.lnkbtn{color:var(--champagne);border-bottom:1px solid rgba(203,176,125,.45);
  font:inherit;letter-spacing:inherit;text-transform:none;
  transition:border-color var(--d) var(--ease)}
.lnkbtn:hover{border-bottom-color:var(--champagne)}
/* the standalone variant, sized for a thumb and clear of the field above it */
.lnkbtn--row{justify-self:start;margin-top:.5rem;padding:.75em 0;
  font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  min-height:44px;display:inline-flex;align-items:center}

/* ---- package cards ---- */
.pk{display:grid;gap:.6rem;margin-top:var(--s5)}
.pk__c{display:grid;gap:.75rem;text-align:left;padding:var(--s5);
  border-radius:var(--r-md);background:rgba(243,239,230,.04);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.1);
  transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.pk__c:hover{background:rgba(243,239,230,.07);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.24)}
.pk__c:active{transform:scale(.995)}
.pk__c.on{background:rgba(203,176,125,.1);
  box-shadow:inset 0 0 0 1px var(--champagne)}
.pk.bad .pk__c{box-shadow:inset 0 0 0 1px rgba(196,135,107,.6)}
.pk__top{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s4);flex-wrap:wrap}
.pk__n{font-family:var(--serif);font-weight:300;font-size:clamp(1.2rem,2.4vw,1.6rem);
  line-height:1.1;letter-spacing:-.01em;color:var(--cream)}
.pk__p{font-family:var(--serif);font-weight:300;font-size:clamp(1.1rem,2.2vw,1.45rem);
  color:var(--champagne);white-space:nowrap}
.pk__inc{display:flex;flex-wrap:wrap;gap:.4rem}
.pk__i{font-size:var(--t-xs);letter-spacing:.06em;color:var(--on-dark-mute);
  padding:.35em .8em;border-radius:var(--r-pill);
  background:rgba(243,239,230,.06)}
.pk__c.on .pk__i{background:rgba(243,239,230,.1);color:var(--cream)}

/* ---- add-ons ---- */
.ao{margin-top:var(--s6)}
.ao__h{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--champagne);font-weight:400;margin-bottom:var(--s4)}
.ao__list{display:grid;gap:.6rem}
.ao__r{display:grid;gap:.5rem;padding:var(--s4) var(--s5);border-radius:var(--r-md);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.09);
  transition:box-shadow var(--d) var(--ease),background var(--d) var(--ease)}
.ao__r.on{background:rgba(243,239,230,.04);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.18)}
.ao__t{justify-self:start}
.ao__n{font-size:var(--t-xs);color:var(--on-dark-mute);line-height:1.6}
/* the quantity only appears once the add-on is ticked, so it never asks a
   question the visitor has not opted into */
.stp{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;
  padding-top:.3rem}
.stp label{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--on-dark-mute)}
.stp input{width:5.5rem;background:none;border:0;
  border-bottom:1px solid var(--rule-dark);color:var(--cream);
  padding:.35rem 0;font-size:1rem}
.stp input:focus{outline:none;border-bottom-color:var(--champagne)}
.stp__v{margin-left:auto;font-family:var(--serif);font-weight:300;
  font-size:1.15rem;color:var(--champagne)}

@media (min-width:720px){
  .pk{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (pointer:coarse){
  .stp input{font-size:16px;padding:.6rem 0}
}

/* thumbs need a target, and the chips are the densest thing in the dialog */
@media (pointer:coarse){
  .chip{padding:.85em 1.4em}
  .lnk__x,.fl__x{width:44px;height:44px}
  /* the Edit label is small by design, so the target is grown around it with a
     pseudo-element rather than with padding, which would break the baseline it
     shares with the section heading. Same trick for "Add another link", whose
     underline would otherwise drift away from the text. */
  .rev__e::after,.addln::after{content:'';position:absolute;left:-12px;right:-12px;
    top:50%;height:44px;transform:translateY(-50%)}
  /* "Back" is short enough to fall a pixel under on a narrow phone */
  .inq__nav .cta--quiet{min-width:44px;justify-content:center}
}


.inq__nav{display:flex;align-items:center;justify-content:space-between;gap:var(--s5);flex-wrap:wrap;
  margin-top:var(--s7);padding-top:var(--s5);border-top:1px solid var(--rule-dark)}
.inq__meta{font-size:var(--t-sm);color:var(--champagne);flex:1;text-align:center;min-width:9rem}
.inq__meta b{font:400 1.25rem/1 var(--serif);color:var(--cream)}
.inq__nav .cta--fill{background:var(--cream);color:var(--olive-950)}
.inq__nav .cta--fill::before{background:var(--champagne)}

.inq__done{display:grid;place-content:center;justify-items:center;gap:var(--s5);text-align:center;
  flex:1;max-width:38rem;margin-inline:auto}
.inq__done .mark{width:64px;height:64px;color:var(--champagne)}
.inq__done h3{font-family:var(--serif);font-weight:300;font-size:clamp(1.9rem,4.6vw,3rem);line-height:1}
.inq__done p{color:var(--on-dark-soft)}

/* ------------------------------------------------------------- PAY BLOCK */
/* Sits on the done panel, which is dark ground, so everything here is the
   on-dark set. Rendered by js/paylink.js only once the server has signed an
   amount, so if payment is not configured none of this is ever on the page. */
.payb{width:100%;display:grid;justify-items:center;gap:var(--s3);
  margin-top:var(--s2);padding:var(--s6) var(--s5) var(--s5);
  border:1px solid rgba(217,201,169,.26);border-radius:var(--r-md);
  background:rgba(217,201,169,.045)}

.payb__k{font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--champagne)}

.payb__amt{display:flex;align-items:baseline;gap:.4rem;
  font-family:var(--serif);font-weight:300;color:var(--on-dark);line-height:1}
.payb__cur{font-size:.9rem;letter-spacing:.1em;color:var(--on-dark-mute)}
.payb__n{font-size:clamp(2.1rem,6vw,2.9rem)}

/* The itemisation, so the figure is shown rather than asserted. Only drawn
   when there is more than one line, since repeating a single total under
   itself reads as a mistake. */
.payb__l{list-style:none;width:100%;max-width:26rem;display:grid;gap:var(--s2);
  margin:var(--s1) 0 var(--s2);padding-top:var(--s3);
  border-top:1px solid rgba(217,201,169,.18);
  font-size:.82rem;color:var(--on-dark-soft)}
.payb__l li{display:flex;justify-content:space-between;gap:var(--s4);text-align:left}

/* The same inversion .send uses. Plain .cta--fill is a dark olive pill built
   for the ivory page, and on this panel it is dark on dark: legible, but it
   stops reading as the thing to press. Cream on olive is how every other
   primary action inside this dialog is drawn. */
.payb__go{width:100%;max-width:26rem;justify-content:center;
  background:var(--cream);color:var(--olive-950)}
.payb__go::before{background:var(--champagne)}

.payb__f{font-size:.78rem;line-height:1.55;color:var(--on-dark-mute);max-width:30rem}
.payb__ref{font-size:.7rem;letter-spacing:.08em;color:var(--on-dark-mute);opacity:.75}

/* ============================================================ BREAKPOINTS */
@media (min-width:601px){
  .flds{grid-template-columns:1fr 1fr}
  .send{grid-template-columns:1fr 1fr}
  .pf__pair{grid-template-columns:1fr 1fr}
}

@media (min-width:741px){
  .st__custom{gap:var(--s6)}
  .ft__grid{grid-template-columns:1.5fr 1fr 1fr 1.1fr}
  .inq{place-items:center;padding:var(--s5)}
  .inq__panel{width:min(62rem,100%);max-height:min(94svh,58rem);
    padding:var(--s8) var(--s8) var(--s7);border-radius:var(--r-xl);
    box-shadow:var(--sh-lg),var(--edge-dark)}
  .inq__close{right:var(--s6)}
}

@media (min-width:901px){
  .wy{grid-template-columns:.92fr 1.08fr;gap:var(--s9);align-items:center}
  .st__grid{grid-template-columns:repeat(3,1fr)}
  .op{border-bottom:0;border-right:1px solid var(--rule-dark);padding:var(--s7) var(--s6)}
  .op:first-child{padding-left:0}
  .op:last-child{border-right:0;padding-right:0}
}

@media (min-width:1025px){
  .ss{grid-template-columns:1.05fr .95fr;gap:var(--s9);align-items:start}
  .ss__mob{display:none}
  .ss__p-in{padding-bottom:var(--s5)}
  /* A solid plate in the brand olive sits behind the photograph, offset down
     and to the right, so the image reads as a card lifted off a backing board
     rather than a picture pasted onto the page. It is drawn as a hard-edged box-shadow
     with no blur and no spread, which takes the element's own corner radius
     for free and, unlike a pseudo-element, is painted outside the
     `overflow:hidden` this stage needs for its cross-fading layers.
     The soft shadow is listed first so it falls ON the plate. Against an olive
     this dark it barely registers, but the warm photograph against the deep
     green is separation enough on its own. */
  /* 3/2, not the 4/5 it was. The service photographs are landscape and two
     of them are composites an upright frame would have cut in half. */
  .ss__stage{display:block;position:sticky;top:calc(50svh - 22svh);aspect-ratio:3/2;
    overflow:hidden;background:var(--limestone-lt);
    --plate:clamp(16px,2.1vw,30px);
    border-radius:var(--r-xl);
    box-shadow:var(--edge),var(--sh-md),
               var(--plate) var(--plate) 0 0 var(--olive-700)}
  .ss__stage .lyr{position:absolute;inset:0;opacity:0;transform:scale(1.06);
    transition:opacity .9s var(--ease-out),transform 1.6s var(--ease-out)}
  .ss__stage .lyr.on{opacity:1;transform:scale(1)}
  .ss__stage .lyr img{width:100%;height:100%;object-fit:cover}
}

@media (max-width:1200px){
  .nav__links{gap:var(--s4)}
  .nav__links a{letter-spacing:.1em}
  .nav__side,.nav__end{gap:var(--s4)}
  .nav__emblem svg{width:38px;height:38px}
  .nav.solid .nav__emblem svg{width:33px;height:33px}
  .nav__cta{padding:.8em 1rem}
  .nav__logo{height:48px}
  .nav.solid .nav__logo{height:42px}
}

/* With every link on the bar there is nothing behind the menu button that is
   not already visible, so it goes. */
@media (min-width:1025px){
  .burger{display:none}
}

/* Both side tracks are an equal 1fr, so the heavier right side, three links
   plus the button, runs out of room before the left one does. Below this the
   whole set folds into the menu rather than being squeezed. */
@media (max-width:1024px){
  .nav__links{display:none}
  .nav__cta{display:none}
  /* masthead on the left, menu button on the right */
  .nav__in{gap:var(--s3)}
}

@media (max-width:900px){
  .nav__in{padding:.45rem .6rem}
  .nav__logo{height:44px}
  .nav.solid .nav__logo{height:39px}
  .nav__emblem svg{width:34px;height:34px}
  .nav.solid .nav__emblem svg{width:31px;height:31px}
  .burger{width:40px;height:40px}
  .fin__veil{background:linear-gradient(to top,rgba(20,22,15,.9),rgba(20,22,15,.8))}
  /* conversion bar, introduced after the hero */
  .sticky-cta{display:flex;position:fixed;left:var(--gutter);right:var(--gutter);
    bottom:calc(.9rem + env(safe-area-inset-bottom));z-index:var(--z-float);
    align-items:center;justify-content:center;gap:1rem;
    padding:1.05rem 1.5rem;border-radius:var(--r-pill);
    background:var(--olive-700);color:var(--cream);box-shadow:var(--sh-md);
    font:500 .9rem/1 var(--sans);letter-spacing:.006em;
    transform:translateY(200%);transition:transform var(--d) var(--ease-out)}
  .sticky-cta:active{transform:scale(.985)}
  .sticky-cta.in{transform:none}
  .wa{bottom:calc(4.6rem + env(safe-area-inset-bottom));height:46px;padding:0 13px}
  /* lifted over the conversion bar on the same line as the WhatsApp pill */
  .backb{bottom:calc(4.6rem + env(safe-area-inset-bottom));height:46px;
    padding:0 .95rem 0 .7rem;gap:.55rem}
  .backb__t{letter-spacing:.14em}
  .wa__ico{width:20px;height:20px}
}

/* ------------------------------------------------- SHORT / LANDSCAPE */
/* A phone on its side is about 375px tall, and the hero's contents came to
   432px, so it pushed its own call to action off the screen and the dialog's
   Continue landed below the fold. Everything gets shorter rather than smaller:
   less padding first, type second. The hero keeps its full height, so the
   section below it still waits for a scroll. */
@media (orientation:landscape) and (max-height:520px){
  .hero{padding-top:6rem;padding-bottom:2rem}
  .hero__h{font-size:clamp(1.9rem,7.2vw,3.1rem);margin-bottom:.9rem}
  .hero__line{margin-bottom:1.1rem;font-size:1rem}
  /* a landscape phone has width to spare and no height at all, so the facts
     give up their air rather than their place */
  .hf{margin-top:clamp(.8rem,2vw,1.2rem);padding-top:.85rem}
  .hero__acts{margin-top:1rem}
  .hf__v{font-size:1rem}
  .hf__r{margin-bottom:.2rem}
  .hero__veil{background:
    radial-gradient(110% 120% at 22% 104%,rgba(18,20,14,.66),rgba(18,20,14,0) 84%),
    linear-gradient(to top,rgba(18,20,14,.56),rgba(18,20,14,.3) 40%,rgba(18,20,14,0) 82%),
    linear-gradient(to bottom,rgba(18,20,14,.52),rgba(18,20,14,.3) 16%,rgba(18,20,14,0) 34%)}
  .inq__panel{padding-top:var(--s5)}
  .inq__rail{margin-bottom:var(--s4)}
  /* Back / total / Continue sticks to the bottom of the scrolling panel, so
     the primary action is reachable without hunting for it. It stays in flow,
     so nothing is hidden underneath it. */
  .inq__panel{padding-bottom:0}
  .inq__nav{position:sticky;bottom:0;margin-top:auto;
    background:var(--olive-950);
    padding-bottom:calc(var(--s5) + env(safe-area-inset-bottom));
    box-shadow:0 -16px 26px -14px rgba(20,22,15,.95)}

  .menu{padding-top:5rem}
  .fin{min-height:auto}
}

/* ------------------------------------------------------- TOUCH TARGETS */
/* Everything you can tap gets to 44px on a touch screen. Several of these
   were fine with a mouse and much too small with a thumb: the footer links
   were 16px tall, the text buttons 35px. Where the target grows, the list gap
   shrinks to match, so the footer does not get dramatically longer.

   Keyed on the pointer, not just the width: a tablet is 768px or wider and is
   still a thumb. The width arm matches the navigation's own breakpoint, so
   "compact layout" and "touch sizing" are the same threshold. */
@media (pointer:coarse),(max-width:1024px){
  .cta--line{padding:1.05em 0}
  .cta--quiet{padding:1.05em .2em}
  .chip{padding:.85em 1.5em}
  .sp__jump{gap:0 var(--s5)}
  .sp__jump a{padding:.82rem 0}
  /* tel: and mailto: are the highest-intent taps on a phone, and these were
     22px tall */
  .menu__contact{gap:0}
  .menu__contact a{display:inline-block;padding:.7rem 0}
  .burger{width:44px;height:44px}
  /* the panel runs to the bottom edge under viewport-fit=cover, so the last
     control has to clear the home indicator */
  .menu{padding-bottom:calc(var(--s7) + env(safe-area-inset-bottom))}
  /* Back / total / Continue sticks to the bottom of the scrolling panel, so
     the primary action is reachable without hunting for it. It stays in flow,
     so nothing is hidden underneath it. */
  .inq__panel{padding-bottom:0}
  .inq__nav{position:sticky;bottom:0;margin-top:auto;
    background:var(--olive-950);
    padding-bottom:calc(var(--s5) + env(safe-area-inset-bottom));
    box-shadow:0 -16px 26px -14px rgba(20,22,15,.95)}

  /* Footer nav links become full width rows so a thumb has something to hit.
     The opening hours are a <ul> in the same column and are NOT links, so
     they have to be held out: this rule was flattening their flex rows back
     to block, which dropped the day and the time onto the same line with no
     space between them. It read as "MON TO FRI8:30am to 5:00pm". */
  .ft__col ul:not(.oh__list){gap:0}
  .ft__col ul:not(.oh__list) a{display:block;padding:.72rem 0}
  .ft__col ul:not(.oh__list) li{display:block}
  .nl__go{padding:1.22em 1.3em}
  .faq__more-a{display:inline-block;padding:.78rem .35rem}
  .rv__rail{padding-block:2px}
  /* 16px is the threshold under which iOS zooms the page on focus, which then
     leaves the visitor scrolled sideways on a page that has no sideways */
  .nl__row input,.f input,.f textarea,.f select{font-size:16px}
  /* the placeholder tag was 8.5px, which is a squint on a phone */
  .ph{font-size:11px;padding:.34em .62em}
}

@media (max-width:740px){
  /* the headline and the supporting line run the full width on a phone, so the
     pool has to as well, the left-weighted one would leave the right-hand
     ends of both sitting on bare daylight */
  /* Deepened for the facts row. The first two labels sit higher up the frame
     than the buttons did, where the old ramp had already thinned out, and
     they were reading 4.03 and 4.23 against the brightest pixels under them.
     A taller pool and about six points more body through the middle of the
     ramp carries the worst of them at 4.97. */
  /* Stretched again, gently, because the buttons moved below the facts and
     pushed the whole type block about 115px further up the frame. Reaching
     the labels by depth alone would have wanted a ramp heavy enough to take
     roughly a third of the light out of the photograph; this one is mild and
     the labels take cream instead of champagne up here to make up the rest. */
  .hero__veil{background:
    radial-gradient(120% 100% at 50% 104%,rgba(18,20,14,.74),rgba(18,20,14,0) 82%),
    linear-gradient(to top,rgba(18,20,14,.58),rgba(18,20,14,.53) 28%,
      rgba(18,20,14,.39) 50%,rgba(18,20,14,.15) 66%,rgba(18,20,14,0) 78%),
    /* The crown carries the hours mark here too, and the mark lost its pool
       at the same time the desktop one did. It sits at about 10% down on a
       phone, so the deep part is shorter and higher than the desktop ramp
       rather than simply copied from it. */
    /* the plateau reaches 20% now, because the mark moved down to 17% */
    linear-gradient(to bottom,
      rgba(18,20,14,.62),
      rgba(18,20,14,.60) 10%,
      rgba(18,20,14,.58) 20%,
      rgba(18,20,14,.30) 27%,
      rgba(18,20,14,0) 36%)}
  .rv__i{width:clamp(230px,74vw,290px)}
  .rv__track{gap:var(--s4)}
  /* tighter vertical rhythm, mobile visitors should reach the pricing fast */
  :root{--bay:clamp(3.25rem,7.5vw,4.5rem)}
  /* the two supporting projects become a swipeable row, so they cost the
     height of one image instead of two */
  .pf__pair{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:76%;
    gap:var(--s4);overflow-x:auto;scroll-snap-type:x mandatory;
    margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter);
    scroll-padding-inline:var(--gutter);
    scrollbar-width:none;-ms-overflow-style:none}
  .pf__pair::-webkit-scrollbar{display:none}
  .pf__s{scroll-snap-align:start}
  .pf__cmp{margin-top:var(--s7)}
  .cmp{aspect-ratio:4/5}
  .pf__fig--over{max-height:none}
  .pf__fig{aspect-ratio:4/3}
  /* and the before and after frame follows the featured project, because the
     client asked for the two to be the same and because 16/9 across a 335px
     phone is a 188px band */
  .cmpx__stage{aspect-ratio:4/3}
  /* One action, then a quieter way in, rather than two pills of equal weight
     competing for the same thumb. The consultation keeps the button and hugs
     its own words instead of stretching across the screen; the site visit
     steps down to a ruled link underneath it. Both keep a 44px target. */
  .hero__acts{grid-column:2;grid-row:2;
    flex-direction:column;align-items:flex-start;gap:.35rem;width:auto;
    margin-top:0;align-self:start}
  /* Trimmed so the pill clears its cell at 375px without its label wrapping.
     The horizontal padding is what gives way; the height is pinned at 44px,
     because a narrower button is a design choice and a shorter one is a
     thumb missing its target. */
  .hero__acts>.cta:first-child{padding:.6em 1.15em;font-size:.82rem;
    min-height:44px;box-sizing:border-box}
  .hero__acts>.cta:first-child{width:auto;justify-content:center}
  .hero__acts>.cta:last-child{width:auto;padding:0;min-height:44px;
    background:none;border-radius:0;box-shadow:none;overflow:visible;
    color:var(--cream);font-size:var(--t-xs);letter-spacing:.2em;
    text-transform:uppercase;transform:none}
  /* the fill wipe belongs to a pill, and this is no longer one */
  .hero__acts>.cta:last-child::before{display:none}
  .hero__acts>.cta:last-child::after{content:'';position:absolute;
    left:0;right:0;bottom:11px;height:1px;background:currentColor;opacity:.55}
  .hero__acts>.cta:last-child:hover,
  .hero__acts>.cta:last-child:active,
  .hero__acts>.cta:last-child:focus-visible{transform:none;box-shadow:none}
  .hero__acts>.cta:last-child:hover::after{opacity:1}
  .fin__acts{gap:var(--s4);width:100%}
  .fin__acts .cta--fill,.fin__acts .cta--line-light{width:100%;justify-content:center}
  .ft__base{gap:.5rem}
  .ft__dot-s{display:none}
  /* the WhatsApp float is fixed bottom right and, at the very end of the page,
     sat straight on top of the centred copyright. Give the footer room to
     clear it, plus the home indicator on iOS. */
  .ft{padding-bottom:calc(5.75rem + env(safe-area-inset-bottom))}
}

/* =================================================== FOOTER SOCIAL ICONS */
/* Only platforms with a url are printed, so this never has to reserve room
   for an icon that is not there. */
/* Each platform is named under its glyph and the row is opened right out.
   Five discs at a third of a rem apart read as one undifferentiated strip of
   furniture, and the reader has to recognise every icon in it to know where
   any of them go. */
.ft__soc{display:flex;justify-content:center;flex-wrap:wrap;
  gap:clamp(1.25rem,4.5vw,3.5rem);
  margin:var(--s7) auto 0;max-width:var(--maxw);list-style:none;padding:0}
.ft__soc a{display:grid;justify-items:center;gap:.65rem;min-width:66px;
  color:var(--on-dark-soft);
  transition:color var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.ft__soc-i{width:46px;height:46px;display:grid;place-items:center;border-radius:50%;
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.16);
  transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease)}
.ft__soc svg{width:20px;height:20px}
.ft__soc-n{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  white-space:nowrap}
.ft__soc a:hover{color:var(--cream)}
.ft__soc a:hover .ft__soc-i{background:rgba(243,239,230,.1);
  box-shadow:inset 0 0 0 1px rgba(203,176,125,.5)}
.ft__soc a:active{transform:scale(.96)}
.ft__soc a:focus-visible{outline:2px solid var(--champagne);outline-offset:6px;
  border-radius:var(--r-md)}

/* ============================================= JOURNAL, CARDS AND GRIDS */
.pc{display:grid;gap:var(--s4);align-content:start;
  transition:transform var(--d) var(--ease)}
.pc:hover{transform:translateY(-3px)}
.pc__fig{display:block;border-radius:var(--r-lg);overflow:hidden;
  aspect-ratio:4/3;background:var(--limestone-lt);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.07)}
/* a picture element is inline by default, so height:100% on the image inside
   resolves against nothing and the figure keeps a band of empty box below it */
.pc__fig picture,.ar__cover picture,.wt__tf picture{display:block;width:100%;height:100%}
.pc__fig img{width:100%;height:100%;object-fit:cover;display:block;
  object-position:50% var(--pc-focus,50%);
  transition:transform 1.1s var(--ease-out)}
.pc:hover .pc__fig img{transform:scale(1.04)}
.pc__cap{display:grid;gap:.55rem}
.pc__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .85rem;
  font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-muted)}
.pc__tag{padding:.3em .8em;border-radius:var(--r-pill);
  background:rgba(65,68,55,.08);color:var(--ink);letter-spacing:.14em}
.pc__t{display:block;font-family:var(--serif);font-weight:300;
  font-size:clamp(1.25rem,2.4vw,1.7rem);line-height:1.15;letter-spacing:-.015em;
  text-wrap:balance;color:var(--ink)}
/* Her excerpts are the opening paragraph of the post, which is the right
   thing to put in front of a reader and far too much for a card. Three lines
   on a tile, four on the lead, and the rest is behind the click. */
.pc__x{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;
  overflow:hidden;color:var(--ink-muted);line-height:1.7;
  font-size:var(--t-sm);text-wrap:pretty}

.pc--lead .pc__fig{aspect-ratio:16/9}
.pc--lead .pc__t{font-size:clamp(1.6rem,3.6vw,2.6rem)}
.pc--lead .pc__x{font-size:1rem;max-width:56ch;-webkit-line-clamp:4}

/* ---- the homepage preview ---- */
/* the light limestone, not the dark one: `--ink-muted` clears 4.5:1 on
   #D5CEC1 and only manages 3.87 on #C4BCAC */
.jr{padding:var(--bay) var(--gutter);background:var(--limestone-lt);position:relative}
.jr__head{margin-bottom:var(--s7)}
.jr__note{max-width:var(--maxw);margin:0 auto var(--s6);font-size:var(--t-sm);
  font-style:italic;color:var(--ink-muted)}
.jr__grid{max-width:var(--maxw);margin:0 auto;display:grid;gap:var(--s6)}
.jr__foot{max-width:var(--maxw);margin:var(--s7) auto 0;display:flex;
  justify-content:center}

/* ---- the journal page ---- */
.jh{padding:calc(var(--bay) + 4rem) var(--gutter) var(--s7);text-align:center;
  background:var(--ivory)}
.jh__h{font-family:var(--serif);font-weight:300;margin-top:var(--s4);
  font-size:clamp(2.2rem,6vw,4.6rem);line-height:1.02;letter-spacing:-.025em;
  text-wrap:balance}
.jh__h em{font-style:italic;color:var(--bronze)}
.jh__line{margin:var(--s5) auto 0;max-width:46ch;color:var(--ink-muted);
  line-height:1.7;text-wrap:pretty}

.jl{padding:0 var(--gutter) var(--bay);background:var(--ivory)}
.jl__note{max-width:var(--maxw);margin:0 auto var(--s6);font-size:var(--t-sm);
  font-style:italic;color:var(--ink-muted);text-align:center}
.jl__grid{max-width:var(--maxw);margin:0 auto;display:grid;gap:var(--s6)}
.jl__empty{max-width:var(--maxw);margin:0 auto;text-align:center;
  color:var(--ink-muted);font-style:italic;padding:var(--s7) 0}

/* ---------------------------------------------- THE PHONE, LESS SCROLL */
/* The cards pair up under the lead one. The lead keeps its excerpt and the
   whole width; the two below it give theirs up, because a title is a label
   and survives a 160px measure while a paragraph does not. */
@media (max-width:759px){
  .jr__grid,.jl__grid{grid-template-columns:repeat(2,minmax(0,1fr));
    gap:var(--s5) var(--s4)}
  .jr__grid .pc--lead,.jl__grid .pc--lead{grid-column:1/-1}
  .jr__grid .pc:not(.pc--lead) .pc__x,
  .jl__grid .pc:not(.pc--lead) .pc__x{display:none}
  .jr__grid .pc:not(.pc--lead) .pc__t,
  .jl__grid .pc:not(.pc--lead) .pc__t{font-size:1.02rem;line-height:1.25}
}

@media (min-width:760px){
  .jr__grid,.jl__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pc--lead{grid-column:1/-1}
}
@media (min-width:1100px){
  .jr__grid,.jl__grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pc--lead{grid-column:1/-1;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);
    gap:var(--s6);align-items:center}
  .pc--lead .pc__fig{aspect-ratio:4/3}
}

/* ================================================== JOURNAL, ONE ARTICLE */
/* ================================================= ONE POST, AS A PAGE */
/* The journal reads as a book. The limestone is the surface the page is
   lying on; everything from the running head to the folio sits on paper.

   The writing is set in the serif rather than the interface sans, which is
   the single change that does most of the work: a book is not set in a UI
   font. It also buys real italics, because Cormorant is loaded with an italic
   and Montserrat is not, so the emphasis in her posts was being drawn by the
   browser as a slanted upright until now. */
.ar{padding:calc(var(--bay) + 3rem) var(--gutter) var(--bay);
  background:var(--limestone-lt)}

/* ---- the sheet ---- */
.ar__sheet{position:relative;max-width:52rem;margin:var(--s6) auto 0;
  padding:clamp(2.2rem,5vw,3.6rem) clamp(1.5rem,5vw,4.5rem) clamp(2.4rem,5vw,3.6rem);
  background:var(--grain),var(--ivory);
  background-size:160px 160px,auto;
  border-radius:var(--r-sm);
  box-shadow:
    inset 0 0 0 1px rgba(65,68,55,.10),
    0 2px 6px rgba(20,22,15,.12),
    0 46px 84px -38px rgba(20,22,15,.5)}
/* the leaves underneath, showing at the fore edge on both sides. The same
   device the process book uses, so the two books on this site are the same
   book. */
.ar__sheet::before,.ar__sheet::after{content:'';position:absolute;
  top:1.1%;bottom:1.1%;width:10px;border-radius:3px;pointer-events:none}
.ar__sheet::before{left:-9px;
  background:repeating-linear-gradient(to right,
    rgba(65,68,55,.16) 0 1px,rgba(255,255,255,.55) 1px 3px)}
.ar__sheet::after{right:-9px;
  background:repeating-linear-gradient(to left,
    rgba(65,68,55,.16) 0 1px,rgba(255,255,255,.55) 1px 3px)}
@media (max-width:620px){
  /* no room for a fore edge on a phone, and a 9px sliver either side of a
     335px page reads as a rendering fault rather than as paper */
  .ar__sheet::before,.ar__sheet::after{display:none}
}

/* ---- the running head ---- */
.ar__rh{display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--s5);margin:0 0 clamp(2rem,4.5vw,3.2rem);padding-bottom:var(--s3);
  border-bottom:1px solid var(--rule);
  font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--bronze)}
.ar__rh span:last-child{color:var(--ink-muted);letter-spacing:.2em}
/* At .24em the two halves of the running head did not fit across a 287px
   page and each broke onto two lines, which is not a running head. */
@media (max-width:560px){
  .ar__rh{letter-spacing:.12em;gap:var(--s4);font-size:.64rem}
  .ar__rh span:last-child{letter-spacing:.12em}
}

/* ---- the chapter opening ---- */
.ar__mark{display:block;width:clamp(42px,7vw,56px);aspect-ratio:1/1;
  margin:0 auto clamp(1.2rem,3vw,1.8rem);color:var(--bronze);opacity:.5}
.ar__mark svg{width:100%;height:100%;display:block}
.ar__head{max-width:40rem;margin:0 auto;text-align:center}
/* the rule a book sets between a chapter title and its first line */
.ar__head::after{content:'';display:block;width:54px;height:1px;
  background:var(--bronze);opacity:.5;
  margin:clamp(1.5rem,3.5vw,2.2rem) auto 0}
.ar__back{display:inline-flex;align-items:center;min-height:44px;
  max-width:52rem;margin-inline:auto;
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-muted);border-bottom:1px solid transparent;
  transition:color var(--d) var(--ease),border-color var(--d) var(--ease)}
.ar__back:hover{color:var(--ink);border-bottom-color:rgba(65,68,55,.4)}
.ar__meta{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:.5rem .85rem;margin-top:var(--s5);
  font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-muted)}
.ar__t{font-family:var(--serif);font-weight:300;margin-top:var(--s4);
  font-size:clamp(2rem,5.4vw,4rem);line-height:1.04;letter-spacing:-.025em;
  text-wrap:balance}
/* A band across the top of the piece rather than a 729px wall between the
   headline and the first line of it. The reader came here to read. */
.ar__cover{max-width:100%;margin:var(--s7) auto 0;border-radius:var(--r-md);
  overflow:hidden;height:clamp(15rem,40vh,23rem);background:var(--limestone-lt);
  box-shadow:var(--sh-md)}
/* An upright cover is a plate on the page, not a band. In the band it would
   have kept a horizontal slice across the middle of the photograph, which on
   a portrait of somebody means their chest. */
.ar__cover--tall{width:min(100%,22rem);height:auto;aspect-ratio:2/3}
.ar__cover img{width:100%;height:100%;object-fit:cover;display:block}

/* one measure for the whole article, so the reading line never shifts */
/* Cormorant has a small x-height, so it reads a size smaller than it is set:
   16.8px of it looked slighter than the 15px sans it replaced. At 19.8px it
   has the same apparent size and 34rem lands the measure on 64 characters,
   which is what a book is set to. The old 38rem of sans ran past 80. */
.ar__body{max-width:34rem;margin:0 auto;padding:clamp(1.8rem,4vw,2.8rem) 0 0}
.ar__lead{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.22rem,2.4vw,1.55rem);line-height:1.5;color:var(--ink);
  margin-bottom:var(--s6);text-wrap:pretty}
/* the chapter opens on a dropped capital, the way a book opens one. It is the
   first letter of her own first sentence, so it costs no words. */
.ar__lead::first-letter{float:left;font-weight:300;
  font-size:3.1em;line-height:.76;padding:.05em .09em 0 0;
  color:var(--bronze)}
.ar__p{font-family:var(--serif);font-weight:400;
  font-size:clamp(1.12rem,1.6vw,1.24rem);line-height:1.72;
  color:var(--ink-soft);margin:0 0 .8em;text-wrap:pretty}

/* Book setting indents the first line and drops the space between paragraphs.
   That is not right here: her third post is written in very short paragraphs
   that are doing the rhythm of the piece, and run together they would read as
   one grey slab. The space stays; the serif, the measure, the paper and the
   dropped capital carry the book. */

/* ---- the folio ---- */
.ar__folio{display:flex;align-items:center;justify-content:center;
  gap:clamp(.9rem,2.5vw,1.6rem);margin:clamp(2.4rem,5vw,3.6rem) 0 0;
  font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-muted);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.ar__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.35rem,2.8vw,1.9rem);line-height:1.2;letter-spacing:-.015em;
  margin:var(--s7) 0 var(--s4)}
.ar__ul{margin:0 0 var(--s5);padding-left:1.15rem;display:grid;gap:.5rem}
.ar__ul li{font-family:var(--serif);font-weight:400;
  font-size:clamp(1.12rem,1.6vw,1.24rem);line-height:1.68;color:var(--ink-soft)}
.ar__ul li::marker{color:var(--bronze)}
/* ---- a numbered run where every point carries its own heading ---- */
/* Counted by the list rather than typed into the wording, so the numbers can
   never disagree with the order. Leading zeros to match the numbering used by
   the process book and the about chapters, and lining figures because
   Cormorant sets oldstyle by default and ran 01 together as the word OI. */
.ar__steps{list-style:none;margin:var(--s6) 0 var(--s6);padding:0;
  display:grid;gap:var(--s6);counter-reset:step}
.ar__step{counter-increment:step;position:relative;
  padding-left:clamp(2.5rem,7vw,3.4rem)}
.ar__step::before{content:counter(step,decimal-leading-zero);
  position:absolute;left:0;top:-.06em;
  font-family:var(--serif);font-weight:300;
  font-size:clamp(1.4rem,3vw,1.85rem);line-height:1;letter-spacing:.01em;
  color:var(--bronze);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.ar__step-h{font-family:var(--serif);font-weight:400;
  font-size:clamp(1.12rem,2.3vw,1.4rem);line-height:1.28;letter-spacing:-.01em;
  color:var(--ink);margin:0 0 .45rem;text-wrap:pretty}
.ar__step-p{font-family:var(--serif);font-weight:400;
  font-size:clamp(1.12rem,1.6vw,1.24rem);line-height:1.72;
  color:var(--ink-soft);margin:0;text-wrap:pretty}

/* ---- the sign-off ---- */
/* She ends every post with her name behind a dash. The site carries no
   dashes, so the rule above the name does the work the dash was doing. */
.ar__sign{margin:var(--s8) 0 0;padding-top:var(--s5);
  border-top:1px solid var(--rule);
  font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:clamp(1.15rem,2.4vw,1.45rem);line-height:1;color:var(--bronze)}
/* A pull quote already closes on a rule. Following it with the signature's own
   rule printed two hairlines 25px apart, which reads as a mistake rather than
   as punctuation, so the signature drops its own when it follows one. */
.ar__q + .ar__sign{border-top:0;padding-top:0;margin-top:clamp(2rem,4.5vw,3rem)}

/* ---- inline emphasis ---- */
/* Cormorant is loaded at 300, 400 and 500 upright and 300 and 400 italic, so
   both of these are real cuts. While the body was set in Montserrat, which
   ships no italic here, every one of her italics was a slanted upright drawn
   by the browser. */
.ar__body strong{font-weight:500;color:var(--ink)}
.ar__body em{font-style:italic}

/* A rule above and below with the words centred between them, which is how a
   book sets a quotation standing on its own. The bar down the left was a
   blockquote out of a web page. */
.ar__q{margin:clamp(2.2rem,5vw,3.4rem) 0;padding:clamp(1.5rem,3.5vw,2.2rem) 0;
  border-block:1px solid var(--rule);text-align:center}
.ar__q p{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:clamp(1.3rem,2.8vw,1.75rem);line-height:1.38;color:var(--ink);
  text-wrap:balance;margin:0}
.ar__q cite{display:block;margin-top:var(--s4);font-style:normal;
  font-size:var(--t-xs);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-muted)}
/* images break the measure, which is what makes the page read as editorial
   rather than as a long column of text */
/* Inside a sheet, a full bleed figure would tear straight through the paper.
   A plate in a book sits within the text block, so this one does too. */
.ar__f{margin:clamp(2rem,4vw,3rem) 0;width:100%}
.ar__f picture,.ar__f img{display:block;width:100%}
.ar__f img{max-height:76vh;object-fit:cover}
.ar__f figcaption{max-width:38rem;margin:var(--s4) auto 0;padding:0 var(--gutter);
  font-size:var(--t-xs);color:var(--ink-muted);line-height:1.6;text-align:center}
.ar__none{max-width:38rem;margin:0 auto;padding:var(--s7) 0;text-align:center;
  color:var(--ink-muted)}
.ar__none a{border-bottom:1px solid rgba(65,68,55,.4)}

@media (min-width:1100px){
  /* inside the measure the full-bleed image is too much, so it steps back to
     a generous but contained width */
  .ar__f{margin-inline:-7rem;width:auto;max-width:none}
  .ar__f figcaption{padding:0}
}

/* ---- sharing and the walk to the next post ---- */
.ar__foot{max-width:52rem;margin:clamp(2.2rem,5vw,3.4rem) auto 0}
.ar__share{display:grid;gap:var(--s4);padding:var(--s6) 0;
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.ar__share-l{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-muted)}
.ar__share-b{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem}
.ar__s{width:44px;height:44px;display:grid;place-items:center;border-radius:50%;
  color:var(--ink-muted);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.14);
  transition:color var(--d) var(--ease),background var(--d) var(--ease),
             box-shadow var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.ar__s svg{width:19px;height:19px}
.ar__s-l{font-family:var(--serif);font-size:1.05rem;line-height:1}
.ar__s:hover{color:var(--cream);background:var(--olive-700);
  box-shadow:inset 0 0 0 1px var(--olive-700)}
.ar__s:active{transform:scale(.94)}
.ar__copied{font-size:var(--t-xs);letter-spacing:.1em;color:var(--bronze);
  min-width:7ch}

.ar__walk{display:grid;gap:var(--s5);margin-top:var(--s6)}
/* on limestone now, so the panel is paper rather than a darker tint */
.ar__w{display:grid;gap:.35rem;padding:var(--s5);border-radius:var(--r-md);
  background:rgba(251,249,244,.62);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.08);
  transition:background var(--d) var(--ease)}
.ar__w:hover{background:var(--ivory)}
.ar__w--next{text-align:right}
.ar__w-l{font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-muted)}
.ar__w-t{font-family:var(--serif);font-weight:300;font-size:1.15rem;
  line-height:1.25;color:var(--ink);text-wrap:balance}

.ar__more{padding:var(--bay) var(--gutter);background:var(--limestone-lt)}
.ar__more-t{font-family:var(--serif);font-weight:300;text-align:center;
  font-size:clamp(1.5rem,3.4vw,2.4rem);letter-spacing:-.02em;
  margin-bottom:var(--s7)}

@media (min-width:640px){
  .ar__walk{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (pointer:coarse){
  .wt__t{flex-basis:clamp(11rem,54vw,14rem)}
}

/* ============================================ 2c · INVESTMENT ESTIMATOR */
.es{padding:var(--bay) var(--gutter);background:var(--ivory)}
.es__head{margin-bottom:var(--s7)}
.es__line{margin-top:var(--s4);color:var(--ink-muted);max-width:46ch;line-height:1.7}
.es__shell{max-width:58rem;margin:0 auto}

/* The card is the one dark object in a light section, so it has to hold its
   own weight: a ground that falls off toward the bottom, a hairline inside the
   edge to catch the light, and a shadow deep enough to lift it off the page. */
.es__card{position:relative;overflow:hidden;
  border-radius:clamp(20px,2.4vw,30px);
  padding:clamp(1.75rem,4.2vw,3.25rem);
  color:var(--cream);
  background:
    radial-gradient(120% 90% at 82% 0%,rgba(203,176,125,.13),transparent 58%),
    linear-gradient(168deg,#22251B 0%,var(--olive-950) 52%,#101208 100%);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.09),
             inset 0 1px 0 rgba(243,239,230,.07),
             0 2px 6px rgba(20,22,15,.14),
             0 34px 70px -34px rgba(20,22,15,.62)}

/* the step number, oversized behind the question the way the rest of the site
   sets its numerals */
/* bottom right and half off the edge, so it reads as texture in the corner
   rather than a second number competing with "Step 1 of 9" at the top */
.es__ghost{position:absolute;bottom:clamp(-3.5rem,-7vw,-2rem);
  right:clamp(.5rem,2.5vw,1.75rem);
  font-family:var(--serif);font-weight:300;
  font-size:clamp(7rem,18vw,13rem);line-height:.8;letter-spacing:-.05em;
  color:var(--champagne);opacity:.07;pointer-events:none;user-select:none}

/* ---- progress ---- */
.es__top{position:relative;display:flex;align-items:center;
  justify-content:space-between;gap:var(--s5);flex-wrap:wrap-reverse}
.es__seg{display:flex;gap:5px;list-style:none;padding:0;margin:0;flex:1;min-width:12rem}
.es__seg li{flex:1;height:3px;border-radius:3px;background:rgba(243,239,230,.14);
  transition:background .45s var(--ease-out),transform .45s var(--ease-out)}
.es__seg li.done{background:rgba(217,201,169,.55)}
.es__seg li.on{background:var(--champagne);transform:scaleY(1.7)}
.es__step{flex:none;font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--champagne)}

/* ---- the question ---- */
/* a fieldset carries a UA border, padding and a notched legend. Without this
   reset the question sits inside a grey box with a gap cut through the top. */
.es__q{display:none;border:0;padding:0;margin:0;min-width:0;
  margin-top:clamp(2rem,4.5vw,3rem)}
.es__q.on{display:block;animation:esIn .5s var(--ease-out) both}
@keyframes esIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.es__l{padding:0;font-family:var(--serif);font-weight:300;
  font-size:clamp(1.5rem,3.4vw,2.5rem);line-height:1.1;letter-spacing:-.02em;
  text-wrap:balance;color:var(--cream)}
.es__hint{margin-top:var(--s3);font-size:var(--t-xs);letter-spacing:.06em;
  color:var(--on-dark-mute)}

/* ---- options as cards ---- */
.es__opts{margin-top:clamp(1.5rem,3.4vw,2.25rem);display:grid;gap:.6rem}
.es__o{display:flex;align-items:center;gap:var(--s4);text-align:left;
  min-height:56px;padding:.95rem 1.25rem;border-radius:var(--r-md);
  color:var(--cream);font-size:var(--t-sm);
  background:rgba(243,239,230,.035);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.13);
  transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.es__o:hover{background:rgba(243,239,230,.08);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.3);transform:translateY(-1px)}
.es__o:active{transform:translateY(0) scale(.995)}
.es__ol{flex:1;min-width:0;line-height:1.4}

/* the mark: a ring that fills for a single choice, a square that ticks for a
   multiple one, so the two kinds of question never look the same */
.es__mk{flex:none;position:relative;width:20px;height:20px;border-radius:50%;
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.36);
  transition:box-shadow var(--d) var(--ease),background var(--d) var(--ease)}
.es__mk--box{border-radius:6px}
.es__mk::after{content:'';position:absolute;inset:0;margin:auto;
  width:8px;height:8px;border-radius:50%;background:var(--olive-950);
  opacity:0;transform:scale(.4);
  transition:opacity var(--d-fast) var(--ease),transform var(--d-fast) var(--ease)}
.es__mk--box::after{width:5px;height:9px;border-radius:0;background:none;
  border:solid var(--olive-950);border-width:0 1.6px 1.6px 0;
  transform:rotate(45deg) scale(.4);margin:0;
  left:6px;top:3px;right:auto;bottom:auto}

.es__o[aria-checked="true"],.es__o[aria-pressed="true"]{
  background:rgba(217,201,169,.14);
  box-shadow:inset 0 0 0 1px var(--champagne)}
.es__o[aria-checked="true"] .es__mk,.es__o[aria-pressed="true"] .es__mk{
  background:var(--champagne);box-shadow:inset 0 0 0 1px var(--champagne)}
.es__o[aria-checked="true"] .es__mk::after{opacity:1;transform:scale(1)}
.es__o[aria-pressed="true"] .es__mk--box::after{opacity:1;transform:rotate(45deg) scale(1)}

/* ---- the counter ---- */
.es__count{margin-top:clamp(1.75rem,4vw,2.5rem);
  display:flex;align-items:center;justify-content:center;gap:clamp(1.5rem,4vw,2.5rem);
  padding:clamp(1.25rem,3vw,2rem);border-radius:var(--r-lg);
  background:rgba(243,239,230,.035);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.1)}
.es__pm{flex:none;width:52px;height:52px;display:grid;place-items:center;
  border-radius:50%;color:var(--cream);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.28);
  transition:background var(--d) var(--ease),box-shadow var(--d) var(--ease),
             transform var(--d-fast) var(--ease)}
.es__pm svg{width:20px;height:20px}
.es__pm:hover{background:rgba(243,239,230,.1);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.5)}
.es__pm:active{transform:scale(.94)}
.es__n{font-family:var(--serif);font-weight:300;font-size:clamp(2.6rem,7vw,4rem);
  line-height:1;min-width:2.6ch;text-align:center;color:var(--champagne);
  letter-spacing:-.03em}

/* ---- navigation ---- */
.es__nav{position:relative;z-index:1;display:flex;align-items:center;
  justify-content:space-between;gap:var(--s5);
  margin-top:clamp(2rem,4.5vw,3rem);padding-top:clamp(1.25rem,3vw,1.75rem);
  border-top:1px solid rgba(243,239,230,.12)}
.es__back{display:inline-flex;align-items:center;gap:.5em;min-height:44px;
  padding:.5em .2em;font-size:var(--t-xs);letter-spacing:.18em;
  text-transform:uppercase;color:var(--on-dark-mute);
  transition:color var(--d) var(--ease),opacity var(--d) var(--ease)}
.es__back svg{width:16px;height:16px;
  transition:transform var(--d) var(--ease-out)}
.es__back:hover{color:var(--cream)}
.es__back:hover svg{transform:translateX(-3px)}
.es__back.off{opacity:0;pointer-events:none}

/* the primary reads as ready, not as an afterthought sitting in the corner */
.es__go{display:inline-flex;align-items:center;gap:.6em;
  min-height:48px;padding:.8em 1.6em;border-radius:var(--r-pill);
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--olive-950);background:var(--cream);
  box-shadow:0 1px 2px rgba(20,22,15,.2),0 10px 24px -12px rgba(20,22,15,.6);
  transition:background var(--d) var(--ease),transform var(--d-fast) var(--ease),
             box-shadow var(--d) var(--ease),opacity var(--d) var(--ease)}
.es__go svg{width:16px;height:16px;
  transition:transform var(--d) var(--ease-out)}
.es__go:hover{background:var(--champagne);transform:translateY(-1px)}
.es__go:hover svg{transform:translateX(4px)}
.es__go:active{transform:translateY(0) scale(.98)}
/* unanswered: clearly not ready, but still legible rather than a grey smear */
/* a disabled control is exempt from 1.4.3, but .55 landed at 4.46 and .62
   clears it outright, so there is no reason to lean on the exemption */
.es__go:disabled{background:rgba(243,239,230,.16);color:rgba(243,239,230,.62);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.14);pointer-events:none}

/* ---- the result ---- */
.es__out{position:relative;margin-top:clamp(2rem,4.5vw,3rem)}
.es__range{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.8rem,5.4vw,3.2rem);line-height:1.1;letter-spacing:-.02em;
  color:var(--champagne);text-wrap:balance}
.es__range span{font-size:.5em;color:var(--on-dark-mute);padding:0 .25em}
/* shown instead of a figure while the rates are unset. It is a statement, not
   an error, so it is styled like one. */
.es__pending{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:clamp(1.1rem,2.6vw,1.5rem);line-height:1.5;color:var(--cream);
  text-wrap:pretty}
/* printed with every result, never tucked away */
.es__caveat{margin-top:var(--s5);padding:var(--s4) var(--s5);
  border-radius:var(--r-md);border:1px solid rgba(243,239,230,.14);
  border-left:2px solid var(--champagne);
  font-size:var(--t-sm);line-height:1.65;color:var(--on-dark-mute)}
.es__sum{margin-top:var(--s6);gap:.45rem}
.es__sum dt{color:var(--on-dark-mute)}
.es__sum dd{color:var(--cream)}
/* the review screen's 9rem label column is sized for two word labels; these
   are whole questions, so they get room rather than wrapping four lines deep */
@media (min-width:560px){
  .es__sum .rev__r{grid-template-columns:minmax(0,15rem) minmax(0,1fr)}
}
.es__acts{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:var(--s6)}
.es__acts .cta--fill{background:var(--cream);color:var(--olive-950)}
.es__acts .cta--fill::before{background:var(--champagne)}
.es__acts .cta--line{border-radius:var(--r-pill);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.3);color:var(--cream)}
.es__acts .cta--line::after{display:none}
.es__acts .cta--quiet{color:var(--on-dark-mute)}

@media (min-width:620px){
  /* two to a row once there is width for it, which keeps four options from
     becoming a tall ladder */
  .es__opts{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (pointer:coarse){
  .es__o{min-height:60px}
}
@media (prefers-reduced-motion:reduce){
  .es__q.on{animation:none}
  .es__seg li.on{transform:none}
}

/* ================================================ 4d · ABOUT PREVIEW */
.ab{padding:var(--bay) var(--gutter);background:var(--ivory);
  display:grid;gap:var(--s7);max-width:var(--maxw);margin:0 auto;
  align-items:center}
.ab__fig{position:relative;border-radius:var(--r-xl);overflow:hidden;aspect-ratio:4/5;
  background:var(--limestone-lt);box-shadow:var(--sh-md)}
.ab__fig>picture{display:block;width:100%;height:100%}
.ab__fig img{width:100%;height:100%;object-fit:cover;display:block}
.ab__in{display:grid;gap:var(--s5);justify-items:start}
.ab__p{color:var(--ink-muted);line-height:1.8;max-width:46ch;text-wrap:pretty}

@media (min-width:860px){
  .ab{grid-template-columns:minmax(0,.85fr) minmax(0,1fr);
    gap:clamp(2.5rem,6vw,6rem)}
  .ab__fig{aspect-ratio:3/4}
}

/* ============================================= 6c · COZY COLLECTIONS */
/* A teaser and nothing more: there is deliberately nothing here to click. */
/* The band came to 963px on a 1269 screen, taller than the window it sits in,
   and 352 of that was padding. Trimmed here and in four small places below;
   the countdown is what the section is for and it should not need a scroll to
   reach. */
.co{position:relative;isolation:isolate;overflow:hidden;
  padding:clamp(3.2rem,9vw,6rem) var(--gutter);
  background:var(--olive-950);color:var(--cream);text-align:center}
.co__art{position:absolute;inset:0;z-index:-2}
.co__art picture,.co__art img{width:100%;height:100%;object-fit:cover;display:block;
  /* Desktop keeps the wide 1916x821 crop centred. On a phone, pic() swaps
     in a dedicated portrait banner via <source media="(max-width:740px)">,
     so the full composition fits the tall viewport without cropping. */
  object-position:center center}
/* The veil used to be a flat 72% to 86% across the whole band, which held the
   type easily and buried the photograph. The client wanted the room bright.

   It cannot simply be turned down: her banner is a warm, bright interior, and
   at a flat 40% the cream wording measured 2.5:1, nowhere near the 4.5 an
   11px line needs. So the tint is off the picture and under the words
   instead. The wash is 16% to 26%, which is barely there, and a soft pool
   sits behind the wording only.

   Measured against the brightest pixel under each line: eyebrow 5.1,
   headline 3.6 at 58px so its bar is 3, body 6.0, the pill 7.2. */
/* A BAND, NOT A BLOB.
   The pool that used to sit behind the wording was an ellipse on the text
   box, and you could see it: a soft edged rectangle cutting vertically
   through the sofa. Anything with vertical edges over a photograph reads as
   a smudge rather than as light.
   This runs the full width and only varies down the page, so it has no
   vertical edges to notice. The room reads at the top and the bottom and the
   wording sits in the deeper middle. */
.co::after{content:'';position:absolute;inset:0;z-index:-1;
  /* Warm brown rather than the cold near black this used to be. The client
     said the band read as dark when the room in it is a warm one, and a
     veil takes its character from its colour long before its depth. */
  background:linear-gradient(to bottom,
    rgba(46,31,20,.38) 0%,
    rgba(46,31,20,.62) 12%,
    rgba(46,31,20,.62) 88%,
    rgba(46,31,20,.32) 100%)}
/* The hold runs to 88%, not 72%. Trimming the band's height moved the launch
   date down into the light end of the ramp and it measured 4.29 against the
   4.5 an 11px line needs; now 5.85. Every line in the band, measured against
   the brightest pixel under it: eyebrow 5.9, headline 6.1, body 5.1, COMING
   SOON 3.6 at 26px so its bar is 3, numerals 5.4, unit labels 10.0. */
/* The ramp reaches its depth by 12%, not 26%. The eyebrow sits near the top
   of the band and was catching the light end of the gradient at 3.99 against
   the 4.5 it needs. Measured against the brightest pixel under each line the
   band now gives: eyebrow 5.8, headline 5.2, body 5.1, COMING SOON 3.6 at
   26px so its bar is 3, the numerals 5.2, the date 5.0. */

.co__in{position:relative;z-index:0}

/* On a phone the band turns upright and the photograph covers to a narrow
   slice, so the gradient is tightened up rather than spread over a height
   that is mostly text anyway. */
@media (max-width:740px){
  /* The top end stays light so the room reads as a photograph, not a dark
     bar; the band only deepens where the writing sits. */
  .co::after{background:linear-gradient(to bottom,
    rgba(46,31,20,.22) 0%,
    rgba(46,31,20,.42) 20%,
    rgba(46,31,20,.70) 42%,
    rgba(46,31,20,.70) 90%,
    rgba(46,31,20,.50) 100%)}
  /* The painted "COZY COLLECTIONS" wordmark on the wall sits near the top
     of the mobile crop (ceiling trimmed off the source so the mark starts
     high in the frame). Pin the image's top edge to the band's top and
     push the writing just past the wordmark zone; the vw term scales the
     clearance up with the viewport so wider phones hold the gap too. */
  .co__art picture,.co__art img{object-position:center top}
  .co{padding-top:clamp(9rem,36vw,17rem)}
}
/* with no photograph the ground stands on its own, so the veil is not needed
   and a quiet wash of light does the work instead */
.co__art--bare+.co__in{position:relative}
.co:has(.co__art--bare)::after{
  background:radial-gradient(120% 80% at 50% 0%,rgba(203,176,125,.14),transparent 62%)}

.co__in{max-width:46rem;margin:0 auto;display:grid;gap:var(--s4);justify-items:center}

/* THE WORDING SITS TO THE RIGHT ON A WIDE SCREEN.
   Her banner has COZY COLLECTIONS lettered on the wall in the left half of
   the photograph, and the centred block was sitting across it: the headline
   ran straight through the word COLLECTIONS. So the writing moves into the
   right hand side and the scrim turns with it, light on the left where the
   lettering is and deep on the right where the words are. The room's own
   sign gets to be read, which is the whole reason it is in the picture.

   Below 1000px the photograph is cropped hard enough by cover that the
   lettering is mostly outside the frame anyway, so it stays centred there. */
@media (min-width:1000px){
  /* 33rem, not 38. At 38 the block began at 47% of the band and the wall
     lettering runs to about the same point, so the headline's first letter
     was sitting against the last S of COLLECTIONS. This starts it at 56% and
     leaves a clear hand's width of photograph between the two. */
  .co__in{margin-inline:auto 0;max-width:33rem}
  /* Measured against the brightest pixel under each line, with the wall
     lettering kept as light as it can be: eyebrow 5.2, headline 7.4, body
     7.0, COMING SOON 4.3, numerals 7.0, the date 5.5. The first 24% of the
     width is barely touched, which is where her lettering sits. */
    /* The ramp reaches its full depth by 58% rather than 62%. The paragraph is
     the widest line in the block and its left edge reaches further into the
     light than anything else does; at 62% it was measuring 3.94 against a
     4.5 pass mark while every other line cleared. The left third, which is
     where her lettering is on the wall, is untouched at 6%. */
.co::after{background:linear-gradient(96deg,
    rgba(46,31,20,.06) 0%,
    rgba(46,31,20,.12) 26%,
    rgba(46,31,20,.38) 44%,
    rgba(46,31,20,.68) 58%,
    rgba(46,31,20,.70) 100%)}
}
/* CREAM, NOT CHAMPAGNE, AND THIS IS THE WHOLE REASON THE BAND CAN BE LIGHT.
   This line sits on a white wall in the photograph. Champagne against it
   needs 73% of the light taken out before it is legible; cream needs far
   less, and eight points of veil is the difference between a warm room and
   a dark one. The gold has not left the band, it has moved to COMING SOON,
   which is the line the section is actually for. */
.co__name{font-size:var(--t-xs);letter-spacing:.34em;text-transform:uppercase;
  color:var(--cream)}
.co__tag{font-family:var(--serif);font-weight:300;font-style:italic;
  font-size:clamp(1.8rem,4.6vw,2.9rem);line-height:1.1;letter-spacing:-.02em;
  text-wrap:balance}
/* was dimmed to 62% cream, which is a discount the band can no longer
   afford: dimmed type needs a darker ground to sit on */
/* 52ch reached back into the bright half of the photograph. 42ch is a
   better measure for a paragraph this size anyway. */
.co__line{color:var(--cream);line-height:1.75;max-width:42ch;
  text-wrap:pretty}
/* It was an 11px pill. She asked for it much bigger, and it is the thing the
   section is actually announcing, so it is set as a statement with a rule
   running out to either side of it. */
.co__soon{display:flex;align-items:center;gap:clamp(.9rem,2.5vw,1.6rem);
  margin-top:clamp(1rem,2.4vw,1.6rem);width:100%;
  font-size:clamp(1.05rem,2.6vw,1.62rem);letter-spacing:.34em;
  text-transform:uppercase;font-weight:500;color:var(--champagne);
  text-indent:.34em}
.co__soon::before,.co__soon::after{content:'';flex:1;height:1px;
  background:linear-gradient(90deg,rgba(217,201,169,0),rgba(217,201,169,.55))}
.co__soon::after{background:linear-gradient(90deg,rgba(217,201,169,.55),rgba(217,201,169,0))}

/* ---- the countdown ---- */
/* Tabular lining figures are not decoration here: Cormorant sets oldstyle by
   default, and without tabular the seconds shift the whole row sideways
   every tick. */
.co__count{display:flex;align-items:flex-start;
  gap:clamp(1rem,3.4vw,2.2rem);margin-top:clamp(.9rem,2.2vw,1.4rem)}
.co__u{display:grid;justify-items:center;gap:.4rem;min-width:3.2ch}
.co__n{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.8rem,4.8vw,2.85rem);line-height:.92;letter-spacing:.01em;
  color:var(--cream);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.co__ul{font-size:var(--t-xs);letter-spacing:var(--track-caps);
  text-transform:uppercase;color:var(--cream)}
/* the same reasoning as .co__name, and it sits on the brightest part of the
   floor, 253,248,213 */
.co__date{margin-top:clamp(.7rem,1.8vw,1.1rem);
  font-size:var(--t-xs);letter-spacing:.26em;text-transform:uppercase;
  color:var(--cream)}

/* ==================================================== ABOUT PAGE, SPREAD */
/* `spr`, not `sp`: the services page already owns `.sp`, and a `.sp>*` rule
   here was reaching across and capping that page's columns at 42rem.

   The page is set as a magazine spread. With no filler photography left in it,
   the rhythm has to come from the layout itself, so three things do that work:

     a rail          every chapter numeral sits in the same left margin, which
                     gives the whole page one strong vertical edge to read down
     a measure       the writing holds a 38rem column against that rail rather
                     than floating centred in the window
     a break         the pull quotes go full bleed on the dark ground, so the
                     page has two moments that stop you instead of one even
                     column of text from top to bottom
*/
.au{position:relative;isolation:isolate;min-height:clamp(26rem,66vh,42rem);
  display:grid;align-items:end;padding:calc(var(--bay) + 5rem) var(--gutter) var(--bay);
  background:var(--olive-950);color:var(--cream);overflow:hidden}
/* Overscanned top and bottom so the banner can be parallaxed without ever
   showing an edge: js moves it 5% either way, and the header clips the rest. */
.au__art{position:absolute;inset:-7% 0;z-index:-2}
.au__art picture,.au__art img{width:100%;height:100%;display:block}
/* the vignette in the banner sits right of centre, so the crop is pushed that
   way and the headline gets clear wall to sit against */
.au__art img{object-fit:cover;object-position:68% 42%}
/* The banner photograph averages 191 of 255, which is bright enough that the
   eyebrow came out at 3.92 against the worst pixel under it. Deepening the
   veil to .64 at the top and .91 at the foot carries every line past AA with
   the picture still legible underneath. */
.au::after{content:'';position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to bottom,rgba(20,22,15,.64),rgba(20,22,15,.91))}
.au:has(.au__art--bare)::after{
  background:radial-gradient(110% 80% at 50% 0%,rgba(203,176,125,.12),transparent 64%)}
.au__in{max-width:var(--maxw);margin:0 auto;width:100%}
/* `.eyebrow` is coloured for the light grounds it usually sits on. Over the
   dark header it comes out at 2.5:1, so it takes the champagne instead. */
.au .eyebrow{color:var(--champagne)}
.au__h{font-family:var(--serif);font-weight:300;margin-top:var(--s4);
  font-size:clamp(2.4rem,7vw,5.6rem);line-height:1;letter-spacing:-.03em;
  text-wrap:balance;max-width:18ch}
.au__h em{font-style:italic;color:var(--champagne)}
.au__line{margin-top:var(--s5);max-width:44ch;color:var(--on-dark-soft);
  line-height:1.8}

/* ---- the spread ---- */
/* A twelve column measure, not a centred column with pictures in it.

   The old version put every block in one 42rem column running down the same
   axis, and dropped the pictures in above and below it. That is a blog post.
   A spread is asymmetric: the writing sits off the centre line, the pictures
   run off the edge of the page, and two pictures on the same row sit at
   different heights so the eye moves diagonally instead of straight down.

   Everything below is placed on this grid by hand. Nothing is centred by
   default, because a default is the opposite of what she asked for. */
/* The bottom pad is not decoration. The spread ended flush against the
   closing band: measured zero pixels between the last trait's last line and
   the dark edge. It went unnoticed while the traits were one-line
   placeholders and read as clipped the moment her real two-line copy went in.
   Only the bottom is padded; the sides stay at zero so the full-bleed quote
   and photograph blocks can still reach full-start and full-end. */
.spr{background:var(--ivory);padding:0 0 clamp(3.5rem,8vw,6rem);
  display:grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter),1fr)
    /* capped at the house measure: each column takes a twelfth of it and the
       outer tracks absorb whatever is left, so the page does not keep
       widening on a large monitor */
    [m-start] repeat(12,[c] minmax(0,calc(var(--maxw) / 12))) [m-end]
    minmax(var(--gutter),1fr) [full-end];
  column-gap:clamp(.7rem,1.5vw,1.4rem);
  row-gap:0}
.spr>*{grid-column:m-start/m-end;min-width:0}

/* ---- the chapter opener ---- */
.spr__ch{grid-column:m-start/m-end;
  display:grid;gap:var(--s4);align-items:baseline;
  padding-top:clamp(4rem,11vw,8rem);padding-bottom:clamp(1.5rem,3vw,2.5rem)}
/* Lining, tabular figures with the tracking opened out. At -.05em Cormorant
   ran the zero and the one of 01 together, and the chapter numeral read as
   the word OI rather than as a number. */
.spr__ch-n{font-family:var(--serif);font-weight:300;line-height:.8;
  font-size:clamp(3rem,8vw,5.5rem);letter-spacing:.04em;
  /* This carried opacity:.55, which never survived: spreads() in motion.js
     reveals the numeral by animating opacity 0 to 1 and writes 1 inline, so
     the page has always drawn it at full strength. Animating to .55 instead
     would honour the old intent and measure 2.29 against the ivory, under the
     3:1 a 88px numeral needs. Full bronze measures 5.59 and is what you see,
     so the stylesheet now says so. */
  color:var(--bronze);
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1,'tnum' 1}
.spr__ch-t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.9rem,5vw,3.2rem);line-height:1.04;letter-spacing:-.025em;
  text-wrap:balance}
.spr__ch-l{margin-top:var(--s3);color:var(--ink-muted);font-style:italic;
  max-width:40ch}
/* the hairline that closes the chapter head and opens the writing */
.spr__ch::after{content:'';grid-column:1/-1;height:1px;background:var(--rule);
  margin-top:clamp(1.25rem,3vw,2rem)}

/* ---- the writing ---- */
.spr__tx{padding-top:clamp(1.75rem,4vw,2.75rem);
  padding-bottom:clamp(1.5rem,3vw,2.5rem)}
.spr__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.3rem,3vw,1.9rem);line-height:1.2;letter-spacing:-.015em;
  margin-bottom:var(--s5)}
.spr__body p{line-height:1.9;color:var(--ink-soft);margin-bottom:var(--s5);
  text-wrap:pretty}
.spr__body p:last-child{margin-bottom:0}
/* The paragraph that opens a chapter is set larger, the way a magazine sets a
   standfirst, so the eye has somewhere to land after the title. It applies
   after an offset block as well as a text one, because the first chapter
   opens on the founder's portrait rather than on prose. */
.spr__ch+.spr__tx .spr__body>p:first-child,
.spr__ch+.spr__off .spr__off-t .spr__body>p:first-child{
  font-family:var(--serif);font-weight:300;
  font-size:clamp(1.15rem,2.3vw,1.5rem);line-height:1.6;color:var(--ink)}

/* The dropped capital. It is the oldest device in magazine setting and it
   does two things here: it marks where a chapter actually begins, which a
   numeral in the margin cannot do on its own, and it gives a page built
   almost entirely of type one piece of drawn detail per chapter. Bronze
   rather than ink, so it belongs to the same family as the numerals. */
.spr__ch+.spr__tx .spr__body>p:first-child::first-letter,
.spr__ch+.spr__off .spr__off-t .spr__body>p:first-child::first-letter{
  float:left;font-family:var(--serif);font-weight:300;
  font-size:2.9em;line-height:.8;
  margin:.06em .11em 0 0;color:var(--bronze)}
/* a dropped capital needs three lines under it to sit in; on a narrow column
   it would be taller than its own paragraph */
@media (max-width:520px){
  .spr__ch+.spr__tx .spr__body>p:first-child::first-letter,
  .spr__ch+.spr__off .spr__off-t .spr__body>p:first-child::first-letter{
    font-size:2.3em}
}
.spr__ph{margin-top:var(--s5)}

/* ---- the pull quote, full bleed on the dark ground ---- */
/* With the filler photography gone these are the only visual moments left on
   the page, so they are given the whole width and a ground of their own. */
/* `--qy` is written by the scroll, so the light behind the quote travels
   down the band as the band travels up the screen. It is a slow, almost
   subliminal move, and it is most of why these two panels feel like
   something happening rather than two dark rectangles going by. */
.spr__q{--qy:0%;grid-column:full-start/full-end;
  position:relative;isolation:isolate;overflow:hidden;
  margin-top:clamp(3rem,7vw,5rem);
  padding:clamp(3.5rem,10vw,7rem) var(--gutter);
  background:
    radial-gradient(90% 120% at 50% var(--qy),rgba(203,176,125,.16),transparent 62%),
    var(--olive-950);
  color:var(--cream);text-align:center}
.spr__q blockquote{max-width:34rem;margin-inline:auto}
/* the quote mark, set oversized behind the words as texture */
.spr__q blockquote::before{content:'\201C';display:block;
  font-family:var(--serif);font-size:clamp(4rem,11vw,7rem);line-height:.6;
  color:var(--champagne);opacity:.34;margin-bottom:clamp(.5rem,1.5vw,1rem)}
.spr__q blockquote p{font-family:var(--serif);font-weight:300;font-style:italic;
  font-size:clamp(1.45rem,4vw,2.5rem);line-height:1.28;letter-spacing:-.02em;
  color:var(--cream);text-wrap:balance}
.spr__q cite{display:block;margin-top:var(--s5);font-style:normal;
  font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--champagne)}
.spr__q .ph{margin-top:var(--s5)}

/* ---- a plate held for a photograph ---- */
/* Not a broken image and not a grey box: a reserved plate, ruled and marked
   with the house emblem, that reads as a deliberate part of the layout until
   the photograph replaces it. The hatching is the one the site's other
   placeholders already use, so the whole unfinished state speaks with one
   voice. Printing these rather than dropping the blocks is what keeps the
   spread's rhythm: a magazine page is the picture and the writing together,
   and with every picture removed it collapsed into a column of prose. */
.rsv{position:relative;display:grid;place-items:center;width:100%;height:100%;
  background:
    repeating-linear-gradient(135deg,rgba(29,31,24,.05) 0 1px,transparent 1px 14px),
    linear-gradient(152deg,var(--limestone-lt),var(--limestone))}
/* the printed rule, inset from the trim, the way a reserved plate is marked */
.rsv::after{content:'';position:absolute;inset:clamp(.7rem,1.6vw,1.15rem);
  border:1px solid rgba(125,95,58,.24);pointer-events:none}
.rsv__m{width:clamp(56px,16%,104px);aspect-ratio:1/1;
  color:var(--bronze);opacity:.3}
.rsv__m svg{width:100%;height:100%;display:block}
/* 11px caps, so it needs 4.5:1. Plain --bronze measures 3.12 against the dark
   end of the plate's gradient and fails outright. #5E4526 reaches 4.73 on the
   flat ground but only 4.27 on the hatch lines, which are 5% black; this one
   holds 5.05 on the worst pixel and 5.59 on the flat. It matters more now than
   it did on the about spread, because seventeen portfolio tiles carry it. */
.rsv__t{position:absolute;left:0;right:0;bottom:clamp(1.4rem,3vw,2.1rem);
  text-align:center;padding:0 1.5rem;
  font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:#513B1F}

/* ---- the full width photograph ---- */
/* A band, not a wall. Edge to edge at 16:9 this came out over 800px tall on
   a laptop, which is not a photograph in a magazine, it is a photograph
   instead of one. It is now a fixed band height whatever the width, and it
   breaks one edge rather than both, so it still reads as a break in the page
   without swallowing a whole screen of it. */
.spr__full{grid-column:full-start/c 11;margin:clamp(3rem,7vw,5rem) 0}
/* the second one in the page breaks the other edge, so two of them never
   read as the same block repeated */
.spr__full:nth-of-type(even){grid-column:c 3/full-end}
/* THE BAND FOLLOWS THE PHOTOGRAPH, UP TO A POINT.
   This was a fixed height ribbon, which meant every picture put in it was
   cut to roughly 2.9:1 whatever shape it actually was. That was fine while
   both strips were wide crops; the replacement below Our Story is 16:9 and
   was losing 38% of its height, the arches off the top and the rug off the
   bottom. It takes its own shape now, with a ceiling so a tall one still
   cannot swallow a whole screen. */
.spr__full>picture,.spr__full>.rsv{position:relative;width:100%;
  aspect-ratio:var(--ar,3/1);
  max-height:clamp(20rem,58vh,34rem);
  overflow:hidden;background:var(--limestone-lt)}
.spr__full>picture{display:block}
.spr__full img{width:100%;height:100%;display:block;object-fit:cover}
/* the caption sits under the picture's own left edge, not centred under the
   page, because the picture is no longer centred on the page either */
.spr__full figcaption{max-width:34rem;margin:var(--s4) 0 0;
  padding:0 var(--gutter);
  font-size:var(--t-xs);color:var(--ink-muted);line-height:1.6}

/* The two plates are not a tidy pair of equals in the middle of the page.
   One runs off the left edge and sits low, the other runs off the right and
   sits high, which is the single move that makes a spread read as a spread.
   `display:contents` dissolves the wrapper so both figures land straight on
   the page grid and can be placed independently. */
.spr__pair{display:contents}
/* 3/4, which is the shape of the photograph that sits in it. 4/5 was chosen
   while this was an empty plate and would have taken 6% off the top and the
   bottom of her for no reason. Only the upright half uses this: the wide half
   overrides it at both breakpoints. */
.spr__pair figure{position:relative;overflow:hidden;
  aspect-ratio:3/4;background:var(--limestone-lt)}
.spr__pair figure>picture{display:block;width:100%;height:100%}
.spr__pair img{width:100%;height:100%;object-fit:cover;display:block}
.spr__cap{grid-column:c 4/c 11;margin-top:var(--s5);
  font-size:var(--t-xs);color:var(--ink-muted)}

/* ---- the founder, photograph beside the writing ---- */
/* The portrait runs off the left edge of the page and the writing sits in
   the right hand columns, optically centred against it. Dissolved for the
   same reason as the pair: so both halves sit on the page grid rather than
   inside a centred box of their own. */
.spr__off{display:contents}
.spr__off-f{position:relative;overflow:hidden;
  aspect-ratio:4/5;background:var(--limestone-lt);box-shadow:var(--sh-md)}
.spr__off-f>picture{display:block;width:100%;height:100%}
.spr__off-f img{width:100%;height:100%;object-fit:cover;display:block}
/* 38ch beside a photograph that tall left 286px of the slot unused and ran
   the founder's paragraph at eight words a line, which reads as pinched
   rather than generous. 46ch is still a comfortable measure and balances the
   picture instead of cowering beside it. */
.spr__off-t .spr__body p{max-width:46ch}

/* ---- the signature style grid ---- */
.spr__tr{grid-column:m-start/m-end;
  margin:clamp(3rem,7vw,5rem) 0 0;padding:clamp(3rem,7vw,5rem) 0 0;
  border-top:1px solid var(--rule)}
.spr__tr .spr__h{text-align:center;margin-bottom:clamp(2rem,5vw,3.5rem)}
.spr__tr-l{display:grid;gap:var(--s6);list-style:none;padding:0;margin:0}
.spr__tr-l li{display:grid;gap:.5rem;align-content:start;
  padding-top:var(--s5);border-top:1px solid var(--rule)}
.spr__tr-n{font-family:var(--serif);font-weight:300;font-size:1.6rem;
  line-height:1;color:var(--bronze);opacity:.8}
.spr__tr-l h4{font-family:var(--serif);font-weight:300;font-size:1.3rem;
  line-height:1.2;letter-spacing:-.01em}
.spr__tr-l p{color:var(--ink-muted);line-height:1.7;font-size:var(--t-sm)}

/* ---- the closing band ---- */
/* The page used to end on a single centred button on an empty ivory field,
   which is not an ending, it is a page that has run out. This is a split
   band edge to edge: the picture on one side, an ink panel on the other
   carrying the sign-off.

   The words are the site's own closing copy, the same ones the homepage ends
   with, pulled from the config rather than written for this spot, so the two
   endings cannot drift apart.

   Height is capped for the same reason everything else on this page is: a
   closing band is a full stop, not another screen to scroll through. */
.cb{display:grid;background:var(--olive-950);color:var(--cream)}
.cb__fig{position:relative;overflow:hidden;background:var(--limestone-lt);
  min-height:clamp(15rem,34vh,21rem)}
.cb__fig>picture,.cb__fig>.rsv{position:absolute;inset:0;width:100%;height:100%}
/* the crop sits a little above centre, where the blossom is densest and the
   branch still reads against the sky */
.cb__fig img{width:100%;height:100%;object-fit:cover;object-position:50% 42%;
  display:block}

.cb__panel{position:relative;isolation:isolate;
  display:grid;align-content:center;justify-items:start;gap:var(--s5);
  padding:clamp(2.75rem,6vw,4.5rem) clamp(1.5rem,5vw,4rem)}
/* a wash of light from the top, so the panel is not a flat rectangle of ink */
.cb__panel::before{content:'';position:absolute;inset:0;z-index:-1;
  background:radial-gradient(120% 90% at 10% 0%,rgba(203,176,125,.16),transparent 66%)}
.cb__e{font-size:var(--t-xs);letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--champagne)}
.cb__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.8rem,4vw,2.9rem);line-height:1.04;letter-spacing:-.025em;
  text-wrap:balance}
.cb__h span{display:block}
.cb__h em{display:block;font-style:italic;color:var(--champagne)}
.cb__l{color:var(--on-dark-soft);line-height:1.8;max-width:38ch;text-wrap:pretty}
.cb__cta{margin-top:var(--s3)}

@media (min-width:820px){
  /* The picture takes the smaller half: the panel is the one doing the
     talking. It is narrower than a half for a second reason too. The artwork
     is a tall painting, 852 by 1846, and a wide landscape slot would show a
     quarter of it and upscale that quarter. A near square slot around 430px
     shows about half the painting and asks for no more pixels than the file
     actually has. */
  .cb{grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr);align-items:stretch}
  .cb__fig{min-height:clamp(21rem,46vh,29rem)}
}

@media (min-width:800px){
  .spr__pair{grid-template-columns:repeat(2,minmax(0,1fr))}
  .spr__tr-l{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:960px){
  /* the rail opens up and every chapter numeral lines up down the page */
  /* ---- where everything actually sits on the page ---- */
  /* The chapter head opens hard left, the writing answers it from the right
     of the centre line, and the pictures break out past both edges. Read
     down the column numbers and you can see the zigzag. */
  .spr__ch{grid-column:m-start/c 11;
    grid-template-columns:clamp(5rem,9vw,8rem) minmax(0,1fr);column-gap:0}
  .spr__ch-n{grid-row:1;grid-column:1}
  .spr__ch-t{grid-row:1;grid-column:2}
  .spr__ch-l{grid-row:2;grid-column:2;margin-top:0}

  /* the body answers the head: pushed right of the centre line, and held to
     a reading measure rather than the width of the page */
  .spr__tx{grid-column:c 4/c 12}
  .spr__body p{max-width:58ch}

  /* the portrait breaks the left edge; the writing meets it from column 8 */
  /* The portrait still breaks the left edge, but it is given a width rather
     than allowed to fill its span. At the full span it came out 702 by 878,
     which is the same mistake the plates and the services figures were
     making: a picture the height of the window. A width keeps the 4:5 crop
     honest, where capping the height would just have squashed the frame and
     cropped her out of it. */
  .spr__off-f{grid-column:full-start/c 6;
    width:min(100%,27rem);justify-self:start;
    margin:clamp(3rem,7vw,5.5rem) 0;
    border-radius:0 var(--r-lg) var(--r-lg) 0}
  /* the writing starts a column earlier, so the space the picture gave up
     goes to the words rather than to the margin */
  .spr__off-t{grid-column:c 6/m-end;align-self:center;
    margin:clamp(3rem,7vw,5.5rem) 0}
  .spr__off--flip .spr__off-f{grid-column:c 8/full-end;justify-self:end;
    border-radius:var(--r-lg) 0 0 var(--r-lg)}
  .spr__off--flip .spr__off-t{grid-column:m-start/c 9}

  /* Two plates, not two walls. At 4:5 across half the page each, these came
     out around 880px tall and between them they ate a whole screen of
     placeholder.

     They are also no longer the same shape as each other. A magazine pairs a
     wide picture with a tall one at different sizes and different heights;
     two identical rectangles side by side is a contact sheet. So: a landscape
     band breaking the left edge and sitting low, and a smaller upright held
     inside the measure sitting high. */
  .spr__pair figure:first-child{grid-column:full-start/c 7;
    aspect-ratio:auto;height:clamp(15rem,36vh,22rem);
    margin:clamp(4rem,9vw,7rem) 0 clamp(2.5rem,6vw,4rem);
    border-radius:0 var(--r-lg) var(--r-lg) 0}
  .spr__pair figure:last-child{grid-column:c 8/c 12;
    width:min(100%,21rem);justify-self:start;
    margin:0 0 clamp(4rem,9vw,7rem)}
  .spr__pair figure:only-child{grid-column:full-start/c 7;
    aspect-ratio:auto;height:clamp(15rem,36vh,22rem)}
}
@media (min-width:1100px){
  .spr__tr-l{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s5)}
}
@media (max-width:959px){
  /* stacked, the numeral leads the title rather than sitting beside it */
  .spr__ch{gap:var(--s3)}
  .spr__ch-n{opacity:.45}
  /* There is no room for a spread on one column, so the breakouts fold back
     in and everything runs the full measure in order. The plates keep their
     stagger as plain vertical rhythm. */
  .spr__off-f,.spr__off-t,
  .spr__pair figure,.spr__cap,
  .spr__full,.spr__full:nth-of-type(even){grid-column:m-start/m-end}
  /* A phone was giving these a near square box, 313 by 276, and covering a
     panoramic three part composition into that shows about the middle third
     of it. They keep their own shape here too, with a floor so a very wide
     one still reads as a band rather than a hairline. */
  .spr__full>picture,.spr__full>.rsv{height:auto;max-height:none;
    aspect-ratio:var(--ar,3/1);min-height:7.5rem}
  .spr__full figcaption{padding:0}
  .spr__off-f{margin:clamp(2rem,6vw,3rem) 0 var(--s6);
    width:auto;justify-self:stretch}
  .spr__off-t{margin-bottom:clamp(2rem,6vw,3rem)}
  .spr__off-f,.spr__pair figure{border-radius:var(--r-lg)}
  /* 2/1, not the 16/10 this carried while it was an empty plate. The
     photograph in it is 2.77:1, and 16/10 was covering away 42% of its
     width, which took the olive branches off one end and the swatch fan off
     the other. At 2/1 it loses 28% and still reads as a band on a phone. */
  .spr__pair figure:first-child{margin:clamp(2.5rem,7vw,4rem) 0 var(--s5);
    aspect-ratio:2/1;height:auto}
  .spr__pair figure:last-child{margin:0 0 clamp(2.5rem,7vw,4rem);
    width:auto;justify-self:stretch}
}

/* ========================================== PRIVATE REVIEW SESSION PAGE */
.rs{padding:clamp(9rem,20vh,13rem) var(--gutter) var(--bay);
  background:var(--ivory);min-height:70vh}
.rs__in{max-width:44rem;margin:0 auto;text-align:center}
.rs__h{font-family:var(--serif);font-weight:300;margin-top:var(--s4);
  font-size:clamp(2.2rem,6vw,4.4rem);line-height:1.02;letter-spacing:-.025em;
  text-wrap:balance}
.rs__h em{font-style:italic;color:var(--bronze)}
.rs__line{margin:var(--s5) auto 0;max-width:42ch;color:var(--ink-muted);
  line-height:1.8;text-wrap:pretty}
/* the same material as the estimator card: a ground that falls off toward the
   bottom, a hairline inside the edge, and a shadow deep enough to lift it */
.rs__card{position:relative;overflow:hidden;margin-top:var(--s7);text-align:left;
  border-radius:clamp(20px,2.4vw,30px);
  padding:clamp(1.5rem,4vw,3rem);color:var(--cream);
  background:
    radial-gradient(120% 90% at 50% 0%,rgba(203,176,125,.14),transparent 60%),
    linear-gradient(168deg,#22251B 0%,var(--olive-950) 52%,#101208 100%);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.09),
             inset 0 1px 0 rgba(243,239,230,.07),
             0 2px 6px rgba(20,22,15,.14),
             0 34px 70px -34px rgba(20,22,15,.62)}
.rs__fee{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s4);flex-wrap:wrap;padding-bottom:var(--s5);margin-bottom:var(--s5);
  border-bottom:1px solid rgba(243,239,230,.12);
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase}
.rs__free{font-family:var(--serif);font-size:1.3rem;letter-spacing:0;
  text-transform:none;color:var(--champagne)}
/* ---- the locked states ---- */
.rs__gate{position:relative;display:grid;justify-items:center;text-align:center;
  padding:clamp(1.5rem,4vw,2.75rem) 0 clamp(1rem,2.5vw,1.5rem)}
/* the mark is not repeated behind the copy: at any opacity that is visible it
   competes with the text, and at any opacity that does not it is not worth the
   node. The gradient ground carries the material on its own. */
.rs__ghost{display:none}
.rs__seal{position:relative;display:grid;place-items:center;
  width:74px;height:74px;border-radius:50%;
  color:var(--champagne);
  background:radial-gradient(circle at 50% 35%,rgba(203,176,125,.16),transparent 70%);
  box-shadow:inset 0 0 0 1px rgba(203,176,125,.34)}
.rs__seal svg{width:36px;height:36px}
.rs__tag{position:relative;margin-top:var(--s5);
  font-size:var(--t-xs);letter-spacing:.3em;text-transform:uppercase;
  color:var(--champagne)}
.rs__gh{position:relative;margin-top:var(--s4);
  font-family:var(--serif);font-weight:300;
  font-size:clamp(1.35rem,3.2vw,2rem);line-height:1.15;letter-spacing:-.02em;
  color:var(--cream);text-wrap:balance;max-width:20ch}
.rs__gb{position:relative;margin-top:var(--s4);
  color:var(--on-dark-mute);line-height:1.75;max-width:42ch;text-wrap:pretty}

.rs__gacts{position:relative;margin-top:clamp(1.75rem,4vw,2.5rem);
  display:flex;align-items:center;justify-content:center;
  gap:var(--s5);flex-wrap:wrap}
/* the way out is the primary action, because the copy sends you to it */
.rs__wa{display:inline-flex;align-items:center;gap:.6em;
  min-height:48px;padding:.8em 1.6em;border-radius:var(--r-pill);
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--olive-950);background:var(--cream);
  box-shadow:0 1px 2px rgba(20,22,15,.2),0 10px 24px -12px rgba(20,22,15,.6);
  transition:background var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.rs__wa svg{width:17px;height:17px}
.rs__wa:hover{background:var(--champagne);transform:translateY(-1px)}
.rs__wa:active{transform:translateY(0) scale(.98)}
.rs__ghost-a{display:inline-flex;align-items:center;min-height:44px;
  font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--on-dark-mute);border-bottom:1px solid transparent;
  transition:color var(--d) var(--ease),border-color var(--d) var(--ease)}
.rs__ghost-a:hover{color:var(--cream);border-bottom-color:rgba(243,239,230,.45)}
.rs__done{display:grid;gap:var(--s5);justify-items:center;text-align:center;
  padding:var(--s6) 0}
.rs__done .mark{width:52px;height:52px;color:var(--champagne)}
.rs__done h2{font-family:var(--serif);font-weight:300;font-size:1.7rem}
.rs__done p{color:var(--on-dark-mute);line-height:1.7;max-width:44ch}

@media (pointer:coarse){
  .es__o{padding:.85em 1.3em}
}

/* ------------------------------------------------------- SCROLL EXPERIENCE */
/* The heading lines, the progress hairline and the unveil frames. Everything
   here is motion scaffolding: with JavaScript off or reduced motion on, none
   of it changes how the page reads. */

/* a masked line. `ln` clips, `ln__i` is what moves inside it. The pair has to
   be inline-block or the mask collapses to the text baseline and the descenders
   get shaved off as the line arrives. */
.ln{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
/* the hint is set by js/motion.js while the line rises and cleared when it
   lands, rather than living here and holding a layer for ever */
.ln__i{display:block}
/* an em inside a line keeps whatever it already had; the mask does not touch it */
.ln__i>em,.ln__i>span{display:inline}

/* The permanent `will-change:clip-path` that used to be here is gone. It was
   promoting every picture frame on the site to its own compositing layer and
   leaving it there for the life of the page, and a rounded corner rasterised
   on its own layer renders soft. js/motion.js borrows the hint for the
   duration of the unveil and clears it on completion instead. */

@media (prefers-reduced-motion:reduce){
  .ln__i{transform:none!important}
}

/* =============================================================== WATCH PAGE */
/* The channel on a page of its own: a header, one large player, filters, and
   the grid that feeds the player. Nothing autoplays on arrival; the first film
   sits as a still until someone asks for it. */

/* ---- header ---- */
.wh{background:var(--olive-950);color:var(--cream);position:relative;isolation:isolate;
  overflow:hidden;
  padding:clamp(9rem,20vh,13rem) var(--gutter) clamp(3rem,7vw,5rem)}
.wh::after{content:'';position:absolute;inset:0;z-index:-1;
  background:radial-gradient(100% 80% at 50% 0%,rgba(203,176,125,.16),transparent 62%)}
.wh__in{max-width:var(--maxw);margin:0 auto;display:grid;gap:var(--s5);
  justify-items:center;text-align:center}
.wh .eyebrow{color:var(--champagne)}
.wh__h{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.2rem,6vw,4.6rem);line-height:1.02;letter-spacing:-.03em;
  text-wrap:balance}
.wh__h em{font-style:italic;color:var(--champagne)}
.wh__line{max-width:52ch;color:var(--on-dark-soft);line-height:1.8;text-wrap:pretty}
.wh__act{margin-top:var(--s4)}

/* the channel button, used in the header and again at the foot */
.yt{display:inline-flex;align-items:center;gap:var(--s4);
  padding:.7rem 1.6rem .7rem .7rem;border-radius:var(--r-pill);
  background:var(--cream);color:var(--olive-950);
  box-shadow:0 1px 2px rgba(20,22,15,.2),0 14px 30px -16px rgba(20,22,15,.7);
  transition:transform var(--d) var(--ease),box-shadow var(--d) var(--ease)}
.yt:hover{transform:translateY(-2px);box-shadow:0 2px 4px rgba(20,22,15,.24),
  0 22px 44px -18px rgba(20,22,15,.8)}
.yt__glyph{flex:none;width:42px;height:42px;display:grid;place-items:center;
  border-radius:50%;background:var(--olive-950);color:var(--champagne)}
.yt__glyph svg{width:22px;height:22px}
.yt__txt{display:grid;gap:.1rem;text-align:left}
.yt__l{font-size:var(--t-xs);letter-spacing:.16em;text-transform:uppercase}
.yt__h{font-size:var(--t-xs);color:var(--ink-muted);letter-spacing:.04em}
.yt--light{background:var(--olive-700);color:var(--cream)}
.yt--light .yt__glyph{background:var(--champagne);color:var(--olive-950)}
.yt--light .yt__h{color:rgba(243,239,230,.72)}

/* ---- the featured player ---- */
.wf{background:var(--olive-950);padding:0 var(--gutter) clamp(3rem,7vw,5rem)}
.wf__stage{max-width:min(var(--maxw),72rem);margin:0 auto;position:relative;
  aspect-ratio:16/9;border-radius:var(--r-xl);overflow:hidden;
  background:#000;
  box-shadow:0 2px 6px rgba(20,22,15,.3),0 40px 80px -36px rgba(0,0,0,.9)}
.wf__stage iframe{width:100%;height:100%;border:0;display:block}
.wf__poster{position:absolute;inset:0;width:100%;height:100%;display:block;
  cursor:pointer}
.wf__poster img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--ease-out),opacity var(--d) var(--ease)}
.wf__poster:hover img{transform:scale(1.03);opacity:.86}
.wf__play,.wv__play{position:absolute;top:50%;left:50%;translate:-50% -50%;
  display:grid;place-items:center;border-radius:50%;
  background:rgba(20,22,15,.55);color:var(--cream);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  box-shadow:inset 0 0 0 1px rgba(243,239,230,.34);
  transition:background var(--d) var(--ease),transform var(--d) var(--ease-out)}
.wf__play{width:clamp(64px,8vw,88px);height:clamp(64px,8vw,88px)}
.wf__play svg{width:34%;height:34%;margin-left:6%}
.wf__poster:hover .wf__play{background:var(--champagne);color:var(--olive-950);
  transform:translate(-50%,-50%) scale(1.06)}

.wf__meta{max-width:min(var(--maxw),72rem);margin:var(--s6) auto 0;
  display:grid;gap:var(--s3);justify-items:start;color:var(--cream)}
.wf__cat{font-size:var(--t-xs);letter-spacing:.24em;text-transform:uppercase;
  color:var(--champagne)}
.wf__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.3rem,3vw,2.1rem);line-height:1.12;letter-spacing:-.02em;
  text-wrap:balance}
.wf__out{margin-top:var(--s3);font-size:var(--t-xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--on-dark-mute);
  border-bottom:1px solid transparent;min-height:44px;display:inline-flex;
  align-items:center;
  transition:color var(--d) var(--ease),border-color var(--d) var(--ease)}
.wf__out:hover{color:var(--cream);border-bottom-color:rgba(243,239,230,.45)}

/* ---- the grid ---- */
.wg{background:var(--ivory);padding:clamp(3.5rem,8vw,6rem) var(--gutter)}
.wg__head{max-width:var(--maxw);margin:0 auto clamp(2rem,4vw,3rem);
  display:grid;gap:var(--s5)}
.wg__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.5rem,3.4vw,2.4rem);line-height:1.1;letter-spacing:-.02em}
.wg__filters{display:flex;flex-wrap:wrap;gap:.4rem}
.wg__f{display:inline-flex;align-items:center;gap:.5em;min-height:44px;
  padding:.6em 1.15em;border-radius:var(--r-pill);
  font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-muted);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.14);
  transition:background var(--d) var(--ease),color var(--d) var(--ease),
             box-shadow var(--d) var(--ease)}
.wg__f:hover{background:rgba(65,68,55,.06);color:var(--ink)}
.wg__f.on{background:var(--olive-700);color:var(--cream);
  box-shadow:inset 0 0 0 1px var(--olive-700)}
.wg__n{font-family:var(--serif);font-size:.95em;letter-spacing:0;opacity:.7}

.wg__grid{max-width:var(--maxw);margin:0 auto;display:grid;gap:clamp(1.5rem,3vw,2.25rem)}
.wg__none{max-width:var(--maxw);margin:var(--s7) auto 0;text-align:center;
  color:var(--ink-muted);font-style:italic}

.wv{display:grid;gap:var(--s4);text-align:left;align-content:start;
  transition:transform var(--d) var(--ease)}
.wv:hover{transform:translateY(-4px)}
.wv__fig{position:relative;display:block;border-radius:var(--r-lg);overflow:hidden;
  aspect-ratio:16/9;background:var(--limestone-lt);
  box-shadow:inset 0 0 0 1px rgba(65,68,55,.08),0 1px 2px rgba(20,22,15,.06)}
.wv__fig img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.1s var(--ease-out)}
.wv:hover .wv__fig img{transform:scale(1.05)}
.wv__play{width:52px;height:52px;opacity:0;
  transition:opacity var(--d) var(--ease),background var(--d) var(--ease),
             transform var(--d) var(--ease-out)}
.wv__play svg{width:36%;height:36%;margin-left:6%}
.wv:hover .wv__play,.wv:focus-visible .wv__play{opacity:1}
.wv__len{position:absolute;right:.55rem;bottom:.55rem;
  font-size:11px;letter-spacing:.04em;color:var(--cream);
  padding:.25em .55em;border-radius:5px;background:rgba(20,22,15,.76);
  font-variant-numeric:tabular-nums}
.wv__cap{display:grid;gap:.4rem}
.wv__cat{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--bronze)}
.wv__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.02rem,1.5vw,1.2rem);line-height:1.3;color:var(--ink);
  text-wrap:pretty}
/* the film currently in the player is marked, so the grid says where you are */
.wv.on .wv__fig{box-shadow:inset 0 0 0 2px var(--bronze),0 1px 2px rgba(20,22,15,.06)}
.wv.on .wv__cat{color:var(--ink)}

/* ---- the closing band ---- */
.ws{background:var(--limestone-lt);padding:clamp(3.5rem,8vw,6rem) var(--gutter)}
.ws__in{max-width:44rem;margin:0 auto;display:grid;gap:var(--s5);
  justify-items:center;text-align:center}
.ws__t{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.6rem,4vw,2.6rem);line-height:1.1;letter-spacing:-.02em;
  text-wrap:balance}
.ws__l{color:var(--ink-muted);line-height:1.8;max-width:46ch;text-wrap:pretty}

@media (min-width:640px){
  .wg__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:1000px){
  .wg__grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .wg__head{grid-template-columns:auto minmax(0,1fr);align-items:center;
    column-gap:var(--s6)}
  .wg__filters{justify-content:flex-end}
}
@media (prefers-reduced-motion:reduce){
  .wv,.wv:hover{transform:none}
  .wv__fig img,.wf__poster img{transition:none}
}

/* ---- the phone page turn, see .fb__stage in the 900px block ---- */
/* The perspective lives in the transform so the book does not have to
   become a 3D context. 30 degrees rather than 90: a card turning fully edge
   on is a card that vanishes, because there is nothing printed on its back. */
@keyframes fbOutF{
  from{transform:perspective(1200px) rotateY(0) translateX(0) scale(1);opacity:1}
  to  {transform:perspective(1200px) rotateY(-30deg) translateX(-7%) scale(.97);opacity:0}
}
@keyframes fbOutB{
  from{transform:perspective(1200px) rotateY(0) translateX(0) scale(1);opacity:1}
  to  {transform:perspective(1200px) rotateY(30deg) translateX(7%) scale(.97);opacity:0}
}
@keyframes fbInF{
  from{transform:perspective(1200px) rotateY(26deg) translateX(7%) scale(.97);opacity:0}
  to  {transform:perspective(1200px) rotateY(0) translateX(0) scale(1);opacity:1}
}
@keyframes fbInB{
  from{transform:perspective(1200px) rotateY(-26deg) translateX(-7%) scale(.97);opacity:0}
  to  {transform:perspective(1200px) rotateY(0) translateX(0) scale(1);opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .fb__stage.x--f,.fb__stage.x--b,.fb__stage.in--f,.fb__stage.in--b{animation:none}
}


/* ---------------------------------------------- THE FOOTER ON A PHONE */
/* Explore is nine links between 28 and 75px wide, which sit in a half
   column with room to spare, so they pair and the list is five rows
   instead of nine. The service names run to 176px and stay in one. */
@media (max-width:740px){
  #ftNav{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:var(--s4)}
  #ftContact{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:var(--s4)}
  /* the open hours badge sits under both columns rather than in one */
  #ftContact li.oh__list,.oh{grid-column:1/-1}
}


/* ------------------------------------- THE HERO BAND, NARROW SCREENS */
/* Three across at 375px gives about 105px a column. The values fit; the
   labels wrap to two lines, which is what a tracked small cap is for. The
   tracking and the size come down so they wrap at two rather than three. */
@media (max-width:560px){
  .hf{padding-top:.9rem}
  .hf__i{padding-inline:clamp(.4rem,2vw,.8rem)}
  .hf__k{font-size:9.5px;letter-spacing:.06em;line-height:1.35}
  .hf__v{font-size:1.02rem}
  .hf__i + .hf__i::before{top:calc(.9rem * -1)}
}


/* ------------------------------ THE OPENING BLOCK, NARROW SCREENS */
/* The buttons move to the right hand side and the writing above them closes
   up, so the whole block sits lower and more of the room is left showing.
   The band across the foot is untouched. */
@media (max-width:740px){
  .hero__h{margin-bottom:.4rem}
  .hero__line{margin-bottom:.85rem}
  /* THE LINE AND THE BUTTONS SHARE A ROW.
     The heading keeps the full width, because it is the thing the page is
     for. Under it the supporting line and the two buttons sit beside each
     other rather than stacked, which brings the whole block down the screen
     and leaves more of the room showing above it.

     display:contents on the foot drops its box so the band and the buttons
     become cells of this grid directly. The foot has no pseudo elements, so
     nothing is left behind the way it would be on .hf. */
  .hero__in{display:grid;grid-template-columns:minmax(0,1fr) auto;
    align-items:end;column-gap:var(--s4)}
  .hero__h{grid-column:1/-1}
  .hero__line{grid-column:1;margin-bottom:0;align-self:end}
  .hero__foot{display:contents}
  .hero__acts{grid-column:2;grid-row:auto;width:auto;
    align-items:flex-end;justify-content:flex-end;margin-top:0}
  .hf{grid-column:1/-1;margin-top:clamp(1.2rem,4vw,2rem)}
}


/* ==========================================================================
   THE BOOKING DIALOG IN CREAM
   --------------------------------------------------------------------------
   The dialog was built on the deep olive. The client asked for it on the
   cream instead, saying the dark made the flow hard to navigate and people
   were dropping out of it.

   This is an override rather than an edit of the rules above, deliberately.
   Every colour decision for the light panel is in this one block, so it can
   be read in one go and taken out in one go, and the original dark styling
   is still there underneath if she changes her mind.

   ONE RULE RUNS THROUGH ALL OF IT: champagne becomes bronze. Champagne is
   #D9C9A9 and the panel is now #F3EFE6. That is a contrast ratio of about
   1.3 to 1, which is not a colour, it is a rumour. Bronze #7D5F3A is the
   brand's dark metal and carries the same jewellery role legibly.

   Anything cream on olive flips to olive on cream, and the low-alpha cream
   borders become low-alpha ink.
   ========================================================================== */

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

/* The scroll bar she could not see. It was champagne at .3 alpha on near
   black. On cream it needs to be ink, and wide enough to find with a mouse.
   The track is tinted too, so there is a visible groove telling you the
   thing scrolls at all, which is half of what was wrong. */
.inq__panel{scrollbar-color:rgba(29,31,24,.42) rgba(29,31,24,.07)}
.inq__panel::-webkit-scrollbar{width:12px}
.inq__panel::-webkit-scrollbar-track{background:rgba(29,31,24,.06);border-radius:999px}
.inq__panel::-webkit-scrollbar-thumb{background:rgba(29,31,24,.38);
  border:3px solid transparent;background-clip:content-box;border-radius:999px}
.inq__panel::-webkit-scrollbar-thumb:hover{background:rgba(29,31,24,.62);
  border:3px solid transparent;background-clip:content-box}

.inq__close{color:var(--ink)}

/* ---- the step rail ---- */
.inq__rail li{color:rgba(29,31,24,.5)}
.inq__rail li.on{color:var(--ink)}
.inq__rail li.done{color:var(--bronze)}

/* ---- headings and notes ---- */
.step__note{color:var(--bronze)}
.step__opt{color:var(--bronze)}
.step__note--flag{color:var(--ink-muted);border:1px solid var(--rule);
  border-left:2px solid var(--bronze);background:rgba(125,95,58,.04)}

/* ---- option rows ---- */
.opt{border:1px solid var(--rule);background:rgba(29,31,24,.015)}
.opt:hover{border-color:var(--rule-firm);background:rgba(29,31,24,.045)}
.opt[aria-checked="true"]{border-color:var(--bronze);background:rgba(125,95,58,.07)}
.opt__dot{border:1px solid rgba(29,31,24,.42)}
.opt[aria-checked="true"] .opt__dot{border-color:var(--bronze)}
.opt[aria-checked="true"] .opt__dot::after{background:var(--bronze)}
.opt__n{color:var(--bronze)}
.opt__n.quote{color:var(--ink-muted)}

/* ---- fields ---- */
.fld label{color:var(--ink-muted)}
.fld label i{color:var(--bronze)}
.fld input,.fld select,.fld textarea{color:var(--ink);border-bottom-color:var(--rule)}
.fld textarea{border:1px solid var(--rule)}
.fld textarea:focus{border-color:var(--bronze)}
.fld input:focus,.fld select:focus,.fld textarea:focus{border-bottom-color:var(--bronze)}
.fld input::placeholder,.fld textarea::placeholder{color:rgba(29,31,24,.42)}
/* Chevron for the light select is drawn as the .fld pseudo-element below. */
.fld select option{background:var(--cream);color:var(--ink)}
.fld>.fld__hint{color:var(--ink-muted)}

/* Errors. The salmon pair were picked to glow on near black and are far too
   pale to read as a warning on cream, so both go to a brick that clears 4.5
   to 1 against this ground. */
.fld.bad input,.fld.bad select,.fld.bad textarea{border-color:#A2472B}
.fld.bad input{border-bottom-color:#A2472B}
.fld.bad>label,.fld.bad>span:not(.fld__hint):not(.fld__e){color:#8E3D23}
.fld__e,.fld>.fld__e{color:#8E3D23}

/* ---- chips ---- */
.chip{border:1px solid var(--rule)}
.chip:hover{border-color:var(--rule-firm);background:rgba(29,31,24,.045)}
.chip[aria-checked="true"],.chip[aria-pressed="true"]{
  background:var(--ink);color:var(--cream);border-color:var(--ink)}
.chip__tick{border:1px solid rgba(29,31,24,.38)}
.chip__tick::after{border-color:var(--cream)}
.chip[aria-pressed="true"] .chip__tick{background:transparent;border-color:var(--cream)}

/* ---- the running total ---- */
.sumry{border:1px solid var(--rule);background:rgba(29,31,24,.02)}
.sumry__r{border-bottom:1px solid var(--rule-soft)}
.sumry__r:last-child{border-bottom:0}
.sumry__r span:first-child{color:var(--ink-muted)}
.sumry__r.total span:last-child{color:var(--bronze)}

/* ---- the send buttons ---- */
/* .send inverted .cta--fill to cream because the ground was dark. On cream
   the plain dark pill is correct again, so the inversion is undone rather
   than replaced. */
.send .cta--fill{background:linear-gradient(180deg,#4C5041,#3A3E31);color:var(--cream)}
.send .cta--fill::before{background:var(--olive-950)}
.send .cta--line{border:1px solid var(--rule-firm);color:var(--ink)}
.send .cta--line:hover{background:rgba(29,31,24,.055);border-color:var(--ink)}
.send__n{color:var(--ink-muted)}

/* ---- inspiration links and photographs ---- */
.lnk__x{color:var(--ink-muted)}
.lnk__x:hover{background:rgba(29,31,24,.08);color:var(--ink)}
.addln{color:var(--bronze);border-bottom:1px solid rgba(125,95,58,.45)}
.addln:hover{border-bottom-color:var(--bronze)}
.drop{border:1px dashed rgba(29,31,24,.26)}
.drop:hover{border-color:var(--bronze);background:rgba(29,31,24,.03)}
.drop__l{color:var(--ink)}
.drop__n{color:var(--ink-muted)}
.fl{background:rgba(29,31,24,.04)}
.fl__x{color:var(--ink-muted)}
.fl__x:hover{background:rgba(29,31,24,.09);color:var(--ink)}

/* ---- review ---- */
.rev__g{background:rgba(29,31,24,.025);box-shadow:inset 0 0 0 1px var(--rule-soft)}
.rev__h h3{color:var(--bronze)}
.rev__h em{color:var(--ink-muted)}
.rev__e{color:var(--ink-muted)}
.rev__e:hover{color:var(--ink);border-bottom-color:var(--rule-firm)}
.rev__r dt{color:var(--ink-muted)}

/* ---- the foot of the dialog ---- */
.inq__meta{color:var(--bronze)}
.inq__meta b{color:var(--ink)}
.inq__nav .cta--fill{background:linear-gradient(180deg,#4C5041,#3A3E31);color:var(--cream)}
.inq__nav .cta--fill::before{background:var(--olive-950)}

/* ---- the done panel ---- */
.inq__done .mark{color:var(--bronze)}
.inq__done p{color:var(--ink-soft)}

/* ---- the pay block ---- */
.payb{border:1px solid var(--rule);background:rgba(125,95,58,.045)}
.payb__k{color:var(--bronze)}
.payb__amt{color:var(--ink)}
.payb__cur{color:var(--ink-muted)}
.payb__l{border-top:1px solid var(--rule-soft);color:var(--ink-soft)}
.payb__go{background:linear-gradient(180deg,#4C5041,#3A3E31);color:var(--cream)}
.payb__go::before{background:var(--olive-950)}
.payb__f,.payb__ref{color:var(--ink-muted)}

/* focus rings were champagne to show on olive; bronze shows on cream */
.inq :focus-visible{outline-color:var(--bronze)}

@media (min-width:741px){
  /* the inset hairline was a light edge for a dark card */
  .inq__panel{box-shadow:var(--sh-lg),var(--edge)}
}

/* ---- the sticky foot ---- */
/* Two media queries pin this to the bottom and paint it olive so content
   cannot show through behind it. Both need the cream, and the shadow that
   lifted it off a dark panel has to become one that reads on a light one. */
.inq__nav{border-top:1px solid var(--rule)}
@media (orientation:landscape) and (max-height:520px){
  .inq__nav{background:var(--cream);
    box-shadow:0 -16px 26px -18px rgba(20,22,15,.42)}
}
@media (pointer:coarse),(max-width:1024px){
  .inq__nav{background:var(--cream);
    box-shadow:0 -16px 26px -18px rgba(20,22,15,.42)}
}

/* The eyebrow over the heading. Champagne again, so bronze again. */
.inq .eyebrow{color:var(--bronze)}


/* ==========================================================================
   THE BOOKING FLOW, MODERNISED
   --------------------------------------------------------------------------
   The flow was underlined fields on a flat ground, which is a 2015 web form.
   This rebuilds the controls as grouped rounded rows, the shape a phone user
   already knows, with targets big enough for a thumb and a focus state you
   can actually see.

   Two bugs are fixed at the top, both of which made the flow feel broken
   rather than merely dated, and both of which came from the panel flipping
   to cream: the Back button and the step rail were still painted for a dark
   ground, so Back was cream on cream, invisible, and the rail read at
   3.1 to 1.
   ========================================================================== */

/* ---- 1. the invisible Back button ---- */
.inq .cta--quiet{color:var(--ink-muted)}
.inq .cta--quiet:hover{color:var(--ink)}

/* ---- 2. the step rail, was 3.14:1 at 11px ---- */
.inq__rail li{color:var(--ink-faint)}

/* ---- the controls ---- */
/* 16px minimum on anything typed into: below that, iOS Safari zooms the
   whole page on focus and the visitor is left pinched in on one field
   wondering where the form went. */
.inq .fld input,
.inq .fld select,
.inq .fld textarea{
  -webkit-appearance:none;appearance:none;
  width:100%;min-height:52px;
  padding:.9rem 1rem;
  font-size:16px;font-weight:400;
  color:var(--ink);
  background:rgba(255,255,255,.66);
  border:1px solid rgba(29,31,24,.10);
  border-radius:14px;
  box-shadow:0 1px 2px rgba(20,22,15,.04);
  transition:border-color var(--d-fast) var(--ease),
             box-shadow var(--d-fast) var(--ease),
             background var(--d-fast) var(--ease)}

.inq .fld textarea{min-height:120px;line-height:1.6;resize:vertical}

.inq .fld input:hover,
.inq .fld select:hover,
.inq .fld textarea:hover{background:rgba(255,255,255,.9);border-color:rgba(29,31,24,.18)}

/* A focus ring that is a ring, not a one pixel colour change. */
.inq .fld input:focus,
.inq .fld select:focus,
.inq .fld textarea:focus{
  outline:none;
  background:#fff;
  border-color:var(--bronze);
  box-shadow:0 0 0 4px rgba(125,95,58,.14)}

.inq .fld input::placeholder,
.inq .fld textarea::placeholder{color:rgba(29,31,24,.38)}

/* ---- selects get a real chevron ---- */
/* The old one was two CSS gradients faking a triangle. */
.inq .fld select{padding-right:2.6rem;cursor:pointer}

/* ---- date inputs ---- */
/* The native control prints mm/dd/yyyy in a grey nobody chose and hangs the
   operating system's own icon off the end, which is the single most dated
   thing on the page. The text is brought up to the field colour and the
   stock icon is replaced with one that matches the chevron. */
.inq .fld input[type="date"]{
  padding-right:2.6rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237D5F3A' stroke-width='1.7' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='3'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 1rem center;
  background-size:18px 18px;
  cursor:pointer}
.inq .fld input[type="date"]::-webkit-calendar-picker-indicator{
  opacity:0;cursor:pointer;
  position:absolute;right:0;width:2.6rem;height:100%;padding:0;margin:0}
.inq .fld input[type="date"]::-webkit-datetime-edit{color:var(--ink)}
.inq .fld input[type="date"]:invalid::-webkit-datetime-edit,
.inq .fld input[type="date"]:not(:focus):placeholder-shown::-webkit-datetime-edit{
  color:rgba(29,31,24,.38)}
.inq .fld{position:relative}

/* ---- labels ---- */
/* Quieter and closer to the control they name. Shouting every label in
   tracked-out caps at full contrast made the form look like a tax return. */
.inq .fld label{
  display:block;margin-bottom:.5rem;
  font-size:.72rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-muted);font-weight:500}
.inq .fld>.fld__hint{margin-top:.5rem}

/* ---- option rows as cards ---- */
.inq .opt{
  border-radius:14px;padding:1rem 1.1rem;min-height:56px;
  background:rgba(255,255,255,.6);
  border:1px solid rgba(29,31,24,.10);
  box-shadow:0 1px 2px rgba(20,22,15,.04)}
.inq .opt:hover{background:rgba(255,255,255,.92);border-color:rgba(29,31,24,.2)}
.inq .opt[aria-checked="true"]{
  background:#fff;border-color:var(--bronze);
  box-shadow:0 0 0 3px rgba(125,95,58,.13),0 1px 2px rgba(20,22,15,.05)}

/* ---- chips as a segmented control ---- */
.inq .chip{
  min-height:44px;padding:.65em 1.3em;
  background:rgba(255,255,255,.62);
  border:1px solid rgba(29,31,24,.10);
  box-shadow:0 1px 2px rgba(20,22,15,.04)}
.inq .chip:hover{background:rgba(255,255,255,.95);border-color:rgba(29,31,24,.2)}
.inq .chip[aria-checked="true"],
.inq .chip[aria-pressed="true"]{
  background:var(--ink);color:var(--cream);border-color:var(--ink);
  box-shadow:0 2px 8px -3px rgba(20,22,15,.42)}

/* ---- the summary and review cards ---- */
.inq .sumry,
.inq .rev__g{border-radius:16px;background:rgba(255,255,255,.62);
  border:1px solid rgba(29,31,24,.09);box-shadow:0 1px 2px rgba(20,22,15,.04)}
.inq .rev__g{box-shadow:0 1px 2px rgba(20,22,15,.04)}

/* ---- the pay block, same family ---- */
.inq .payb{border-radius:16px;background:rgba(255,255,255,.66);
  border:1px solid rgba(29,31,24,.09);box-shadow:0 1px 2px rgba(20,22,15,.04)}

/* ---- the drop zone ---- */
.inq .drop{border-radius:14px;border:1.5px dashed rgba(29,31,24,.2);
  background:rgba(255,255,255,.4);min-height:96px;align-content:center}
.inq .drop:hover{border-color:var(--bronze);background:rgba(255,255,255,.75)}


/* ==========================================================================
   THE CALENDAR, REBUILT
   --------------------------------------------------------------------------
   Two cards. A month whose days are tiles you can actually hit, and a panel
   of start times grouped morning and afternoon.

   Closed days are hatched rather than merely faded. A faded number reads as
   "not loaded yet"; diagonal ruling reads as "deliberately not available",
   which is the thing being said. The legend at the foot names all three
   states so nobody has to work the code out.

   Unavailable times are shown and struck rather than removed. A card that
   silently drops the afternoon just looks short, and the visitor cannot tell
   whether the studio shuts at two or the page failed.
   ========================================================================== */

.cal{gap:clamp(1rem,2vw,1.5rem)}

.cal__grid,.cal__side{
  background:#FCFAF6;
  border:1px solid rgba(29,31,24,.07);
  border-radius:22px;
  padding:clamp(1.1rem,2.6vw,1.5rem);
  box-shadow:0 1px 2px rgba(20,22,15,.04),0 18px 36px -28px rgba(20,22,15,.3)}
.cal.is-asked .cal__grid,.cal.is-asked .cal__side{border-color:rgba(162,71,43,.5)}

/* ---- the month ---- */
.cal__head{margin-bottom:var(--s5)}
.cal__month{font-size:clamp(1.15rem,3vw,1.45rem);color:var(--ink);font-weight:300}
.cal__month em{font-style:italic;color:var(--bronze)}
.cal__arrow{width:40px;height:40px;color:var(--ink);
  border:1px solid rgba(29,31,24,.16);background:#fff;
  transition:border-color var(--d-fast) var(--ease),
             background var(--d-fast) var(--ease),
             transform var(--d-fast) var(--ease)}
.cal__arrow:hover:not([disabled]){border-color:var(--bronze);color:var(--bronze);
  background:#fff;transform:translateY(-1px)}
.cal__arrow[disabled]{opacity:.28}
.cal__arrow:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}

.cal__dows{gap:4px;margin-bottom:.4rem}
.cal__dows span{font-size:10px;letter-spacing:.14em;color:var(--ink-faint);
  text-transform:uppercase;padding-bottom:.35rem}

/* ---- the days ---- */
.cal__days{gap:4px}
.cal__d{aspect-ratio:1;min-height:44px;border-radius:13px;
  font-size:.95rem;font-weight:400;color:var(--ink);
  background:rgba(29,31,24,.035);
  border:1px solid transparent;
  transition:background var(--d-fast) var(--ease),
             border-color var(--d-fast) var(--ease),
             transform var(--d-fast) var(--ease)}
.cal__d:hover:not([disabled]):not(.is-on){background:#fff;
  border-color:rgba(29,31,24,.18);transform:translateY(-1px)}
.cal__d:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}

.cal__d.is-on{background:var(--ink);color:var(--cream);font-weight:500;
  border-color:var(--ink);
  box-shadow:0 4px 12px -4px rgba(20,22,15,.45)}

/* today gets a dot, and it has to survive being the chosen day */
.cal__d.is-today::after{background:var(--bronze)}
.cal__d.is-on.is-today::after{background:var(--cream)}

/* Closed or full. Ruled, not just dimmed. */
.cal__d.is-off{
  color:rgba(29,31,24,.3);background:transparent;
  background-image:repeating-linear-gradient(-45deg,
    rgba(29,31,24,.11) 0 1px, transparent 1px 6px)}
.cal__d.is-off:hover{transform:none}

/* ---- the legend ---- */
.cal__key{gap:1.1rem;margin-top:var(--s5);padding-top:var(--s4);
  border-top:1px solid var(--rule-soft)}
.cal__key li{font-size:9.5px;letter-spacing:.13em;color:var(--ink-faint);
  text-transform:uppercase}
.cal__sw{width:14px;height:14px;border-radius:5px}
.cal__sw--open{background:rgba(29,31,24,.035);box-shadow:inset 0 0 0 1px rgba(29,31,24,.14)}
.cal__sw--on{background:var(--ink);box-shadow:none}
.cal__sw--off{background:repeating-linear-gradient(-45deg,
    rgba(29,31,24,.3) 0 1px, transparent 1px 5px);
  box-shadow:inset 0 0 0 1px rgba(29,31,24,.12)}

/* ---- the times ---- */
.cal__pick{font-size:clamp(1.2rem,3.2vw,1.5rem);color:var(--ink);font-weight:300;
  margin-bottom:.15rem}
.cal__pick em{font-style:italic;color:var(--bronze)}
.cal__len{margin:0 0 var(--s5);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-faint)}

.cal__band{margin:var(--s4) 0 .55rem;font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-muted);font-weight:500}
.cal__band:first-of-type{margin-top:0}

.cal__times{gap:.5rem;grid-template-columns:repeat(auto-fill,minmax(7.2rem,1fr))}

.cal__t{display:grid;gap:.1rem;place-items:center;
  min-height:56px;padding:.6rem .5rem;border-radius:15px;
  color:var(--ink);background:#fff;
  border:1px solid rgba(29,31,24,.11);
  box-shadow:0 1px 2px rgba(20,22,15,.04);
  transition:background var(--d-fast) var(--ease),
             border-color var(--d-fast) var(--ease),
             transform var(--d-fast) var(--ease)}
.cal__t:hover:not([disabled]){border-color:var(--bronze);transform:translateY(-1px)}
.cal__t:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}

.cal__t-h{font-size:1.05rem;font-weight:400;line-height:1;
  display:inline-flex;align-items:baseline;gap:.22em}
.cal__t-h i{font-style:normal;font-size:.62em;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-muted)}
.cal__t-n{font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint)}

.cal__t.is-on{background:var(--ink);border-color:var(--ink);color:var(--cream);
  box-shadow:0 4px 12px -4px rgba(20,22,15,.45)}
.cal__t.is-on .cal__t-h i{color:rgba(243,239,230,.7)}

/* the same ruling the closed days use, so the two read as one idea */
.cal__t.is-closed,.cal__t.is-taken{
  cursor:default;color:rgba(29,31,24,.34);background:transparent;
  border-color:rgba(29,31,24,.08);box-shadow:none;
  background-image:repeating-linear-gradient(-45deg,
    rgba(29,31,24,.07) 0 1px, transparent 1px 6px)}
.cal__t.is-closed .cal__t-h i,.cal__t.is-taken .cal__t-h i{color:inherit}

.cal__free{margin:var(--s5) 0 0;padding-top:var(--s4);
  border-top:1px solid var(--rule-soft);
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint)}

.cal__none{color:var(--ink-muted)}

/* ---- the empty state ---- */
.cal__blank{padding:var(--s6) var(--s4)}
.cal__mark{color:var(--bronze)}
.cal__blank-h{font-family:var(--serif);font-size:1.15rem;color:var(--ink);font-weight:300}
.cal__blank-p{font-size:var(--t-sm);color:var(--ink-muted);line-height:1.6}
.cal__blank-p strong{color:var(--bronze);font-weight:400}

@media (min-width:741px){
  .cal{grid-template-columns:1.15fr .85fr;align-items:start}
}

/* The submit failure. Since the WhatsApp hand-off went, this is the only
   thing standing between a failed booking and a visitor who thinks they
   booked, so it is loud rather than a polite grey line. */
.send__e{margin-top:var(--s4);padding:var(--s4) var(--s5);
  border-radius:var(--r-md);
  border:1px solid rgba(162,71,43,.42);
  background:rgba(162,71,43,.07);
  font-size:var(--t-sm);line-height:1.6;color:#8E3D23}


/* ==========================================================================
   ACCEPTED CARDS, IN THE FOOTER
   --------------------------------------------------------------------------
   The brand marks keep their own colours on white tiles rather than being
   tinted to suit the dark footer. Trademarks are specific about colour, and
   a white ground is what every till, card reader and checkout uses, so the
   row reads as "these work here" at a glance instead of as ornament.

   The tiles are sized in ems off one font-size, so the whole row scales
   together and stays in proportion with the type around it.
   ========================================================================== */

.ft__pay{display:grid;justify-items:center;gap:var(--s4);
  margin-top:var(--s7);padding-top:var(--s6);
  border-top:1px solid rgba(243,239,230,.1)}

.pay__k{margin:0;font-size:var(--t-xs);font-weight:500;
  letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--champagne)}

.pay__row{display:flex;flex-wrap:wrap;justify-content:center;
  align-items:center;gap:.6rem}

.pay__tile{font-size:15px;                    /* the one dial for the row */
  display:inline-flex;align-items:center;justify-content:center;gap:.4em;
  width:3.6em;height:2.35em;padding:0 .35em;
  background:#fff;border-radius:.42em;
  box-shadow:0 1px 2px rgba(20,22,15,.3),0 6px 14px -8px rgba(20,22,15,.55);
  transition:transform var(--d-fast) var(--ease),
             box-shadow var(--d-fast) var(--ease)}
.pay__tile:hover{transform:translateY(-1px);
  box-shadow:0 2px 4px rgba(20,22,15,.3),0 10px 20px -9px rgba(20,22,15,.6)}

.pay__tile svg{width:100%;height:auto;display:block}

/* Visa is a wordmark. Set tight, italic and heavy, which is how it reads,
   rather than shipping a raster of it that would go soft on a good screen. */
.pay__visa{font-family:var(--sans);font-weight:700;font-style:italic;
  font-size:.92em;letter-spacing:.01em;color:#1434CB;line-height:1}
.pay__visa--on{color:#fff}

/* ---- the two 3-D Secure badges, only drawn when config says so ---- */
.pay__tile--vs{flex-direction:column;gap:.05em;background:#1434CB;
  justify-content:center}
.pay__vs{font-family:var(--sans);font-weight:600;font-size:.42em;
  letter-spacing:.14em;color:#fff;line-height:1}
.pay__tile--wide{width:6.6em;gap:.45em}
/* Has to out-specify `.pay__tile svg{width:100%}` above, which is (0,1,1)
   against a bare class's (0,1,0). Without the extra step the icon renders
   full tile width and shoves "ID Check" out through the right edge. */
.pay__tile .pay__mc-sm{width:2.1em;height:auto;flex:none}
.pay__idc{font-family:var(--sans);font-weight:500;font-size:.56em;
  letter-spacing:.02em;color:#1D1F18;line-height:1;white-space:nowrap}

/* Centred at every width. The rest of the footer is a left-aligned grid,
   but this row is a short, symmetrical badge of trust rather than a column
   of content, and hung on the left edge under four columns it reads as an
   orphan of the last one. */

/* The two that are drawn but not switched on. See payments.cards. */
.pay__tile--amex{background:#006FCF}
.pay__amex{font-family:var(--sans);font-weight:700;font-size:.72em;
  letter-spacing:.04em;color:#fff;line-height:1}
/* Wider than the rest, because DISCOVER is eight characters against four,
   but nowhere near the 6.6em the ID Check badge needs. Borrowing that width
   made it almost twice the size of its neighbours and the row stopped
   reading as a set. */
.pay__tile--disc{width:4.9em}
.pay__disc{font-family:var(--sans);font-weight:700;font-size:.5em;
  letter-spacing:.01em;color:#1D1F18;line-height:1;white-space:nowrap}
.pay__disc span{color:#FF6000}

/* The authentication row, set a little smaller and a little quieter than
   the cards above it. These say the bank verifies the cardholder; they are
   reassurance rather than information, so they should not compete with the
   row that tells you whether your card works. */
.pay__row--sec{margin-top:.55rem;font-size:13px}
.pay__row--sec .pay__tile{font-size:inherit;opacity:.94}
.pay__row--sec .pay__tile:hover{opacity:1}

/* ---- who built it ---- */
/* Forced onto its own line under the copyright. `.ft__base` is a centred
   wrapping flex row, so a 100% basis breaks the line without needing a
   second container or a media query. */
.ft__by{flex:0 0 100%;margin-top:var(--s3);
  font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:rgba(243,239,230,.4)}

/* Brighter than the "site by" that precedes it, and underlined at a
   distance rather than on the baseline, which is what stops a rule of small
   caps looking like it has been struck through. */
.ft__by a,.ft__by-n{color:rgba(243,239,230,.66)}
/* inline-block plus padding, so the thing a thumb has to find is about
   36px tall instead of the 14px the type occupies. Nothing moves visually:
   the padding grows the hit area, not the line. */
.ft__by a{display:inline-block;padding:.62rem .3rem;
  text-decoration:underline;text-underline-offset:.32em;
  text-decoration-thickness:1px;
  text-decoration-color:rgba(243,239,230,.3);
  transition:color var(--d) var(--ease),
             text-decoration-color var(--d) var(--ease)}
.ft__by a:hover{color:var(--cream);text-decoration-color:var(--champagne)}
.ft__by a:focus-visible{outline:2px solid var(--champagne);outline-offset:3px;
  border-radius:2px}


/* ==========================================================================
   THE DESIGN STYLE QUIZ
   --------------------------------------------------------------------------
   Sits where the estimator did, on the light ground. It stays light on
   purpose: the page alternates ivory and dark bands and Collections, the
   section directly below, is dark. Two dark bands back to back would flatten
   the rhythm the whole page is built on.

   SO THE LIFT COMES FROM STRUCTURE, NOT A NEW BACKGROUND. The first version
   put all four options in matching rounded boxes, which is what a layout
   looks like when the container was chosen before the content. Each kind of
   question gets the shape its content actually wants:

     .sq__col   a palette is a WALL OF COLOUR. Five bands, floor to ceiling,
                nothing drawn around them. Picking a palette by looking at a
                palette.
     .sq__row   a worded option is an EDITORIAL ROW, hairline ruled, set in
                the display serif. The same rule this site divides
                everything else with.

   Choosing dims the options not chosen, the way samples get laid aside.
   ========================================================================== */

.sq{padding:var(--bay) var(--gutter);max-width:var(--maxw);margin-inline:auto}
.sq__head{margin-bottom:var(--s9)}
.sq__line{max-width:34rem;color:var(--ink-soft);font-size:var(--t-lede);
  line-height:1.65;margin-inline:auto;
  /* A real breath, not a tucked under one. The display's descenders ate
     the default gap and the paragraph was overlapping the heading. */
  margin-top:var(--s4)}
.sq__shell{max-width:62rem;margin-inline:auto}

/* The browser's own surfaces belong to the design too. */
.sq ::selection{background:var(--champagne);color:var(--ink)}

/* ---- the quiz, OPENED FROM INSIDE THE BOOKING ----
   The booking dialog sits at z-index 1000, so this one layers above it so
   someone can take the quiz without losing their place in the form. The
   backdrop is a touch deeper than the booking's own so the two layers do
   not look like one blurred stack. Panel is cream to match the quiz, which
   is drawn for an ivory ground. */
.sqd{position:fixed;inset:0;z-index:1100;display:grid;place-items:center;
  padding:var(--s5);background:rgba(20,22,15,.72);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
/* The homepage quiz is themed dark (see the .sq rule at line ~6018), so the
   dialog's panel takes the same olive ground to match. A cream panel would
   leave an unstyled outer frame around a dark inner. */
.sqd__box{position:relative;background:var(--olive-950);color:var(--cream);
  width:min(62rem,100%);max-height:min(94svh,58rem);
  overflow-y:auto;overscroll-behavior:contain;
  border-radius:var(--r2);box-shadow:var(--sh-lg);
  scrollbar-width:thin;scrollbar-color:rgba(217,201,169,.38) transparent}
.sqd__inner{padding:var(--s7) var(--gutter) var(--s6)}
.sqd__x{position:absolute;top:1rem;right:1rem;width:44px;height:44px;
  display:grid;place-items:center;color:var(--cream);border-radius:50%;
  background:transparent;z-index:2}
.sqd__x:hover,.sqd__x:focus-visible{background:rgba(243,239,230,.1)}
.sqd__x span{display:block;position:relative;width:18px;height:18px}
.sqd__x span::before,.sqd__x span::after{content:'';position:absolute;
  top:50%;left:0;width:100%;height:1px;background:currentColor}
.sqd__x span::before{transform:rotate(45deg)}
.sqd__x span::after{transform:rotate(-45deg)}

/* .cta--quiet is cream, drawn for the dark sections it was written in. On
   this ivory ground that is cream on cream: Back and Start again were
   invisible, measured at 1.00:1. The dialog needed the same correction. */
.sq .cta--quiet{color:var(--ink-muted)}
.sq .cta--quiet:hover,.sq .cta--quiet:focus-visible{color:var(--ink)}

.sq__open{display:flex;align-items:center;justify-content:center;
  gap:var(--s5);flex-wrap:wrap;text-align:center}
.sq__open-n{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint)}

/* ---- the count and the rule that draws ---- */
.sq__meta{display:flex;align-items:center;gap:var(--s5);margin-bottom:var(--s6)}
.sq__count{display:flex;align-items:baseline;gap:.4rem;flex:none;
  font-family:var(--serif);color:var(--ink)}
.sq__count b{font-weight:400;font-size:1.9rem;line-height:1;
  font-variant-numeric:tabular-nums}
.sq__count span{font-family:var(--sans);font-size:var(--t-xs);
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint)}
.sq__rule{flex:1;height:1px;background:var(--rule-soft);position:relative}
/* scaleX rather than width. Animating width relayouts the row on every
   frame; a transform is composited and the rule draws smoothly. */
.sq__rule i{position:absolute;inset:0;background:var(--bronze);
  transform-origin:left center;transform:scaleX(0);
  transition:transform var(--d-slow) var(--ease-out)}

/* ---- the question, at the scale the rest of the page speaks ---- */
.sq__q{font-family:var(--serif);font-weight:300;
  font-size:clamp(2rem,5.2vw,3.4rem);line-height:1.06;color:var(--ink);
  letter-spacing:-.012em;text-wrap:balance;max-width:20ch;
  margin:0 auto .6rem;text-align:center}
.sq__q:focus-visible{outline:2px solid var(--bronze);outline-offset:8px;
  border-radius:4px}
.sq__qn{font-size:var(--t-sm);color:var(--ink-muted);font-style:italic;
  text-align:center;margin-bottom:var(--s6)}
.sq__step--chip .sq__q,.sq__step--swatch .sq__q{margin-bottom:var(--s7)}

/* ---- laying one aside dims the rest ---- */
.sq__os:has(.is-on) .sq__col:not(.is-on),
.sq__os:has(.is-on) .sq__row:not(.is-on){opacity:.4}
.sq__os:has(.is-on) .sq__col:not(.is-on):hover,
.sq__os:has(.is-on) .sq__row:not(.is-on):hover{opacity:.8}

/* ========================= THE WALL OF COLOUR ========================= */
.sq__step--swatch .sq__os,
.sq__step--photo  .sq__os{display:grid;gap:clamp(.7rem,1.6vw,1.1rem);
  grid-template-columns:repeat(2,1fr)}
@media (min-width:760px){
  .sq__step--swatch .sq__os,
  .sq__step--photo  .sq__os{grid-template-columns:repeat(4,1fr)}
}

.sq__col{display:grid;gap:.85rem;text-align:left;
  transition:opacity var(--d) var(--ease),transform var(--d-fast) var(--ease)}
.sq__col-c{display:flex;flex-direction:column;overflow:hidden;
  height:clamp(190px,30vw,330px);border-radius:3px;
  box-shadow:0 1px 2px rgba(20,22,15,.07),0 20px 40px -30px rgba(20,22,15,.5);
  transition:box-shadow var(--d) var(--ease)}
.sq__col-c i{flex:1;display:block}
.sq__col-c img{width:100%;height:100%;object-fit:cover;display:block}

.sq__col-l{font-size:var(--t-xs);letter-spacing:.15em;text-transform:uppercase;
  color:var(--ink-muted);display:flex;align-items:center;gap:.5rem;
  transition:color var(--d) var(--ease)}
/* the tick is drawn, and only takes its space once it is earned */
.sq__col-l::before{content:'';width:7px;height:7px;border-radius:50%;
  flex:none;background:var(--bronze);
  transform:scale(0);transition:transform var(--d) var(--ease-out)}

.sq__col:hover{transform:translateY(-3px)}
.sq__col:hover .sq__col-c{box-shadow:0 2px 4px rgba(20,22,15,.09),
  0 30px 56px -30px rgba(20,22,15,.6)}
.sq__col:focus-visible{outline:2px solid var(--bronze);outline-offset:6px;
  border-radius:4px}

.sq__col.is-on .sq__col-l{color:var(--ink)}
.sq__col.is-on .sq__col-l::before{transform:scale(1)}
/* The chosen palette lifts out of the set. Earlier this grew the middle
   band with flex-grow, which is a layout animation; lifting reads as
   clearly and composites. */
.sq__col.is-on{transform:translateY(-6px)}
.sq__col.is-on .sq__col-c{box-shadow:0 3px 6px rgba(20,22,15,.1),
  0 34px 60px -28px rgba(20,22,15,.66)}

/* ========================== THE EDITORIAL ROW ========================= */
.sq__step--chip .sq__os{display:block;
  border-top:1px solid var(--rule)}

.sq__row{display:flex;align-items:center;gap:var(--s5);width:100%;
  padding:clamp(1.1rem,2.4vw,1.6rem) 0;text-align:left;
  border-bottom:1px solid var(--rule);
  transition:opacity var(--d) var(--ease)}
/* The row steps aside on hover by moving its contents, not by growing its
   own padding. Padding is a layout property and animating it reflows every
   row beneath this one, sixty times a second. */
.sq__row-t,.sq__row-m{transition:transform var(--d) var(--ease-out)}
.sq__row-t{flex:1;display:grid;gap:.22rem;min-width:0}
.sq__row-l{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.35rem,3.1vw,1.95rem);line-height:1.15;color:var(--ink);
  letter-spacing:-.008em}
.sq__row-n{font-size:var(--t-sm);color:var(--ink-muted);line-height:1.5}

/* the mark: an outline that fills, rather than a checkbox */
.sq__row-m{flex:none;width:19px;height:19px;border-radius:50%;
  box-shadow:inset 0 0 0 1px var(--rule-firm);position:relative;
  transition:box-shadow var(--d) var(--ease)}
.sq__row-m::after{content:'';position:absolute;inset:4px;border-radius:50%;
  background:var(--bronze);transform:scale(0);
  transition:transform var(--d) var(--ease-out)}

.sq__row:hover .sq__row-t{transform:translateX(.7rem)}
.sq__row:hover .sq__row-m{box-shadow:inset 0 0 0 1px var(--bronze)}
.sq__row:focus-visible{outline:2px solid var(--bronze);outline-offset:4px;
  border-radius:4px}
.sq__row.is-on .sq__row-t{transform:translateX(.7rem)}
.sq__row.is-on .sq__row-m{box-shadow:inset 0 0 0 1px var(--bronze)}
.sq__row.is-on .sq__row-m::after{transform:scale(1)}

.sq__nav{display:flex;align-items:center;justify-content:center;
  gap:var(--s5);margin-top:var(--s7);flex-wrap:wrap}
.sq__nav:empty{display:none}
.sq__nav .cta--fill[disabled]{opacity:.32;pointer-events:none}

/* ============================== THE RESULT ============================ */
.sq__res{max-width:52rem;margin-inline:auto;text-align:center}
.sq__rk{font-size:var(--t-xs);letter-spacing:.22em;text-transform:uppercase;
  color:var(--bronze);margin-bottom:.7rem}
.sq__rn{font-family:var(--serif);font-weight:300;
  font-size:clamp(2.4rem,7.6vw,4.6rem);line-height:.98;color:var(--ink);
  letter-spacing:-.022em;text-wrap:balance}

/* the blend, drawn to its real proportion */
.sq__mixbar{display:flex;gap:4px;height:58px;margin-top:var(--s6)}
.sq__mixbar > span{display:block;overflow:hidden;border-radius:3px;
  box-shadow:0 1px 2px rgba(20,22,15,.07)}
.sq__mix-c{display:flex;height:100%}
.sq__mix-c i{flex:1;display:block}

.sq__mix{display:flex;align-items:baseline;justify-content:center;
  flex-wrap:wrap;gap:.3rem .6rem;margin-top:var(--s4);
  font-size:var(--t-sm);color:var(--ink-muted)}
.sq__mix b{font-family:var(--serif);font-weight:400;font-size:1.5em;
  color:var(--bronze);margin-right:.12em;font-variant-numeric:tabular-nums}
.sq__mix-w{opacity:.55;font-style:italic}

.sq__rart{margin:var(--s7) 0;border-radius:var(--r-lg);overflow:hidden}
.sq__rart img{width:100%;height:auto;display:block}

.sq__rl{margin-top:var(--s6);font-size:var(--t-lede);line-height:1.68;
  color:var(--ink-soft);max-width:38rem;margin-inline:auto;text-wrap:pretty}

.sq__grid{display:grid;gap:var(--s6);margin-top:var(--s8);
  padding-top:var(--s7);border-top:1px solid var(--rule);text-align:left}
@media (min-width:760px){
  .sq__grid{grid-template-columns:1.25fr 1fr 1fr;gap:var(--s7)}
}
.sq__gk{font-size:var(--t-xs);letter-spacing:.17em;text-transform:uppercase;
  color:var(--ink-faint);margin-bottom:var(--s4)}

/* the palette shown, with its names read off the colours */
.sq__pal{list-style:none;display:grid;gap:.55rem}
.sq__pal li{display:flex;align-items:center;gap:.6rem;font-size:.9rem;
  color:var(--ink)}
.sq__pal li span{width:20px;height:20px;border-radius:50%;flex:none;
  box-shadow:inset 0 0 0 1px rgba(29,31,24,.14)}

.sq__gl{list-style:none;display:grid;gap:.4rem;font-size:.9rem;
  color:var(--ink-soft)}
.sq__gl li{position:relative;padding-left:.9rem}
.sq__gl li::before{content:'';position:absolute;left:0;top:.62em;
  width:4px;height:1px;background:var(--bronze)}

.sq__cta{margin-top:var(--s8);padding-top:var(--s7);
  border-top:1px solid var(--rule)}
.sq__ck{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.5rem,3.4vw,2.1rem);line-height:1.12;color:var(--ink)}
.sq__cl{margin-top:.6rem;color:var(--ink-soft);line-height:1.62;
  max-width:34rem;margin-inline:auto}
.sq__cb{display:flex;align-items:center;justify-content:center;
  gap:var(--s5);flex-wrap:wrap;margin-top:var(--s6)}
.sq__keep{margin-top:var(--s6);font-size:var(--t-xs);color:var(--ink-faint);
  line-height:1.6;max-width:30rem;margin-inline:auto}

@media (max-width:600px){
  .sq__cb .cta--fill{width:100%;justify-content:center}
  .sq__mixbar{height:46px}
  .sq__grid{text-align:center}
  .sq__pal{justify-items:center}
  .sq__gl li{padding-left:0}
  .sq__gl li::before{display:none}
}


/* ==========================================================================
   SPEAK TO SOMEONE
   --------------------------------------------------------------------------
   The panel the floating button opens, replacing the WhatsApp link.

   It is a panel and not a full screen dialog on purpose: this is a short
   aside, not a booking, and taking the whole window for two questions makes
   it feel heavier than it is. On a phone there is no room for that nicety,
   so it becomes a sheet.

   Cream, like the booking dialog, for the same reason: this is a form to
   fill in and the dark version of it was the thing she could not navigate.
   ========================================================================== */

.rc{position:fixed;z-index:calc(var(--z-float) + 1);
  right:clamp(1rem,2.5vw,2rem);bottom:calc(50px + clamp(1rem,2.5vw,2rem) + .75rem);
  width:min(24.5rem,calc(100vw - 2rem));
  opacity:0;transform:translateY(12px) scale(.985);transform-origin:bottom right;
  transition:opacity var(--d) var(--ease),transform var(--d) var(--ease-out);
  pointer-events:none}
.rc.is-open{opacity:1;transform:none;pointer-events:auto}

.rc__in{position:relative;background:var(--cream);color:var(--ink);
  border:1px solid rgba(29,31,24,.09);border-radius:20px;
  padding:var(--s6) var(--s5) var(--s5);
  max-height:min(76vh,40rem);overflow-y:auto;overscroll-behavior:contain;
  box-shadow:0 2px 6px rgba(20,22,15,.12),0 34px 70px -34px rgba(20,22,15,.6);
  scrollbar-width:thin;scrollbar-color:rgba(29,31,24,.34) transparent}
.rc ::selection{background:var(--champagne);color:var(--ink)}

.rc__x{position:absolute;top:.7rem;right:.7rem;width:38px;height:38px;
  display:grid;place-items:center;border-radius:50%;color:var(--ink-muted);
  transition:background var(--d) var(--ease),color var(--d) var(--ease)}
.rc__x span{position:relative;display:block;width:15px;height:15px}
.rc__x span::before,.rc__x span::after{content:'';position:absolute;top:50%;left:0;
  width:100%;height:1px;background:currentColor}
.rc__x span::before{transform:rotate(45deg)}
.rc__x span::after{transform:rotate(-45deg)}
.rc__x:hover{background:rgba(29,31,24,.06);color:var(--ink)}

.rc__k{font-size:var(--t-xs);letter-spacing:.2em;text-transform:uppercase;
  color:var(--bronze);margin-bottom:.4rem}
.rc__h{font-family:var(--serif);font-weight:300;font-size:1.7rem;line-height:1.1;
  color:var(--ink);letter-spacing:-.01em}

/* whether she is open, from the same clock as the footer badge */
.rc__hrs{display:flex;align-items:center;gap:.45rem;margin-top:.6rem;
  font-size:var(--t-xs);letter-spacing:.06em;color:var(--ink-muted)}
.rc__dot{width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--ink-faint);box-shadow:0 0 0 3px rgba(29,31,24,.07)}
.rc__dot.is-open{background:#5F8F63;box-shadow:0 0 0 3px rgba(95,143,99,.16)}

.rc__f{margin-top:var(--s5)}
.rc__set{border:0;padding:0;margin:0}
.rc__l{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-muted);margin-bottom:.6rem;padding:0}

/* ---- call me / email me ---- */
.rc__ways{display:grid;gap:.5rem}
.rc__way{display:flex;align-items:center;gap:.8rem;text-align:left;
  padding:.85rem .95rem;border-radius:14px;
  background:rgba(255,255,255,.66);border:1px solid rgba(29,31,24,.1);
  transition:background var(--d-fast) var(--ease),
             border-color var(--d-fast) var(--ease),
             transform var(--d-fast) var(--ease)}
.rc__way:hover{background:#fff;border-color:rgba(29,31,24,.2);transform:translateY(-1px)}
.rc__way:focus-visible{outline:2px solid var(--bronze);outline-offset:3px}
.rc__way.is-on{border-color:var(--bronze);background:#fff;
  box-shadow:0 0 0 3px rgba(125,95,58,.13)}
.rc__way-i{flex:none;width:34px;height:34px;display:grid;place-items:center;
  border-radius:50%;color:var(--bronze);background:rgba(125,95,58,.09)}
.rc__way-i svg{width:17px;height:17px}
.rc__way-t{display:grid;gap:.1rem;min-width:0}
.rc__way-t b{font-weight:400;font-size:1rem;color:var(--ink)}
.rc__way-t i{font-style:normal;font-size:var(--t-xs);color:var(--ink-muted)}

/* ---- the rest, once they have chosen ---- */
.rc__rest{margin-top:var(--s5);display:grid;gap:var(--s4)}
.rc__row{display:grid;gap:.4rem}
.rc__fl{font-size:var(--t-xs);letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-muted);font-weight:500}
.rc__fl i{font-style:normal;text-transform:none;letter-spacing:.02em;opacity:.62}

/* 16px minimum: under that, iOS Safari zooms the page when a field is
   tapped and the panel ends up half off the screen */
.rc__i{-webkit-appearance:none;appearance:none;width:100%;
  min-height:48px;padding:.75rem .9rem;font-size:16px;font-weight:400;
  color:var(--ink);background:rgba(255,255,255,.72);
  border:1px solid rgba(29,31,24,.1);border-radius:12px;
  transition:border-color var(--d-fast) var(--ease),
             box-shadow var(--d-fast) var(--ease),background var(--d-fast) var(--ease)}
.rc__i:focus{outline:none;background:#fff;border-color:var(--bronze);
  box-shadow:0 0 0 4px rgba(125,95,58,.14)}
.rc__i::placeholder{color:rgba(29,31,24,.38)}
.rc__t{min-height:76px;line-height:1.55;resize:vertical}

.rc__when{display:flex;gap:.4rem;flex-wrap:wrap}
.rc__w{padding:.5em 1em;border-radius:999px;font-size:var(--t-sm);
  color:var(--ink);background:rgba(255,255,255,.66);
  border:1px solid rgba(29,31,24,.1);
  transition:background var(--d-fast) var(--ease),
             border-color var(--d-fast) var(--ease)}
.rc__w:hover{border-color:var(--rule-firm)}
.rc__w.is-on{background:var(--ink);color:var(--cream);border-color:var(--ink)}
.rc__w:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}

.rc__go{width:100%;justify-content:center;margin-top:.2rem;
  background:linear-gradient(180deg,#4C5041,#3A3E31);color:var(--cream)}
.rc__go::before{background:var(--olive-950)}
.rc__go[disabled]{opacity:.45;pointer-events:none}

.rc__e{padding:.7rem .85rem;border-radius:10px;
  border:1px solid rgba(162,71,43,.4);
  background:rgba(162,71,43,.07);font-size:var(--t-sm);line-height:1.55;
  color:#8E3D23}
.rc__fine{font-size:var(--t-xs);color:var(--ink-faint);line-height:1.55}

/* ---- sent ---- */
.rc__done{display:grid;justify-items:center;text-align:center;gap:.5rem;
  padding:var(--s6) var(--s3) var(--s4)}
.rc__mark{width:48px;height:48px;color:var(--bronze)}
.rc__mark svg{width:100%;height:100%}
.rc__done-l{color:var(--ink-soft);line-height:1.6;max-width:22rem}
.rc__ref{font-size:var(--t-xs);letter-spacing:.09em;color:var(--ink-faint);
  margin-top:.3rem}

/* ---- on a phone it is a sheet ---- */
@media (max-width:600px){
  .rc{right:0;left:0;bottom:0;width:auto;transform:translateY(100%);
    transform-origin:bottom center}
  .rc.is-open{transform:none}
  .rc__in{border-radius:22px 22px 0 0;max-height:88svh;
    padding-bottom:calc(var(--s5) + env(safe-area-inset-bottom))}
}


/* ==========================================================================
   THE STYLE QUIZ ON THE DARK BAND
   --------------------------------------------------------------------------
   Asked for: the same deep olive as "Ready to start?" further up the page.

   An earlier version stayed on the ivory page on the grounds that
   Collections, directly below, is dark and two dark bands together flatten
   the page's rhythm. Collections does render, despite the `hidden` in the
   markup: app.js clears that as soon as the section has a name, and
   `collections.live` governs something else entirely.

   The two sit together anyway, because they are not the same dark. This is
   flat olive; Collections is a photograph under a scrim. Texture divides
   them where colour alone would not, and the join reads as a deliberate
   change of material rather than one long dark stretch.

   THE SECTION GOES FULL WIDTH AND THE CONTENT IS CONSTRAINED INSIDE IT.
   With max-width still on the section, the background stops short of the
   screen and the band reads as a floating rectangle rather than a stripe
   across the page.

   Everything below is the same section with its palette turned over:
   cream type, champagne where bronze was, and the dark rules. Bronze is
   #7D5F3A and the ground is #14160F, which is about 1.7 to 1 and not a
   colour anybody could read.
   ========================================================================== */

.sq{max-width:none;margin-inline:0;
  background:var(--olive-950);color:var(--cream)}
.sq__head{max-width:var(--maxw);margin-inline:auto}
.sq__line{color:var(--on-dark-soft)}
.sq .display em{color:var(--champagne)}
.sq .eyebrow{color:var(--champagne)}
.sq .cta--quiet{color:var(--on-dark-mute)}
.sq .cta--quiet:hover,.sq .cta--quiet:focus-visible{color:var(--cream)}
.sq__open-n{color:var(--on-dark-mute)}

/* ---- the question ---- */
.sq__count{color:var(--cream)}
.sq__count span{color:var(--on-dark-mute)}
.sq__rule{background:var(--rule-dark-sf)}
.sq__rule i{background:var(--champagne)}
.sq__q{color:var(--cream)}
.sq__q:focus-visible{outline-color:var(--champagne)}
.sq__qn{color:var(--on-dark-mute)}

/* ---- the wall of colour ---- */
/* The swatches themselves are untouched. They are the actual palettes and
   they read better against the dark than they did against the cream. */
.sq__col-l{color:var(--on-dark-mute)}
.sq__col-l::before{background:var(--champagne)}
.sq__col.is-on .sq__col-l{color:var(--cream)}
.sq__col:focus-visible{outline-color:var(--champagne)}
.sq__col-c{box-shadow:0 1px 2px rgba(0,0,0,.4),0 24px 44px -30px rgba(0,0,0,.8)}
.sq__col:hover .sq__col-c{box-shadow:0 2px 5px rgba(0,0,0,.45),
  0 34px 60px -30px rgba(0,0,0,.9)}
.sq__col.is-on .sq__col-c{box-shadow:0 3px 7px rgba(0,0,0,.5),
  0 38px 66px -28px rgba(0,0,0,.95)}

/* ---- the editorial rows ---- */
.sq__step--chip .sq__os{border-top-color:var(--rule-dark)}
.sq__row{border-bottom-color:var(--rule-dark)}
.sq__row-l{color:var(--cream)}
.sq__row-n{color:var(--on-dark-mute)}
.sq__row-m{box-shadow:inset 0 0 0 1px rgba(243,239,230,.32)}
.sq__row-m::after{background:var(--champagne)}
.sq__row:hover .sq__row-m,
.sq__row.is-on .sq__row-m{box-shadow:inset 0 0 0 1px var(--champagne)}
.sq__row:focus-visible{outline-color:var(--champagne)}

/* ---- the result ---- */
.sq__rk{color:var(--champagne)}
.sq__rn{color:var(--cream)}
.sq__mix{color:var(--on-dark-mute)}
.sq__mix b{color:var(--champagne)}
.sq__rl{color:var(--on-dark-soft)}
.sq__grid{border-top-color:var(--rule-dark)}
.sq__gk{color:var(--on-dark-mute)}
.sq__pal li{color:var(--cream)}
.sq__pal li span{box-shadow:inset 0 0 0 1px rgba(243,239,230,.22)}
.sq__gl{color:var(--on-dark-soft)}
.sq__gl li::before{background:var(--champagne)}
.sq__cta{border-top-color:var(--rule-dark)}
.sq__ck{color:var(--cream)}
.sq__cl{color:var(--on-dark-soft)}
.sq__keep{color:var(--on-dark-mute)}

/* The primary action inverts on a dark ground, the way .send and .inq__nav
   already do: the dark olive pill would be dark on dark. */
.sq .cta--fill{background:var(--cream);color:var(--olive-950)}
.sq .cta--fill::before{background:var(--champagne)}


/* ==========================================================================
   THE FLOATING BUTTON IS NOT A MESSAGING APP
   --------------------------------------------------------------------------
   Two mistakes made the replacement invisible.

   The icon was a speech bubble with three dots inside, which at 22px on a
   round dark button is the WhatsApp logo as far as anybody glancing at it
   is concerned. It is a headset now: unmistakably a person to speak to,
   and not a messaging app.

   And the label only appeared on hover, so at rest the button was a circle
   with a glyph and nothing else to read. On a phone there is no hover at
   all, so it could never be read there. The words are always on now, which
   is the whole point of replacing a recognisable logo with something of
   her own: if it does not say what it is, it says nothing.
   ========================================================================== */

.wa{gap:10px;padding:0 19px 0 16px}
.wa__txt{max-width:none;overflow:visible}
.wa:hover .wa__txt,.wa:focus-visible .wa__txt{max-width:none}
.wa:hover,.wa:focus-visible{gap:10px}

@media (max-width:420px){
  /* still worth the width on a phone: a label nobody can hover to reveal
     is a label nobody ever sees */
  .wa{padding:0 16px 0 13px;gap:8px;height:46px}
  .wa__txt{font-size:10.5px;letter-spacing:.16em}
}

/* ==========================================================================
   PORTFOLIO SCROLL INVITE
   --------------------------------------------------------------------------
   Drops into the bottom-left corner after someone has clearly spent a while
   looking at the work. Dismissible, shown once per session. Deliberately
   on the OPPOSITE side to the Speak to us button so the two do not fight
   for the same corner.

   On a phone it becomes a thin pinned bar across the bottom, since the
   corner tag covers too much of a small screen and would obscure the work
   it is supposed to be inviting them to book about.
   ========================================================================== */

.pginv{position:fixed;left:clamp(1rem,2.5vw,2rem);
  bottom:clamp(1rem,2.5vw,2rem);z-index:var(--z-float);
  width:min(21rem,calc(100vw - 2rem));
  padding:1.1rem 1.2rem .95rem;
  background:var(--cream);color:var(--ink);
  border:1px solid rgba(29,31,24,.09);border-radius:14px;
  box-shadow:0 2px 6px rgba(20,22,15,.12),
             0 32px 60px -32px rgba(20,22,15,.55);
  opacity:0;transform:translateY(14px);
  transition:opacity .34s var(--ease-out),transform .34s var(--ease-out)}
.pginv.is-in{opacity:1;transform:none}

.pginv__x{position:absolute;top:.5rem;right:.5rem;width:30px;height:30px;
  display:grid;place-items:center;border-radius:50%;color:var(--ink-muted);
  transition:background .18s var(--ease),color .18s var(--ease)}
.pginv__x span{position:relative;display:block;width:12px;height:12px}
.pginv__x span::before,.pginv__x span::after{content:'';position:absolute;
  top:50%;left:0;width:100%;height:1px;background:currentColor}
.pginv__x span::before{transform:rotate(45deg)}
.pginv__x span::after{transform:rotate(-45deg)}
.pginv__x:hover{background:rgba(29,31,24,.06);color:var(--ink)}

.pginv__k{font-family:var(--serif);font-weight:300;
  font-size:1.3rem;line-height:1.12;color:var(--ink);
  margin:0 1.6rem .4rem 0}
.pginv__l{font-size:var(--t-sm);line-height:1.55;color:var(--ink-soft);
  margin-bottom:.85rem}
.pginv__go{width:100%;justify-content:center;
  background:linear-gradient(180deg,#4C5041,#3A3E31);color:var(--cream)}
.pginv__go::before{background:var(--olive-950)}

@media (max-width:600px){
  .pginv{left:0;right:0;bottom:0;width:auto;max-width:none;
    border-radius:14px 14px 0 0;padding:.85rem 1rem calc(.85rem + env(safe-area-inset-bottom));
    transform:translateY(100%)}
  .pginv.is-in{transform:none}
  .pginv__k{font-size:1.05rem;margin:0 2rem .25rem 0}
  .pginv__l{display:none}
  .pginv__go{padding:.75em 1.3em}
}
