/* ===========================================================
   Alisa Pose — "The Lit Arch"
   Palette traced to her room: near-black off the arch surround,
   glow off the LED mirrors, brass off the rods and pendants,
   red off the gerberas on the patio table.
   =========================================================== */

@font-face{font-family:'Cormorant Garamond';src:url('../fonts/CormorantGaramond-300.woff2') format('woff2');font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'Cormorant Garamond';src:url('../fonts/CormorantGaramond-300i.woff2') format('woff2');font-weight:300;font-style:italic;font-display:swap}
@font-face{font-family:'Cormorant Garamond';src:url('../fonts/CormorantGaramond-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Cormorant Garamond';src:url('../fonts/CormorantGaramond-600.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-300.woff2') format('woff2');font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-300i.woff2') format('woff2');font-weight:300;font-style:italic;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-500.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}

:root{
  --ink:#0E0C09;          /* near-black ground */
  --ink-2:#171310;
  --glow:#FFF3D6;         /* LED arch glow */
  --brass:#B08D57;
  --brass-lo:#7A5F36;
  --bone:#F2EDE4;
  --red:#B4202C;
  /* Opaque rather than rgba so the contrast ratio is a fixed,
     checkable number: 5.69:1 on --ink, clears WCAG AA. */
  --muted:#8E8A84;
  --rule:rgba(176,141,87,.28);

  /* Both top corners carry the SAME pair of radii, which is what makes an arch
     read as an arch. The old door token was 100% on the left and 46% on the
     right: the left corner swept the full height and met the base at a tangent
     (a point), the right stopped short and left a straight wall (a square).
     Alisa saw it on every button and card and asked for one even arch. */
  --arch-door:50% 50% 0 0 / 100% 100% 0 0; /* controls: buttons, nav pill */
  /* Panels need their own token. A vertical radius of 100% is a semicircular
     head on a short wide button, but on a 440x491 card it becomes an ellipse
     taller than the card is wide — the curve swept down THROUGH the heading.
     A true arch head is half the element's WIDTH, which border-radius cannot
     express as a percentage of height, so it is given as a length that tracks
     the card: 220px against the 440px card is exactly semicircular. */
  /* The 45% ceiling is what keeps a SHORT panel from being all head and no
     jamb. A review card is 368x257, where 220px of arch eats 86% of its height
     and the card stops reading as a card. 45% of height leaves real straight
     sides on every panel, and on the tall method card 45% lands at 221px —
     within a pixel of the semicircle it wanted anyway. */
  --arch-panel:50% 50% 0 0 / min(clamp(120px,22vw,220px),45%) min(clamp(120px,22vw,220px),45%) 0 0;
  --arch-mirror:50% 50% 0 0 / 62% 62% 0 0; /* her mirrors: tall, near-semicircle */

  --pad:clamp(1.25rem,5vw,5.5rem);
  --serif:'orpheuspro','Cormorant Garamond',Georgia,serif;
  --sans:'Mulish',system-ui,-apple-system,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--ink);color:var(--bone);
  font-family:var(--sans);font-weight:300;font-size:clamp(1rem,.55vw + .88rem,1.125rem);
  line-height:1.62;overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
h1,h2,h3{font-family:var(--serif);font-weight:400;margin:0;line-height:.94;letter-spacing:-.015em}

/* Extreme scale contrast — the award-site tell */
.display{font-size:clamp(2.9rem,9.2vw,10.5rem)}
.h2{font-size:clamp(2.1rem,5.6vw,5.25rem)}
.h3{font-size:clamp(1.5rem,2.6vw,2.5rem)}
.label{
  font-family:var(--sans);font-size:.68rem;font-weight:400;
  letter-spacing:.22em;text-transform:uppercase;color:var(--brass);
}
.lede{font-size:clamp(1.05rem,1.35vw,1.35rem);color:var(--muted);max-width:46ch}

.wrap{max-width:1560px;margin-inline:auto;padding-inline:var(--pad)}
section{position:relative}

/* ---------- SplitType kinetic reveal ----------
   The line box is the mask for the word stagger, but with line-height
   below 1 the mask edge sits above the font's descender, so Orpheus's
   italic 'g' swash gets sliced off ("San Diego"). Pad the mask down and
   pull the same amount back off the layout: the reveal still works, the
   descenders survive, and line spacing is unchanged. */
.split .line{overflow:hidden;display:block;padding-bottom:.22em;margin-bottom:-.22em}
.split .word{display:inline-block;will-change:transform}
/* pre-hide only when JS is driving; no-JS keeps text visible */
.js .reveal{opacity:0}

/* ---------- 0 · Preloader: the arch draws, then opens ---------- */
#preloader{
  position:fixed;inset:0;z-index:100;background:var(--ink);
  display:grid;place-items:center;
}
#preloader .pl-arch{width:min(30vw,190px);aspect-ratio:1/1.35;
  border:1px solid var(--rule);border-radius:var(--arch-mirror);
  display:grid;place-items:end center;padding-bottom:1.1rem;position:relative;
}
#preloader .pl-fill{
  position:absolute;inset:0;border-radius:var(--arch-mirror);
  background:radial-gradient(120% 80% at 50% 100%, rgba(255,243,214,.20), transparent 68%);
  transform:scaleY(0);transform-origin:bottom;
}
#preloader .pl-num{font-family:var(--serif);font-size:1.4rem;color:var(--brass);position:relative}
#preloader .pl-mark{position:absolute;top:var(--pad);left:var(--pad)}
.pl-curtain{position:fixed;inset:0;z-index:99;background:var(--ink);transform-origin:top;pointer-events:none}


/* ---------- Nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:60;
  display:flex;align-items:center;justify-content:space-between;
  padding:1.15rem var(--pad);
  mix-blend-mode:difference;
}
.nav__mark{font-family:var(--serif);font-size:1.22rem;letter-spacing:.06em;
           display:inline-flex;align-items:center;gap:.5em}
/* Her silhouette mark. Height is tied to the wordmark so it scales with it
   in both the bar and the footer, where the type steps up to 1.6rem. */
.nav__sig{width:auto;height:1.5em;flex:none}
.nav__sig--foot{height:1.25em}
.nav__mark em{font-style:italic;color:var(--brass)}
.nav__links{display:flex;gap:clamp(1rem,2.4vw,2.4rem);align-items:center}
.nav__links a{font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;position:relative;white-space:nowrap}
/* Seven links since Before & After joined the bar (2026-09-15). At 721px that
   label wrapped to two lines and hung into the hero; kept on one line at full
   spacing the bar touched the wordmark by 860px and ran 30px off screen at 721px.
   Measured on the homepage: this tighter set leaves 35px beside the wordmark at
   721px, and full spacing still leaves about 40px above 920px. */
@media (max-width:920px){
  .nav__links{gap:.7rem}
  .nav__links a{letter-spacing:.06em;font-size:.66rem}
}
.nav__links a::after{
  content:'';position:absolute;left:0;bottom:-5px;width:100%;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:right;
  transition:transform .45s cubic-bezier(.2,.8,.2,1);
}
.nav__links a:hover::after{transform:scaleX(1);transform-origin:left}
@media (max-width:720px){.nav__links a:not(.nav__cta){display:none}}

/* ---------- 1 · Hero ----------
   The hero photo is 2:3 portrait and the arch in it — the LED mirror the whole
   site is named for — stands 83% of the frame tall and 73% of it wide. A
   full-bleed hero box is landscape at every desktop size, so cover could never
   hold that arch: measured on the live page it kept 41.7% of the picture on
   desktop and 58.7% on mobile, and the arch was clipped at the top on one and
   at both legs on the other. Alisa asked to see the picture, so the picture is
   now laid out rather than cropped: it sits beside the type on desktop, above
   it on a phone, whole in both. Nothing is object-fit anywhere in here. */
.hero{
  min-height:100svh;display:grid;align-content:end;
  gap:clamp(1.2rem,3.4vh,2.2rem);
  padding-bottom:clamp(2rem,6vh,5rem);overflow:hidden;
}
/* On a phone the picture is a centered portrait panel rather than a full-bleed
   band. Full width would make it 585px tall on a 390px screen, which is whole
   but leaves too little under it — the intro line fell below the fold. Capping
   the HEIGHT and letting width follow keeps the whole arch AND the whole first
   screen. */
.hero__media{
  position:relative;z-index:0;overflow:hidden;justify-self:center;
  width:fit-content;height:min(56svh,560px);
}
.hero__media img{display:block;height:100%;width:auto;max-width:100%}
/* Only a vignette, so the photo keeps its own light. The old overlay ran a
   solid --ink stop across the bottom because type used to sit on the picture;
   type sits on the ground now, so that band would just be a grey bar. */
/* Warm glow only. The bottom fade existed to keep type legible when the type
   sat ON the photo; it sits beside it now, so the fade had no job left except
   to darken the length of her hair, which is the thing Alisa wanted to see.
   Softening it from 66% to the last fifth lifted the bottom of the frame from
   46.4 to 62.0 mean brightness — dropping it entirely goes further, and the
   photo is a framed rectangle now, so it does not need to melt into the page. */
.hero__media::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(78% 60% at 50% 32%, rgba(255,243,214,.13), transparent 68%);
}
.hero__inner{position:relative;z-index:1;width:100%}

.hero__eyebrow{margin-bottom:clamp(1rem,3vh,2rem)}
.hero h1{max-width:16ch}
.hero h1 em{font-style:italic;color:var(--glow)}
.hero__foot{
  margin-top:clamp(1.6rem,4vh,2.8rem);display:flex;flex-wrap:wrap;
  gap:clamp(1rem,3vw,3rem);align-items:flex-end;justify-content:space-between;
}
.hero__sub{max-width:38ch;color:var(--muted);font-size:1rem}
.scroll-cue{display:flex;align-items:center;gap:.7rem;font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brass)}
.scroll-cue span.bar{display:block;width:52px;height:1px;background:var(--brass);transform-origin:left}

@media(min-width:900px){
  /* Type left, photo right, both centered on the first screen. */
  .hero{
    /* minmax(0,1fr), not 1fr. A bare 1fr floors at min-content, and the
       min-content of a display-size "Extensions" is wide enough to squeeze the
       photo track down to 258px and squash the picture. */
    grid-template-columns:minmax(0,1fr) auto;
    align-content:center;align-items:center;
    gap:clamp(2rem,5vw,5rem);
    padding-inline:var(--pad);
    /* The header is fixed and 81px tall. Without this the eyebrow line sits
       underneath the wordmark. */
    padding-block:6.5rem clamp(2rem,6vh,5rem);
  }
  /* Placed, not implied. The photo comes first in the markup so a phone stacks
     picture over words; on a wide screen the words read first, so the two are
     assigned columns rather than taking source order. */
  .hero__inner{padding-inline:0;grid-column:1;grid-row:1}
  /* Driven by HEIGHT, width follows. The other way round is circular in an auto
     track — the image collapsed to 258px and squashed — and height is the
     constraint that actually matters, because the point is that the whole
     picture fits on one screen. */
  .hero__media{
    grid-column:2;grid-row:1;justify-self:end;
    /* The flat 640px cap was set against an 800px-tall window and stayed 640px
       on a 1080px one, so the picture shrank into the dark on a big monitor
       while the headline kept growing with the viewport. 78vh lets it scale
       with the screen; the calc still guarantees it clears the fixed header. */
    width:fit-content;height:min(calc(100svh - 13rem),72vh,780px);
  }
  .hero__media img{height:100%;width:auto;max-width:100%}
  /* Let the column decide the wrap. A ch cap is guesswork against a display
     serif, and at 9ch it split the line as "in San / Diego" — a place name
     broken across two lines is the kind of thing you cannot unsee. The column
     is wide enough to hold "in San Diego" whole and narrow enough that "Hair
     Extensions" still breaks after "Hair", which is the intended shape. */
  .hero h1{max-width:100%}
  .hero__foot{flex-direction:column;align-items:flex-start;gap:1.5rem}
  .hero__sub{max-width:34ch}
}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:.85rem;
  padding:1.02rem 1.7rem;border:1px solid var(--brass);
  border-radius:var(--arch-door);
  font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;
  position:relative;overflow:hidden;color:var(--glow);
}
.btn span{position:relative;z-index:1}
.btn::before{
  content:'';position:absolute;inset:0;background:var(--brass);
  transform:scaleY(0);transform-origin:bottom;
  transition:transform .5s cubic-bezier(.2,.8,.2,1);
}
.btn:hover::before{transform:scaleY(1)}
.btn:hover span{color:var(--ink)}
.btn--solid{background:var(--brass);color:var(--ink);border-color:var(--brass)}
.btn--solid::before{background:var(--glow)}

/* ---------- 2b · Plate ----------
   Removed 2026-09-15: its photos now sit beside the story quote and the
   methods intro instead of standing alone. */

/* ---------- 2 · Marquee credential strip ---------- */
.strip{border-block:1px solid var(--rule);padding:1.05rem 0;overflow:hidden;background:var(--ink-2)}
.strip__track{display:flex;gap:3.2rem;width:max-content;will-change:transform}
.strip__track>*{
  font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap;display:flex;align-items:center;gap:3.2rem;
}
.strip__track i{width:4px;height:4px;background:var(--brass);border-radius:50%;display:inline-block}

/* ---------- 3 · Story pull ---------- */
.story{padding-block:clamp(6rem,17vh,13rem)}
/* On a phone the arch photo runs the full width, so the mask's two black
   shoulders are large — and 143px of section padding underneath them read as
   one continuous empty band before the methods section. The arch is the point,
   so the corners stay; the padding under them comes off instead. */
/* The top had the same fault and was missed: 17vh resolves to 138px on a 375px
   phone, and the .plate above it already contributes 49px, so 187px of black
   sat between the photograph and "Why extensions" — a quarter of the screen.
   Rebekah circled exactly this band on 2026-09-09. */
@media(max-width:899px){.story{padding-block:clamp(2rem,5vh,3rem) clamp(1.5rem,4vh,2.5rem)}}
.story__grid{display:grid;grid-template-columns:1fr;gap:clamp(2.5rem,6vw,5.5rem);align-items:center}
@media(min-width:900px){.story__grid{grid-template-columns:1.05fr .95fr}}
/* The portrait is first in the markup so a phone shows it above the quote.
   On desktop it moves to the right column, beside the quote. */
@media(min-width:900px){.story__figure{order:2}}
.story blockquote{margin:0;font-family:var(--serif);font-size:clamp(1.7rem,3.4vw,3.1rem);line-height:1.14;font-weight:400}
.story blockquote em{font-style:italic;color:var(--brass)}
.story__attr{margin-top:2rem;font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.figure{position:relative;overflow:hidden}
.figure--arch{border-radius:var(--arch-mirror)}
.figure img{width:100%;will-change:transform}
.figure__mask{position:absolute;inset:0;background:var(--ink);transform-origin:bottom;z-index:2}

/* ---------- 4 · Methods (pinned horizontal) ---------- */
.methods{background:var(--ink-2)}
.methods__head{
  padding-block:clamp(4.5rem,11vh,8rem) clamp(2rem,5vh,3.5rem);
  display:grid;grid-template-columns:1fr;gap:clamp(2.5rem,6vw,5.5rem);align-items:center;
}
.methods__head p{margin:1.4rem 0 0}
/* Width-capped so a 2:3 portrait beside the intro does not grow taller than
   the screen. Phone: full width, above the heading (markup order). */
@media(min-width:900px){
  .methods__head{grid-template-columns:1.15fr .85fr}
  .methods__figure{order:2;justify-self:end;width:min(100%,440px)}
}
.pin{height:100svh;overflow:hidden;display:flex;align-items:center}
.pin__track{display:flex;gap:clamp(1.25rem,2.4vw,2.4rem);padding-inline:var(--pad);will-change:transform}
.method{
  flex:0 0 auto;width:min(80vw,440px);
  border:1px solid var(--rule);border-radius:var(--arch-panel);
  padding:clamp(1.5rem,2.4vw,2.3rem);
  display:flex;flex-direction:column;gap:1.15rem;
  background:linear-gradient(to bottom, rgba(255,243,214,.045), transparent 55%);
}
.method__n{font-family:var(--serif);font-size:2.6rem;color:var(--brass-lo);line-height:1}
.method h3{margin-top:-.35rem}
.method p{margin:0;font-size:.95rem;color:var(--muted)}
.method ul{margin:.2rem 0 0;padding:0;list-style:none;display:grid;gap:.5rem}
.method li{font-size:.82rem;color:var(--muted);padding-left:1.15rem;position:relative}
.method li::before{content:'';position:absolute;left:0;top:.62em;width:6px;height:1px;background:var(--brass)}
.method__time{margin-top:auto;padding-top:1.1rem;border-top:1px solid var(--rule);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--brass)}
.pin__hint{position:absolute;bottom:clamp(1.5rem,4vh,3rem);left:var(--pad);font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}

/* ---------- 5 · Colour match ---------- */
.match{padding-block:clamp(6rem,16vh,12rem)}
.match__grid{display:grid;gap:clamp(2rem,5vw,4.5rem);grid-template-columns:1fr;align-items:center}
/* Ratio flipped with the order. The rack photo moved ahead of the copy, and
   left as it was that handed the picture the NARROWER of the two columns. */
@media(min-width:900px){.match__grid{grid-template-columns:1.1fr .9fr}}

/* ---------- 6 · Gallery ---------- */
.gallery{padding-bottom:clamp(5rem,13vh,10rem)}
.gallery__grid{display:grid;gap:clamp(.65rem,1.4vw,1.35rem);grid-template-columns:repeat(6,1fr)}
.gallery__grid .figure{grid-column:span 6}
@media(min-width:760px){
  .gallery__grid .figure{grid-column:span 2}
  .gallery__grid .figure.tall{grid-row:span 2}
  .gallery__grid .figure.wide{grid-column:span 4}
  /* .full keeps the whole row. Seven figures cannot pack a 6-column grid
     evenly, so the last one was left alone in a 2-column slot with four
     columns of dead space beside it. Giving it the row closes the hole. */
  .gallery__grid .figure.full{grid-column:span 6}
}
/* The default box is portrait, which is right for the portrait-shaped photos
   and wrong for a 3:2 one — cover would throw away half the frame. .full
   carries the source ratio instead, so nothing is cropped. */
.gallery .figure img{aspect-ratio:3/4;object-fit:cover}
.gallery .figure.wide img{aspect-ratio:16/10}
.gallery .figure.tall img{aspect-ratio:3/5}
.gallery .figure.full img{aspect-ratio:3/2}

/* The hole Alisa reported. Grid rows are auto-height, so a row is as tall as
   its tallest cell — but every image here carries a fixed aspect-ratio, so a
   shorter one left its figure padded out with dead black underneath. Measured:
   the first figure sat in a 990px slot holding a 620px image, 370px of nothing.
   Making the figure the sizing box and letting the image take its full height
   closes it; aspect-ratio yields to a definite height, so the rules above still
   decide the ROW, and only the leftover few percent gets absorbed. */
.gallery__grid .figure{display:grid}
.gallery__grid .figure > img{height:100%}

/* Instagram and the Google listing, in the footer. These are the links that
   let a search engine tie the domain to the real business. */
.foot__social{display:flex;gap:1.2rem;margin-top:1.1rem;list-style:none;padding:0}
.foot__social a{font-size:.72rem;font-weight:700;letter-spacing:.14em;
                text-transform:uppercase}

/* ---------- 6b · Instagram (live) ----------
   Tiles are 4:5, Instagram's own portrait shape, and the ratio is pinned in CSS
   rather than left to the file. The live swap replaces the src of images already
   laid out, so a pinned box is what stops the whole page jumping when eight new
   photos of unknown proportions arrive. */
.ig{padding-block:clamp(5rem,13vh,9rem);border-top:1px solid var(--rule)}
.ba__head{max-width:56ch;margin-bottom:clamp(2.5rem,6vh,4.5rem)}
.ba__head .h2{margin-top:1.4rem}
.ba__head .lede{margin-top:1.6rem}
.ba__head .lede a{color:var(--glow);text-decoration:none;border-bottom:1px solid currentColor}
/* Three across everywhere, Instagram's hairline gutter. Flex rather than grid
   so a short final row centres instead of leaving a hole — the feed returns
   nine on a good day and fewer if she has posted less. */
.ig__grid{display:flex;flex-wrap:wrap;justify-content:center;
          gap:clamp(2px,.35vw,5px);list-style:none;margin:0;padding:0}
.ig__item{flex:0 0 calc((100% - 2 * clamp(2px,.35vw,5px)) / 3)}
/* Edge to edge on a phone, because Instagram's grid has no side gutter and
   matching it was the point. The section keeps its padding for the heading;
   only the grid breaks out. */
@media(max-width:899px){
  .ig__grid{margin-inline:calc(var(--pad) * -1);width:calc(100% + var(--pad) * 2)}
}
/* Her feed is mixed: reels come back 9:16, carousels 4:5, older photos 1:1.
   cover in a 4:5 tile threw ~30% off the width of every reel, which is exactly
   where she burns her titles — "What 22 Years as a Great Lengths Expert" was
   losing a letter at each end. contain keeps the tile grid even and never
   cuts a word. The ground is a shade off --ink so the letterbox reads as a
   frame rather than a hole in the page. */
/* This is Instagram's own grid, on purpose: three across, 4:5 cells, filled.
   Checked against alisaposehair on a phone before copying it.

   The earlier version contained each photo inside a 9:16 cell over a blurred
   copy of itself, to avoid cropping. That was solving a problem that turns out
   not to exist. A 9:16 reel dropped into a 4:5 cell keeps ALL of its WIDTH and
   loses 30% of its HEIGHT, top and bottom — and her titles are set across the
   width, vertically centred. Verified by cropping all eight current posts:
   every title survives whole. Instagram trims exactly this way, which is why
   her grid reads correctly in the app.

   Three columns at every width, not four, because three is what Instagram
   uses and matching it was the request. Nine tiles, so it is a full 3x3 with
   no short final row. */
.ig__item a{display:block;position:relative;overflow:hidden;aspect-ratio:4/5;background:var(--ink)}
.ig__item a img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:opacity .5s cubic-bezier(.22,1,.36,1);
}
/* Was scale(1.04). A zoom on hover crops further into a frame that is already
   trimmed, which is how a title loses a letter. Brightness instead. */
.ig__item a:hover img{opacity:.82}
.ig__foot{margin-top:clamp(2rem,5vh,3.5rem);text-align:center}
@media(prefers-reduced-motion:reduce){.ig__item a img{transition:none}
  .ig__item a:hover img{transform:none}}

/* ---------- 7 · About ---------- */
.about{padding-block:clamp(6rem,16vh,12rem);border-top:1px solid var(--rule)}
.about__grid{display:grid;gap:clamp(2.5rem,6vw,6rem);grid-template-columns:1fr}
@media(min-width:900px){.about__grid{grid-template-columns:.85fr 1.15fr}}
.about__body p{color:var(--muted);max-width:60ch}
.about__body p+p{margin-top:1.35rem}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;margin-top:3rem;border-top:1px solid var(--rule);padding-top:2rem}
.stats dt{font-family:var(--serif);font-size:clamp(2.2rem,4.4vw,3.4rem);line-height:1;color:var(--glow)}
.stats dd{margin:.55rem 0 0;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}

/* ---------- 8 · CTA ---------- */
/* Alisa asked for this one longer, "so you can see what she is doing". The
   photo is the same 2:3 portrait as the hero; at 88svh the box was 1.59 wide
   and held 41.8% of it, which cut her off above the eyes and cut the client's
   lap away below, so the weft in her hand had nothing either side of it to
   read against. Taller box, anchored lower, and the flat 80% black is gone —
   that dimmer was doing as much of the hiding as the crop was. */
/* Height is capped against WIDTH as well as viewport height. Height alone made
   a phone 390px wide and 1046px tall, a 0.33 box holding a 0.67 picture, which
   swapped the old top-and-bottom crop for a worse one down the sides: 49% kept.
   152vw keeps the box near the photo's own shape on a narrow screen and never
   binds on a wide one. */
/* The block is anchored to the BOTTOM of the section, not centred in it. The
   section is capped at 1180px tall while the copy block is about 720px, so
   centring left roughly 230px of empty photograph under the button on any
   screen taller than about 950px — measured at 151px on a 1512x982 viewport.
   Anchoring to the end puts the button a known distance off the bottom edge at
   every size instead of a distance that moves with the viewport. */
.cta{position:relative;min-height:clamp(560px,min(124svh,152vw),1180px);display:grid;align-items:end;justify-items:center;text-align:center;overflow:hidden;padding:var(--pad) var(--pad) clamp(1.75rem,5vh,3.25rem)}
.cta__media{position:absolute;inset:0;z-index:0}
.cta__media img{width:100%;height:114%;object-fit:cover;object-position:50% 44%;will-change:transform}
/* Radial, not a bar: darkest under the type, falling to nothing at the edges,
   so the room and the colour wall stay visible instead of going flat grey. */
.cta__media::after{
  content:'';position:absolute;inset:0;
  background:
    radial-gradient(78% 62% at 50% 50%, rgba(14,12,9,.80), rgba(14,12,9,.46) 62%, rgba(14,12,9,.34) 100%),
    linear-gradient(to bottom, rgba(14,12,9,.34), rgba(14,12,9,.20) 45%, rgba(14,12,9,.42));
}
.cta__inner{position:relative;z-index:1;display:grid;justify-items:center;gap:1.9rem}
.cta h2{max-width:14ch}
/* The client's face sits low and right in this photo, and the button was
   landing level with it — two focal points competing on the same line. This gap
   keeps the button clear of her, below the eyeline rather than beside it. It is
   a fixed range rather than the old 11vh so the spacing between the copy and
   the button no longer changes with window height; the block is bottom-anchored
   now, so vh here would have moved the copy instead of the button. */
.cta .btn{margin-top:clamp(1.5rem,5vh,3.5rem)}
/* --muted is tuned for the flat ink ground, not for sitting on a photograph.
   Measured against the actual pixels behind it here, its worst case was 2.34:1
   before this change and 3.26:1 after the lighter overlay — both short of AA,
   and lifting the dimmer any further would have hidden the picture again. The
   fix belongs on the text: --bone clears 4.5:1 across the whole block. */
.cta .lede{color:var(--bone)}

/* ---------- Footer ---------- */
.foot{border-top:1px solid var(--rule);padding-block:clamp(3rem,7vh,5rem) 2.2rem}
.foot__grid{display:grid;gap:2.4rem;grid-template-columns:1fr}
@media(min-width:760px){.foot__grid{grid-template-columns:1.4fr 1fr 1fr}}
.foot h4{font-family:var(--sans);font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brass);margin:0 0 1.1rem;font-weight:400}
.foot p,.foot li{color:var(--muted);font-size:.92rem;margin:0}
.foot ul{list-style:none;padding:0;display:grid;gap:.55rem}
.foot__base{margin-top:3.2rem;padding-top:1.5rem;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;font-size:.7rem;letter-spacing:.1em;color:var(--muted)}

/* ---------- Reduced motion: everything visible, nothing moves ---------- */
@media (prefers-reduced-motion:reduce){
  .js .reveal{opacity:1!important}
  .figure__mask{display:none}
  .strip__track{animation:none}
  #preloader{display:none}
  *{scroll-behavior:auto!important}
}

/* ---------- 8 · FAQ ---------- */
.faq{padding-block:clamp(5rem,14vh,10rem);border-top:1px solid var(--rule)}
.faq__grid{display:grid;gap:clamp(2.5rem,5vw,5rem);grid-template-columns:1fr}
@media(min-width:900px){.faq__grid{grid-template-columns:.8fr 1.2fr;align-items:start}
  .faq__head{position:sticky;top:clamp(5rem,14vh,9rem)}}
.qa{border-bottom:1px solid var(--rule)}
.qa summary{
  list-style:none;cursor:pointer;padding:1.5rem 2.5rem 1.5rem 0;position:relative;
  display:block;transition:color .3s;
}
.qa summary::-webkit-details-marker{display:none}
.qa__q{font-family:var(--serif);font-size:clamp(1.15rem,1.9vw,1.65rem);font-weight:400;margin:0;line-height:1.2}
.qa summary::after{
  content:'';position:absolute;right:.35rem;top:50%;width:13px;height:1px;
  background:var(--brass);transition:transform .4s cubic-bezier(.2,.8,.2,1);
}
.qa summary::before{
  content:'';position:absolute;right:.35rem;top:50%;width:13px;height:1px;
  background:var(--brass);transform:rotate(90deg);
  transition:transform .4s cubic-bezier(.2,.8,.2,1);
}
.qa[open] summary::before{transform:rotate(0deg)}
.qa summary:hover .qa__q{color:var(--glow)}
.qa__a{padding:0 clamp(1rem,4vw,3.5rem) 1.7rem 0}
.qa__a p{margin:0;color:var(--muted);font-size:.98rem}
.qa__a a{color:var(--glow);border-bottom:1px solid var(--rule)}

/* ---------- Consent bar ---------- */
.consent{
  position:fixed;left:var(--pad);right:var(--pad);bottom:1.1rem;z-index:80;
  background:var(--ink-2);border:1px solid var(--rule);border-radius:6px;
  padding:1rem 1.2rem;display:flex;flex-wrap:wrap;gap:1rem;
  align-items:center;justify-content:space-between;
  max-width:640px;margin-inline:auto;
}
.consent p{margin:0;font-size:.82rem;color:var(--muted);flex:1 1 260px}
.consent__btns{display:flex;gap:.6rem}
.consent button{
  font-family:var(--sans);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  padding:.65rem 1.1rem;border:1px solid var(--rule);background:none;color:var(--bone);cursor:pointer;
}
.consent button[data-consent="granted"]{background:var(--brass);color:var(--ink);border-color:var(--brass)}

/* CTA that has no destination yet must not look clickable */
.btn[aria-disabled="true"]{opacity:.55;cursor:not-allowed}
.btn[aria-disabled="true"]::before{display:none}

/* Screen-reader-only NAP for crawlers that ignore the footer layout */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- Tap targets: the two conversion links must clear 44px.
     Google's mobile usability check flags anything smaller, and these
     are literally the "book" and "call" actions.                   ---------- */
.nav__links a.nav__cta{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 1.15rem;
  border:1px solid currentColor;border-radius:var(--arch-door);
}
.nav__links a.nav__cta::after{display:none}
.foot address a,
.foot a[href^="tel:"]{
  display:inline-flex;align-items:center;min-height:44px;
}
.qa summary{min-height:44px}

/* ---------- Nav legibility.
     mix-blend-mode:difference reads beautifully over the dark body but
     collapses over the bright top of the hero photo. Give the bar its
     own scrim so the links clear contrast on every background. ---------- */
.nav{mix-blend-mode:normal}
.nav::before{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom, rgba(14,12,9,.72), rgba(14,12,9,0));
}
.nav__mark,.nav__links a{text-shadow:0 1px 14px rgba(14,12,9,.75)}

/* The hero overlay used to be redefined here, darkening the top band so the
   eyebrow and nav could sit on the photo, and the bottom band along with
   it. Both are obsolete: the nav carries its own scrim just above, and the
   eyebrow moved off the picture when the hero became two columns. It was
   also the rule that actually WON — softening the gradient further up the
   file changed nothing on the real page, and only looked like it worked
   because the test injected its own !important. One rule governs the hero
   overlay now, and it is the one up in section 1. */
.hero__eyebrow{color:var(--glow);text-shadow:0 1px 12px rgba(14,12,9,.8)}


/* ---------- Text rendering.
     Chrome paints non-composited text with LCD subpixel antialiasing,
     which fringes light-on-dark type with purple and orange. Measured
     at 9.4% coloured pixels across a paragraph. Promoting the prose to
     its own layer switches it to grayscale AA: measured 0.0%.
     Scoped to text blocks so we are not promoting the whole document. ---------- */
.lede,.hero__sub,.story blockquote,.about__body,.method p,.method li,
.qa__a,.stats dd,.foot p,.foot li,.label,.method__time{
  transform:translateZ(0);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* ===========================================================
   MOBILE
   =========================================================== */

/* The pinned rail is a desktop move. At 390px a card plus gutters is
   wider than the viewport, so a pinned track can only ever show two
   clipped half-cards. Below 900px the same markup becomes a native
   scroll-snap carousel: one whole card at a time, swiped. */
@media (max-width:899px){
  .pin{height:auto;overflow:visible;display:block}
  .pin__track{
    transform:none!important;
    overflow-x:auto;overflow-y:hidden;
    scroll-snap-type:x mandatory;
    scroll-padding-inline:var(--pad);
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    padding-block:.5rem 1.75rem;
  }
  .pin__track::-webkit-scrollbar{display:none}
  .method{width:min(84vw,420px);scroll-snap-align:center;flex-shrink:0}
  .pin__hint{position:static;padding:0 var(--pad) 3rem}
}
.hint-m{display:none}
@media (max-width:899px){ .hint-d{display:none} .hint-m{display:inline} }

/* Mobile menu */
.nav__burger{
  display:none;width:44px;height:44px;padding:0;border:0;background:none;
  cursor:pointer;position:relative;color:inherit;
}
.nav__burger span{
  position:absolute;left:11px;width:22px;height:1px;background:currentColor;
  transition:transform .35s cubic-bezier(.2,.8,.2,1),opacity .2s;
}
.nav__burger span:first-child{top:19px}
.nav__burger span:last-child{top:25px}
body.menu-open .nav__burger span:first-child{transform:translateY(3px) rotate(45deg)}
body.menu-open .nav__burger span:last-child{transform:translateY(-3px) rotate(-45deg)}
@media (max-width:720px){ .nav__burger{display:block} }

.navmenu{
  position:fixed;inset:0;z-index:59;background:var(--ink);
  display:flex;flex-direction:column;justify-content:center;gap:2.5rem;
  padding:var(--pad);
}
.navmenu[hidden]{display:none}
.navmenu nav{display:grid;gap:.35rem}
.navmenu nav a{
  font-family:var(--serif);font-size:clamp(2rem,9vw,3rem);line-height:1.18;
  display:block;padding:.15em 0;
}
.navmenu__foot{display:grid;gap:.5rem;border-top:1px solid var(--rule);padding-top:1.5rem}
.navmenu__foot a{font-size:.92rem;color:var(--muted);min-height:44px;display:flex;align-items:center}
body.menu-open{overflow:hidden}

/* The fixed wordmark sat directly on top of the footer's "Visit" heading.
   Give the footer room to clear it. */
@media (max-width:720px){
  .foot{padding-top:clamp(4rem,10vh,6rem)}
}


/* Guard. `.wrap` and a section class have equal specificity, so a later
   `padding: X 0` shorthand silently wipes the horizontal padding and the
   section runs flush to the screen edge. That bug shipped twice. Re-assert
   the inline padding last so source order can no longer lose it. */
.wrap{padding-inline:var(--pad)}

/* Nav auto-hide. Transform only, so it never affects layout. */
.nav{transition:transform .45s cubic-bezier(.2,.8,.2,1),background-color .45s}
.nav--down{transform:translateY(-115%)}
.nav--up{background-color:rgba(14,12,9,.88);backdrop-filter:blur(9px)}
.nav--up::before{opacity:0}
body.menu-open .nav{transform:none!important;background:none}
@media (prefers-reduced-motion:reduce){ .nav{transition:none} .nav--down{transform:none} }

/* ===========================================================
   10 · CONSULTATION FORM
   =========================================================== */
.consult{padding-block:clamp(5rem,14vh,10rem);border-top:1px solid var(--rule);background:var(--ink-2)}
.consult__grid{display:grid;gap:clamp(2.5rem,5vw,5rem);grid-template-columns:1fr}
@media(min-width:960px){
  .consult__grid{grid-template-columns:.85fr 1.15fr;align-items:start}
  .consult__intro{position:sticky;top:clamp(5rem,14vh,9rem)}
}
.consult__intro .lede{margin-top:1.6rem}
.consult__aside{list-style:none;padding:0;margin:2.2rem 0 0;display:grid;gap:.9rem;
  border-top:1px solid var(--rule);padding-top:1.6rem}
.consult__aside li{font-size:.9rem;color:var(--muted)}
.consult__aside strong{color:var(--glow);font-weight:400}
.consult__aside a{color:var(--glow);border-bottom:1px solid var(--rule)}

.cform{display:grid;gap:1.6rem}
.cform__field{display:grid;gap:.55rem;min-width:0}
.cform__field > label,.cform legend{
  font-family:var(--sans);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brass);padding:0;
}
.req{color:var(--red)}
.cform fieldset{border:0;padding:0;margin:0;display:grid;gap:.9rem}
.cform input[type=text],.cform input[type=email],.cform input[type=tel],.cform textarea{
  width:100%;background:transparent;color:var(--bone);
  border:0;border-bottom:1px solid var(--rule);
  font-family:var(--sans);font-size:1rem;font-weight:300;
  padding:.7rem 0;border-radius:0;
  transition:border-color .3s;
}
.cform textarea{resize:vertical;line-height:1.5}
.cform input:focus,.cform textarea:focus{outline:0;border-bottom-color:var(--glow)}
.cform input::placeholder,.cform textarea::placeholder{color:rgba(142,138,132,.7)}

.cform__radios{display:flex;flex-wrap:wrap;gap:.65rem}
.cform__radios--stack{flex-direction:column;align-items:flex-start}
.cform__radios label{
  display:inline-flex;align-items:center;gap:.6rem;cursor:pointer;
  border:1px solid var(--rule);border-radius:var(--arch-door);
  padding:.7rem 1.1rem;min-height:44px;
  font-size:.9rem;color:var(--muted);transition:border-color .3s,color .3s,background-color .3s;
}
.cform__radios input{accent-color:var(--brass);width:15px;height:15px;flex:none}
.cform__radios label:hover{border-color:var(--brass);color:var(--bone)}
.cform__radios label:has(input:checked){border-color:var(--brass);color:var(--glow);background:rgba(176,141,87,.12)}
.cform__radios label:focus-within{outline:2px solid var(--glow);outline-offset:2px}

.cform input[type=file]{
  font-family:var(--sans);font-size:.86rem;color:var(--muted);
  border:1px dashed var(--rule);border-radius:4px;padding:1rem;width:100%;
}
.cform input[type=file]::file-selector-button{
  font-family:var(--sans);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  background:none;border:1px solid var(--brass);color:var(--glow);
  padding:.6rem 1rem;margin-right:1rem;cursor:pointer;border-radius:2px;
}
.cform__hint{margin:0;font-size:.78rem;color:var(--muted)}
.cform__row{display:grid;gap:1.6rem;grid-template-columns:1fr}
@media(min-width:560px){.cform__row{grid-template-columns:1fr 1fr}}
.cform__pot{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cform__submit{justify-self:start;margin-top:.4rem;border:0}
.cform__submit[disabled]{opacity:.6;cursor:progress}
.cform__error{margin:0;color:#FF9A9A;font-size:.9rem}
.cform__done{border:1px solid var(--rule);border-radius:var(--arch-panel);padding:clamp(1.8rem,4vw,3rem);align-self:start}
.cform__done p{color:var(--muted);margin:1rem 0 0}
.cform__done a{color:var(--glow);border-bottom:1px solid var(--rule)}

/* The file input and long legends are the two things that blow out a
   narrow viewport if left unchecked. */
@media(max-width:420px){
  .cform__radios{flex-direction:column;align-items:stretch}
  .cform__radios label{width:100%}
}

/* ===========================================================
   AUTHORITY PAGES (one per method)
   =========================================================== */
.apage{padding-top:clamp(5.5rem,12vh,8rem)}
.apage__crumbs{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding-block:1rem}
.apage__crumbs a{color:var(--brass)}
.apage__crumbs span[aria-hidden]{margin-inline:.5rem;color:var(--rule)}
.apage__hero{padding-block:clamp(1.5rem,4vh,3rem) clamp(2rem,5vh,3.5rem);max-width:960px;margin-inline:auto}
.apage__hero h1{margin:1.2rem 0 0}
.apage__hero .lede{margin-top:1.6rem}
.apage__stat{margin:1.6rem 0 0;font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;color:var(--brass)}
/* Method hero with its own photo: text left, portrait right (Rebekah, 2026-09-15).
   The full-width 16/9 figure under the text cropped these shots badly and showed
   them far larger than their pixels support; a portrait column beside the text is
   both the look she asked for and a box these files are actually sharp in. */
.apage__hero--media{max-width:none}
/* Size cap, measured at a 1512px viewport (Rebekah, 2026-09-15: "the entire frame
   is too big on a desktop"). Uncapped, the picture column ran 578px wide and the
   9:16 frames rendered 1049px tall, so the hero alone was 1130px — taller than a
   900px window. The home page's standard gallery tile is 530x707 at that width;
   420px puts a 9:16 photo at ~420x762 and a 3:4 at ~420x560, the same order of
   size, still with no crop. */
.apage__heroFig{margin:clamp(1.8rem,4vh,2.6rem) 0 0;max-width:420px}
/* No fixed aspect: a 3:4 box cut a quarter of the height off the three phone
   frames and read as too zoomed in (Rebekah, 2026-09-15). Each photo keeps its
   own shape and shows whole. */
.apage__heroFig img{width:100%;height:auto;
  border-radius:var(--arch-panel);box-shadow:0 0 0 1px rgba(176,141,87,.5)}
@media(min-width:980px){
  .apage__hero--media{display:grid;grid-template-columns:1.1fr .9fr;
    gap:clamp(2rem,4vw,4rem);align-items:center}
  .apage__hero--media .apage__heroText{max-width:56ch}
  .apage__heroFig{margin:0}
}
.apage__figure{margin:0;padding-block:clamp(1.5rem,4vh,3rem)}
/* --arch-door is a BUTTON token: its own comment says "buttons, nav pill", and
   its vertical radius is 100%, so the curve spans the element's whole height.
   On a button that is the shape. On a 16:9 photograph it ate the left and right
   of the frame from the bottom edge up, which is what Rebekah reported on
   2026-09-09 as "image is cut off on all the pages about the types of
   extensions" — the subject was being masked away, not badly cropped.
   --arch-panel caps the curve at clamp(120px,22vw,220px), so the arch still
   reads as a doorway and the lower two thirds of the frame stay full width. */
.apage__figure img{width:100%;border-radius:var(--arch-panel);aspect-ratio:16/9;object-fit:cover}
.apage__body{display:grid;gap:clamp(2.5rem,5vw,4.5rem);grid-template-columns:1fr;padding-block:clamp(2rem,6vh,4rem) clamp(4rem,12vh,8rem)}
@media(min-width:980px){.apage__body{grid-template-columns:1.35fr .65fr;align-items:start}
  .apage__aside{position:sticky;top:clamp(5rem,14vh,8rem)}}
.apage__block{margin-bottom:clamp(2rem,5vh,3.2rem)}
.apage__block h2{margin-bottom:1rem}
.apage__prose p{color:var(--muted);max-width:64ch;margin:0}
.apage__benefits{list-style:none;padding:0;margin:0;display:grid;gap:.7rem}
.apage__benefits li{color:var(--muted);padding-left:1.3rem;position:relative}
.apage__benefits li::before{content:'';position:absolute;left:0;top:.72em;width:8px;height:1px;background:var(--brass)}
.apage__aside{display:grid;gap:1.25rem}
.apage__card{border:1px solid var(--rule);border-radius:var(--arch-panel);padding:clamp(1.4rem,2.4vw,2rem);display:grid;gap:1rem}
.apage__card p{margin:0;color:var(--muted);font-size:.95rem}
.apage__card .btn{justify-self:start}
.apage__meta{font-size:.82rem!important}
.apage__meta strong{color:var(--glow);font-weight:400}
.apage__meta a{color:var(--glow);border-bottom:1px solid var(--rule)}
.apage__others{list-style:none;padding:0;margin:0;display:grid;gap:.85rem}
.apage__others a{display:flex;gap:.7rem;font-size:.92rem;color:var(--muted);min-height:44px;align-items:center}
.apage__others a:hover{color:var(--glow)}
.apage__n{font-family:var(--serif);color:var(--brass-lo)}
.apage .qa:first-of-type{border-top:1px solid var(--rule)}

/* Method card links into the authority pages */
.method h3 a{display:block}
.method h3 a:hover{color:var(--glow)}
.method__more{
  display:inline-flex;align-items:center;gap:.5rem;min-height:44px;
  font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--brass);
}
.method__more::after{content:'\2192';transition:transform .3s}
.method__more:hover{color:var(--glow)}
.method__more:hover::after{transform:translateX(4px)}

/* Journal index */
.jgrid{list-style:none;padding:0;margin:0;display:grid;gap:clamp(1.2rem,2.4vw,2rem);
  grid-template-columns:1fr}
@media(min-width:720px){.jgrid{grid-template-columns:1fr 1fr}}
@media(min-width:1100px){.jgrid{grid-template-columns:repeat(3,1fr)}}
.jcard a{display:grid;gap:.9rem;height:100%;align-content:start;
  border:1px solid var(--rule);border-radius:var(--arch-panel);
  padding:clamp(1.1rem,2vw,1.5rem);transition:border-color .3s,background-color .3s}
.jcard a:hover{border-color:var(--brass);background:rgba(176,141,87,.06)}
/* calc() cannot halve a border-radius shorthand, so the old
   calc(var(--arch-door)/2) was invalid and the thumbnail had square
   corners all along. A plain even arch head instead. */
.jcard img{width:100%;aspect-ratio:16/10;object-fit:cover;border-radius:50% 50% 0 0 / 34% 34% 0 0}
.jcard h2{margin:0}
.jcard p{margin:0;color:var(--muted);font-size:.92rem}

/* Before & after gallery (/before-and-after/)
   Same frame as the homepage arches: a brass hairline around an arch head, the
   label set in the italic serif. Every image is cropped to 3:4 at export so the
   arches line up; object-fit only guards against a future file that is not. */
.bagal{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:1fr;
  gap:clamp(3rem,7vh,5rem) clamp(1.5rem,3vw,3rem)}
@media(min-width:900px){.bagal{grid-template-columns:1fr 1fr}}
.bapair{display:grid;gap:1.2rem;align-content:start}
.bapair__frames{display:grid;grid-template-columns:1fr 1fr;gap:clamp(.6rem,1.4vw,1.1rem)}
.bapair__fig{margin:0;display:grid;gap:.7rem;justify-items:center}
.bapair__fig img{width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;
  border-radius:50% 50% 0 0 / 30% 30% 0 0;box-shadow:0 0 0 1px rgba(176,141,87,.55)}
.bapair__fig figcaption{font-family:var(--serif);font-style:italic;color:var(--bone);
  font-size:clamp(1.35rem,2vw,1.75rem);line-height:1}
.bapair__title{margin:0;text-align:center;font-family:var(--sans);font-weight:500;
  font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brass)}
.bagal__foot{margin-top:clamp(3.5rem,9vh,6rem);display:grid;justify-items:center;gap:1.6rem;text-align:center}
.bagal__foot p{margin:0;color:var(--muted);max-width:52ch}

/* ---------- Reviews ---------- */
.reviews{padding-block:clamp(5rem,14vh,10rem);border-top:1px solid var(--rule);background:var(--ink-2)}
.reviews__head{max-width:60ch}
.reviews__head .lede{margin-top:1.6rem}
/* nowrap so the call to action cannot be split across a line break. It was
   landing as "Read them on" / "Google." mid-sentence, which reads as a typo. */
.reviews__head a{color:var(--glow);border-bottom:1px solid var(--rule);white-space:nowrap}
/* Flex, not grid, because there are five reviews and three columns. Grid left
   the last two hard against the left edge with a card-and-a-half of dead space
   beside them — the same hole Alisa flagged in the gallery. Flex lets the
   short final row centre under the full one. */
.reviews__grid{list-style:none;padding:0;margin:clamp(2.5rem,6vh,4rem) 0 0;
  display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(1rem,2vw,1.5rem)}
.reviews__grid > .rev{flex:1 1 100%}
@media(min-width:720px){.reviews__grid > .rev{flex:0 1 calc((100% - clamp(1rem,2vw,1.5rem)) / 2)}}
@media(min-width:1100px){.reviews__grid > .rev{flex:0 1 calc((100% - 2 * clamp(1rem,2vw,1.5rem)) / 3)}}
.rev{border:1px solid var(--rule);border-radius:var(--arch-panel);
  padding:clamp(1.3rem,2.2vw,1.9rem);display:grid;gap:1rem;align-content:start}
.rev__stars{margin:0;color:var(--brass);letter-spacing:.22em;font-size:.82rem}
.rev blockquote{margin:0}
.rev blockquote p{margin:0;color:var(--bone);font-size:.98rem;line-height:1.6}
.rev__by{font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;color:var(--brass)}
.rev__by span{color:var(--muted);text-transform:none;letter-spacing:.04em}
