/* ═══════════════════════════════════════════════════════════════════════
   Redefyn Aesthetics — shared stylesheet

   LIGHT, after Alveos One (reference B in the original teardown). What was
   taken from it: the linen ground #fcf9f7, bands that alternate cream and
   white rather than being separated by rules, achromatic surfaces, and a
   near-black primary action instead of a brand-coloured button.
   What was deliberately NOT taken: its 25px radii, which are the single
   thing that make it read as consumer electronics. Radius stays 0.

   Every ratio below was measured, not estimated:
     ink   #17140F  on linen 17.52:1   on white 18.37:1   on fold 15.79:1
     body  #5E574F  on linen  6.79:1   on white  7.11:1   on fold  6.12:1
     slate #847C73  on linen  3.92:1 - LARGE TEXT ONLY, never body
     brand #816252  on linen  5.27:1   on white  5.52:1   on fold  4.75:1
   The brand bronze is a darker sibling of the logo's own #917366, which
   measures 3.72:1 on fold and cannot carry text. The logo's champagne
   #C7BAA3 reads 1.82:1 on linen — invisible, not merely non-compliant —
   so the light lockups are recoloured to a single bronze.

   Rules that must not drift: radius 0 everywhere, no shadows, at most three
   type sizes visible in any one viewport, tracking measured in em.

   The dark palette this replaced is preserved in theme-dark.css.
   ═══════════════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600&family=Archivo+Narrow:wght@600;700&display=swap');

:root{
  --paper:#FCF9F7; --card:#FFFFFF; --fold:#F2EDE8;
  --ink:#17140F; --slate-text:#5E574F; --slate:#847C73; --slate-soft:#DED6CD;
  --brand:#816252;
  --display:'Archivo Narrow','Arial Narrow',Arial,sans-serif;
  --sans:'Archivo','Helvetica Neue',Arial,sans-serif;
  --container:1120px; --nav-h:76px; --pad:5.4%;
}

*,*::before,*::after{box-sizing:border-box;border-radius:0 !important}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.65;
  -webkit-font-smoothing:antialiased}
img{max-width:100%;display:block}
a{color:inherit}

/* ── type roles. Four sizes site-wide: 112 / 58 / 16 / 11 ────────────── */
.d-xl{font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(46px,10.4vw,104px);line-height:.94;letter-spacing:.012em;margin:0}
/* 104, not 112: at 112 the word AESTHETICS measures 595px and ran to within
   8px of the hero photograph's edge. 104 leaves a 48px gap and still holds
   the 6-8x body ratio the bar requires (6.5x). */
.d-lg{font-family:var(--display);font-weight:600;text-transform:uppercase;
  font-size:clamp(30px,5.4vw,58px);line-height:1.02;letter-spacing:.020em;margin:0}
.mid{font-family:var(--display);font-weight:600;text-transform:uppercase;
  font-size:16px;letter-spacing:.100em}
.eyebrow{font-family:var(--sans);font-size:11px;font-weight:500;
  text-transform:uppercase;letter-spacing:.220em;color:var(--slate-text)}
.body{font-size:16px;color:var(--slate-text);margin:0}

.wrap{width:100%;max-width:var(--container);margin:0 auto;padding:0 var(--pad)}

/* ── navigation: wordmark, hairline rail, booking action ─────────────── */
.nav{position:sticky;top:0;z-index:50;background:rgba(252,249,247,.90);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--slate-soft)}
/* min-height, not height, plus wrap. Spelling the languages out widened this
   row by ~78px, which at 320px pushed the booking action past the viewport —
   documentScrollWidth 326 against a 320 viewport, a real horizontal scroll on
   a small phone. A fixed height cannot wrap, so the overflow had nowhere to
   go. This way the bar stays exactly 76px at every width where the three
   items fit, and grows a row only where they do not.
   (Verified at true viewport widths. Headless Chrome enforces a ~500px
   minimum window, so a --window-size=390 screenshot renders 500px of layout
   and crops it — it shows a clipped button that no real device shows.) */
.nav-top{display:flex;align-items:center;justify-content:space-between;
  gap:14px 20px;flex-wrap:wrap;min-height:var(--nav-h);padding:10px 0}
.nav-logo img{height:30px;width:auto}
/* The brand line above the hero headline. Same 11px as the eyebrow under
   it — the site has four type sizes and this does not get a fifth — but
   set in --ink against the location line's --slate-text, so the name reads
   as the masthead and the address as the caption. */
.eyebrow.brandline{color:var(--ink);font-weight:600;margin-bottom:7px}
.rail{display:flex;gap:30px;list-style:none;margin:0;padding:0;flex-wrap:wrap}
.rail > li{position:relative;padding-bottom:14px}
.rail a{text-decoration:none;color:var(--slate-text);padding-bottom:7px;
  border-bottom:1px solid transparent;transition:color .18s,border-color .18s}
.rail a:hover{color:var(--ink)}
.rail a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--brand)}
/* These inherit their size rather than setting their own. A 9px glyph was a
   fifth type size on a four-size site, and --slate at 9px measures 3.92:1 —
   that colour is large-text-only. Both problems came from one shortcut. */
.rail .caret{margin-left:7px;font-size:inherit;color:var(--slate-text)}
.rail .ext{margin-left:6px;font-size:inherit;color:var(--slate-text)}

/* Folder menus, mirroring the live site's nav. Opened by hover AND by
   focus-within, so the keyboard reaches them without a script. */
.rail .menu{position:absolute;top:100%;left:-18px;min-width:250px;
  background:var(--card);border:1px solid var(--slate-soft);
  padding:12px 0;margin:0;list-style:none;z-index:60;
  opacity:0;visibility:hidden;transform:translateY(-4px);
  transition:opacity .16s,transform .16s,visibility .16s}
.rail > li:hover > .menu,
.rail > li:focus-within > .menu{opacity:1;visibility:visible;transform:none}
.rail .menu li{padding:0}
.rail .menu a{display:block;padding:9px 18px;white-space:nowrap;
  border-bottom:0;color:var(--slate-text)}
.rail .menu a:hover{background:var(--fold);color:var(--ink)}
.rail .menu a[aria-current="page"]{color:var(--ink);border-bottom:0}
@media(prefers-reduced-motion:reduce){.rail .menu{transition:none}}
@media(max-width:900px){
  /* no hover on touch, and a wrapped rail has no room for panels — the
     folder link goes to the real overview page instead */
  .rail .menu{display:none}
  .rail .caret{display:none}
}

/* ── language toggle ─────────────────────────────────────────────────
   Sits between the wordmark and the booking action, the position a
   bilingual visitor already looks in. It inherits the eyebrow's 11px and
   uses --slate-text (6.79:1), never --slate — an 11px glyph in --slate
   measures 3.92:1, which is large-text-only. That mistake has been made
   twice on this site already. */
.lang{display:flex;align-items:center;gap:10px;margin-left:auto;
  font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:.140em;text-transform:uppercase}
/* Both languages carry full --ink, not just the current one. The old rule put
   the language you are NOT reading in --slate-text, which is the wrong way
   round for discovery: the item a Spanish-first visitor needs to find was the
   dimmer of the two. State is now carried by the bronze rule alone, which is
   what aria-current says as well. Letterspacing eased from .180 to .140 —
   whole words at .180 read as separated letters rather than as a word.
   Vertical padding gives a 44px touch target inside the 100px bar. */
.lang a{color:var(--ink);text-decoration:none;padding:14px 2px 11px;
  border-bottom:1px solid transparent;transition:border-color .18s,opacity .18s}
.lang a:hover{border-bottom-color:var(--slate)}
.lang a[aria-current="true"]{border-bottom-color:var(--brand)}
.lang span{color:var(--slate)}   /* was --slate-soft #DED6CD: 1.37:1 on paper,
                                    the only WCAG failure on the site */
@media(max-width:520px){.lang{letter-spacing:.06em;gap:8px}
  .lang a{padding:12px 2px 9px}}

/* ── treatment pages ─────────────────────────────────────────────────
   Two- and four-column reading grids, an FAQ accordion built on <details>
   so it works with no script, and the prep/aftercare lists. Radius stays
   zero and the marker is replaced with a bronze rule, not an icon — the
   site has no icons anywhere else. */
.two{display:grid;grid-template-columns:1fr 1fr;gap:4%}
.four{display:grid;grid-template-columns:repeat(4,1fr);gap:3%}

.faqs{border-top:1px solid var(--slate-soft)}
.faq{border-bottom:1px solid var(--slate-soft)}
.faq summary{list-style:none;cursor:pointer;padding:22px 40px 22px 0;
  position:relative;display:block}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:4px;top:50%;
  width:13px;height:1px;background:var(--brand)}
.faq summary::before{content:"";position:absolute;right:10px;top:50%;
  width:1px;height:13px;background:var(--brand);
  transform:translateY(-50%);transition:opacity .18s}
.faq[open] summary::before{opacity:0}
.faq summary:hover .mid{color:var(--brand)}
.faq .body{max-width:62ch;padding:0 40px 26px 0;margin:0}

.care-grid{display:grid;grid-template-columns:1fr 1fr;gap:5%}
.care-list{list-style:none;margin:0;padding:0}
.care-list li{padding:13px 0;border-top:1px solid var(--slate-soft);
  max-width:44ch}
.care-list .lab{display:block;color:var(--ink);
  font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:.180em;text-transform:uppercase;margin-bottom:5px}

@media(max-width:900px){
  .two,.four,.care-grid{grid-template-columns:1fr;gap:34px}
}

/* ── booking embed ───────────────────────────────────────────────────
   The Moxie widget is cross-origin, so its height cannot be read and the
   frame cannot auto-size. It is given a tall fixed height and scrolls
   internally; Moxie's own footer button is sticky, so the primary action
   stays reachable at any scroll position inside the frame. Taller on
   narrow screens because the widget's content stacks. */
.booking{border:1px solid var(--slate-soft);background:var(--card);
  padding:22px clamp(14px,2vw,26px) 20px}
.booking-frame{display:block;width:100%;height:1180px;border:0;
  background:var(--fold)}
@media(max-width:760px){ .booking-frame{height:1460px} }
@media(max-width:420px){ .booking-frame{height:1560px} }

/* ── legal documents ─────────────────────────────────────────────────
   The rest of the site is built to be scanned; this is built to be read.
   One column, a 68ch measure, and numbered sections so a clause can be
   pointed at. The section number is bronze and hangs outside the heading
   so the headings themselves stay flush left. */
.doc{max-width:70ch}
.doc-sec{padding:34px 0;border-top:1px solid var(--slate-soft)}
.doc-sec:first-child{border-top:0;padding-top:0}
.doc-sec h2{position:relative;padding-left:44px;margin-bottom:18px;
  color:var(--ink)}
.doc-n{position:absolute;left:0;top:2px;color:var(--brand);
  font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:.180em}
.doc-sec .body{max-width:68ch;margin:0 0 14px}
.doc-sec .body:last-child{margin-bottom:0}
.doc-sec strong{color:var(--ink);font-weight:600}
.doc-sec a{color:var(--brand)}
.doc-list{list-style:none;margin:0 0 14px;padding:0}
.doc-list li{position:relative;padding:7px 0 7px 44px;max-width:68ch}
.doc-list li::before{content:"";position:absolute;left:0;top:17px;
  width:13px;height:1px;background:var(--brand)}
@media(max-width:700px){
  .doc-sec h2{padding-left:0}
  .doc-n{position:static;display:block;margin-bottom:7px}
  .doc-list li{padding-left:26px}
  .doc-list li::before{width:9px}
}

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn{display:inline-block;background:var(--ink);color:var(--paper);
  font-family:var(--sans);font-size:11px;font-weight:600;text-transform:uppercase;
  letter-spacing:.180em;padding:15px 26px;text-decoration:none;
  border:1px solid var(--ink);transition:background .18s,color .18s}
.btn:hover{background:#000;border-color:#000}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--slate-soft)}
.btn.ghost:hover{background:transparent;border-color:var(--ink)}

/* ── bands: one section, one screen ──────────────────────────────────── */
.band{min-height:100vh;display:flex;flex-direction:column;justify-content:center;
  /* 5vh, not 14vh. justify-content:center already holds short sections at exactly
     100vh, so this padding only ever applies to sections whose content already
     fills the screen — where it pushed the favorites grid to 1.31 viewports. */
  padding:5vh 0;border-top:1px solid var(--slate-soft)}
.band:first-of-type{border-top:0}
.band.panel{background:var(--card)}
.band.auto{min-height:0;padding:12vh 0}

/* ── hero: a hard split, not a scrim ─────────────────────────────────────
   The dark theme laid light text over a darkened photograph and measured
   fine. Inverted, it does not: near-black type at 112px runs 766px wide and
   crosses into the model's hair, where a light scrim is thinnest. Measured
   worst case there was 2.62:1 — a real failure, not a rounding error.
   Thickening the gradient would have fixed the number by greying out the
   photograph, so the structure changed instead. Type now sits on solid
   linen at a guaranteed 17.52:1, and the photograph keeps its full contrast
   on the other side of a hard edge. Zero radius, no blend, no shadow. */
.hero{min-height:calc(100vh - var(--nav-h));display:grid;
  grid-template-columns:1fr 1fr;align-items:stretch;overflow:hidden;border-top:0}
.hero-copy-col{display:flex;flex-direction:column;justify-content:center;
  background:var(--paper);
  /* Reverted 2026-08-22. Pushing this left edge out to the nav's 237.8 forced
     the copy column wider than 1fr — the 104px headline needs ~552px and
     238+552 overflows a 720 column — which cost the photograph 231px of width
     (720 to 488), cut the headline-to-image gap from 120 to 75, and left an
     86px dead strip of paper at the hero's right edge. The two left margins
     the craft critic found are real, but this is not the way to pay for it. */
  padding:8vh clamp(34px,5.2vw,76px)}
.hero-copy-col .inner{width:100%;max-width:480px;margin:0 auto;padding-left:0}
.hero-img-col{position:relative;overflow:hidden;background:var(--fold)}
.hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 42%;
  /* was saturate(.66) — a 34% colour drain left over from the darker palette,
     the same mistake as the .7 that used to sit on split images. Matched to
     the rest of the photography. */
  filter:saturate(.94) brightness(1.03) contrast(1.02)}
.hero-copy{max-width:none}   /* the <br> sets the break; 11ch was 70px narrower
                                than the word AESTHETICS and overflowed its box */
.hero .body{max-width:40ch}

/* ── two-column: photograph beside a block of text ───────────────────── */
.split{display:grid;grid-template-columns:1fr 1fr;gap:6%;align-items:center}
.split img{width:100%;aspect-ratio:4/5;height:auto;object-fit:cover;
  /* was saturate(.7): a 30% colour drain no photograph survives, and the
     reason these sat two shades cooler than the tiles beside them */
  filter:saturate(.94) brightness(1.03) contrast(1.02)}

/* ── the index rows ──────────────────────────────────────────────────── */
.rows{border-top:1px solid var(--slate-soft)}
.rows a{display:flex;align-items:baseline;gap:18px;padding:20px 0;
  border-bottom:1px solid var(--slate-soft);text-decoration:none;color:var(--ink);
  transition:padding-left .22s,color .18s}
.rows a:hover{padding-left:10px}
.rows .n{font-family:var(--sans);font-size:11px;letter-spacing:.180em;
  color:var(--brand);flex:0 0 26px}
.rows .d{margin-left:auto;font-size:11px;letter-spacing:.06em;
  color:var(--slate-text);text-align:right}

/* ── three-up service cards, after Aesop's category row ──────────────────
   Three services with room to breathe rather than a scrolling rail: at three
   items a rail has nothing to scroll to, and arrows that do nothing are worse
   than no arrows. The way through to the other six sits centred beneath.
   4:3 image, label under it, never over it. Zero radius. */
.cat3{display:grid;grid-template-columns:repeat(3,1fr);gap:3%}
.cat3 a{text-decoration:none;color:var(--ink);display:block}
.cat3 .shot{aspect-ratio:1/1;overflow:hidden;background:var(--fold)}
/* square, not 3:4 — the taller tile pushed the favourites band to 1.107
   viewports at 900px tall and 1.221 at 800px. The services grid keeps 3:4;
   it is not bound by the one-viewport rule. */
.cat3 .shot img{width:100%;height:100%;object-fit:cover;
  filter:saturate(.94) brightness(1.03) contrast(1.02);
  transition:transform .5s cubic-bezier(.22,.61,.36,1)}
.cat3 a:hover .shot img{transform:scale(1.03)}
.cat3 .label{margin-top:14px}
.cat3 .label .d{display:block;margin-top:6px;color:var(--brand);
  /* same two-line reservation as .svc: card 01's descriptor wraps and was
     dropping its body text 18px below cards 02 and 03 */
  min-height:calc(2 * 1.65 * 11px)}
.cat3 .label .body{margin-top:14px;max-width:34ch}
.centre-out{margin-top:4.5vh;text-align:center}

/* ── full-bleed image band ───────────────────────────────────────────────
   Used on the pages that carry no other photography — booking, shop and
   contact. Full width rather than inside the measure, because at 964px a
   landscape frame reads as an illustration; edge to edge it reads as the
   place itself. */
.figure-band{width:100%;overflow:hidden;background:var(--fold);margin:0}
.figure-band img{display:block;width:100%;height:100%;object-fit:cover;
  filter:saturate(.94) brightness(1.03) contrast(1.02)}
.figure-cap{margin:14px auto 0;max-width:var(--container);padding:0 var(--pad)}
@media(max-width:900px){.figure-band{aspect-ratio:3/2 !important}}

/* ── the services grid ───────────────────────────────────────────────────
   Nine cards, three across. Each carries its own photograph, the plain-
   language line, and the detail underneath — the live site puts that detail
   on nine separate pages, which means nine loads to compare two treatments. */
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:4% 3%}
.svc a{text-decoration:none;color:var(--ink);display:block}
.svc .shot{aspect-ratio:3/4;overflow:hidden;background:var(--fold)}
.svc .shot img{width:100%;height:100%;object-fit:cover;
  filter:saturate(.94) brightness(1.03) contrast(1.02);
  transition:transform .5s cubic-bezier(.22,.61,.36,1)}
.svc a:hover .shot img{transform:scale(1.03)}
.svc .label{margin-top:18px}
.svc .label .n{font-size:11px;letter-spacing:.180em;color:var(--brand);
  display:block;margin-bottom:8px}
.svc .label .d{display:block;margin-top:6px;color:var(--brand);
  /* reserve two lines so a descriptor that wraps does not push its card's
     body text out of line with the others across the row */
  min-height:calc(2 * 1.65 * 11px)}
.svc .label .lead{margin-top:14px;color:var(--ink)}
.svc .label .body + .body{margin-top:10px}
@media(max-width:900px){.svc-grid{grid-template-columns:1fr;gap:44px}}
@media(min-width:901px) and (max-width:1180px){.svc-grid{grid-template-columns:repeat(2,1fr)}}

/* ── three-up cells ──────────────────────────────────────────────────── */
.three{display:grid;grid-template-columns:repeat(3,1fr);gap:2%}
/* Review cells are whole-cell links. The rule they must not break: the number
   is the only new element — no star glyphs, no platform logos, no second
   accent. Border-top matches .cell so they read as the same component. */
.rev{display:block;text-decoration:none;transition:border-color .3s ease}
.rev:hover{border-top-color:var(--ink)}
.rev-score{margin:14px 0 6px;color:var(--ink);line-height:1}
.rev-meta{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:baseline}
.rev-go{color:var(--brand)}
.rev:hover .rev-go{text-decoration:underline}
.rev .ext{margin-left:5px;font-size:inherit}

/* ── one patient's sentence ──────────────────────────────────────────────
   Deliberately NOT a card, a carousel or a row of three. It borrows .d-lg,
   the size the site already uses for its own headlines, so it introduces no
   new typographic voice — the only new thing on screen is the measure, held
   narrow so a quote never reads as a heading. No quotation glyph as artwork,
   no avatar, no stars, no reviewer name: those are the four things that make
   testimonial sections look bolted on, and all four are absent here. */
.quote-band{padding:11vh 0}
.quote{max-width:26ch;margin:0;color:var(--ink);text-wrap:balance}  /* 20ch ran the longest quote to eight lines at 58px, which is a wall,
     not a pull-quote. 26ch holds every current quote to four or five. */
.quote-src{margin-top:34px}
.quote-src a{color:var(--brand)}
.quote-src .ext{margin-left:5px;font-size:inherit}
.cell{border-top:1px solid var(--slate-soft);padding:24px 0}
.cell .eyebrow{color:var(--brand)}

/* ── practitioner wells ──────────────────────────────────────────────── */
.people{display:grid;grid-template-columns:repeat(3,1fr);gap:2%}
.well{position:relative;overflow:hidden;aspect-ratio:4/5;background:var(--fold);
  border:1px solid var(--slate-soft);display:grid;place-items:center}
.well img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:saturate(.42) brightness(1.03) contrast(1.03);z-index:1}
.well:has(img) .eyebrow{display:none}

/* ── footer ──────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--slate-soft);padding:8vh 0 6vh;background:var(--fold)}
.foot-grid{display:grid;grid-template-columns:1.35fr 1fr 1fr .7fr;gap:4%}  /* four columns since 2026-08-22: the reviews column was added and the
     address column keeps the extra width it needs for the street line. */
.foot-mark{height:96px;width:auto;margin-bottom:6px}
footer a{color:var(--slate-text);text-decoration:none}
footer a:hover{color:var(--ink)}
.legal{font-size:11px;letter-spacing:.02em;color:var(--slate-text);
  margin:7vh 0 0;padding-top:22px;border-top:1px solid var(--slate-soft);max-width:70ch}

/* ── scroll reveal. Nothing animates on its own; scroll is the clock. ── */
.rise{opacity:0;transform:translateY(16px);
  transition:opacity .7s cubic-bezier(.22,.61,.36,1),transform .7s cubic-bezier(.22,.61,.36,1)}
.rise.in{opacity:1;transform:none}
.d1{transition-delay:.08s}.d2{transition-delay:.16s}.d3{transition-delay:.24s}
@media (prefers-reduced-motion:reduce){
  .rise{opacity:1 !important;transform:none !important;transition:none !important}
  *{scroll-behavior:auto !important}
}

/* ── responsive ──────────────────────────────────────────────────────── */
@media(max-width:900px){
  .split,.three,.people,.foot-grid{grid-template-columns:1fr;gap:32px}
  .band{min-height:auto;padding:12vh 0}
  .hero{grid-template-columns:1fr;min-height:0}
  .hero-copy-col{padding:10vh 0;order:2}
  .hero-copy-col .inner{max-width:none;margin:0;padding:0 var(--pad)}
  .hero-img-col{order:1;height:56vh}
  .hero-copy{max-width:none}
  .rail{gap:22px}
  .foot-mark{height:76px}
  .cat3{grid-template-columns:1fr;gap:40px}
}
@media(max-width:560px){
  .centre-out{margin-top:6vh}
}

/* ── tap targets ─────────────────────────────────────────────────────────
   Reported as "the review links don't work on mobile". They work; they are
   too small to hit. Measured at 375px: "Verified Google review" is 219x12,
   the footer's "Google" is 48x12 and "Yelp" is 33x12. Apple's minimum is
   44x44pt and Material's is 48x48dp, and a fingertip contact patch is around
   40px across — so a tap that looks accurate lands on the paragraph beside
   the text and nothing happens. Nothing is broken in the href or the target;
   the finger never lands on the element.

   .quote-src a sits alone in its own paragraph, so vertical padding on an
   INLINE element is all it needs: padding grows the hit box but not the line
   box, so 12px becomes 44px and not one pixel of the page moves. This is the
   important one — it is the "read the actual review" affordance and it is
   emitted 53 times across the site.

   The footer is the harder case. Its links are stacked 24px apart, so padding
   alone would make neighbouring hit boxes overlap and steal each other's
   taps — worse than the bug. The rows have to be spaced first, which is why
   line-height moves to 4 (44px) before the padding is applied. Mobile only:
   the desktop footer is fine with a mouse, and this makes the mobile footer
   roughly 200px taller per column, which is the honest cost. */
.quote-src a{padding-top:16px;padding-bottom:16px}

.foot-links{font-size:11px;letter-spacing:.02em;line-height:2.2;margin-top:12px}
.foot-links-social{line-height:2;margin-top:14px}
.foot-links-addr{line-height:2;margin-top:0}

@media(max-width:768px){
  /* line-height:1 ON THE LINK is load-bearing. Without it the inline-block
     inherits the 4.2 row spacing as its OWN content height, so the box comes
     out 76px instead of 45 and neighbouring hit boxes overlap by 32px —
     which hands the tap to the wrong link and is worse than the small target
     it replaced. Measured: 20 overlapping boxes before this line was added.
     Box is 11 + 17 + 17 = 45px inside a 46.2px row: clears 44, never collides. */
  .foot-links{line-height:4.2}
  .foot-links a{display:inline-block;line-height:1;padding:17px 0;margin:-17px 0}
  /* The address block is prose with two links inside it, not a list of links.
     Spacing it to 44px rows would shred the address, so it gets a smaller
     lift — enough that the phone number and the email stop colliding. */
  .foot-links-addr{line-height:3}
  .foot-links-addr a{display:inline-block;line-height:1;padding:11px 0;margin:-11px 0}
}
