/* V3: the research build. Overrides the faithful base stylesheet.
   Type system, layout patterns, and motion spec follow Lane 5 of
   docs/research/website-deep-research-2026-08-13.md:
   Playfair Display as editorial serif accent (same face as her guide PDFs),
   tracked caps micro-labels,
   150-300ms hovers, 400-600ms one-time reveals, ease only, no bounce. */

:root {
  --serif: "Playfair Display", Georgia, serif;
  --ink-quiet: #6A6A66;
}

/* ---------- type system ---------- */

h1, h2 {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: -0.005em;
  line-height: 1.06;
}

h1 { font-size: clamp(38px, 4.4vw, 60px); }
h2 { font-size: clamp(30px, 3.6vw, 46px); }

h1 em, h2 em { font-style: italic; font-weight: 400; }

.v3 h3 { font-family: var(--font); font-size: 19px; font-weight: 500; letter-spacing: 0; }

.v3 .eyebrow, .micro-label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: 20px;
}

.lede { font-size: 18px; line-height: 1.7; }

/* Positive top margin: the base reset zeroes all margins, so a negative value
   here pulled the paragraph into the h2's descenders at desktop sizes. */
.section-lede { max-width: 620px; margin-top: 18px; margin-bottom: 44px; color: var(--ink-soft); }

.fine { font-size: 14.5px; line-height: 1.65; color: var(--ink-quiet); }
.fine.alt { margin-top: 4px; }
.fine.center { text-align: center; margin-top: 34px; }
.fine a { text-decoration: underline; text-underline-offset: 3px; }

.v3 h2 + .situations, .v3 h2 + .method, .v3 h2 + .offer-cards { margin-top: 52px; }

/* ---------- header ---------- */

.v3 .site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(255,255,255,.88);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: box-shadow .3s ease;
}

.v3 .site-header.scrolled { box-shadow: 0 1px 22px rgba(0,0,0,.06); }

.v3 .site-nav a { position: relative; }

.v3 .site-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -5px;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .25s ease;
}

.v3 .site-nav a:hover::after, .v3 .site-nav a[aria-current="page"]::after { transform: scaleX(1); }
.v3 .site-nav a:hover, .v3 .site-nav a[aria-current="page"] { text-decoration: none; }

/* ---------- buttons ---------- */

.v3 .btn {
  border: 1px solid #000;
  transition: background .25s ease, color .25s ease;
}

.v3 .btn:hover { background: #fff; color: #000; opacity: 1; }

/* secondary CTA: a quiet underlined link, never a boxed button, so it cannot
   compete with the booking CTA. Specificity must beat `.v3 .btn` above. */
.v3 .btn.btn--quiet {
  background: none;
  color: var(--ink);
  border: none;
  border-bottom: 1px solid var(--ink);
  padding: 0 0 6px;
  transition: color .25s ease, border-color .25s ease;
}

.v3 .btn.btn--quiet:hover { background: none; color: var(--ink-quiet); border-bottom-color: var(--ink-quiet); }

/* ---------- hero ---------- */

.v3 .hero-intro { justify-content: center; display: flex; flex-direction: column; }
.v3 .hero .lede { font-size: 17px; }
.v3 .hero-cta-line { margin-bottom: 4px; }

@media (prefers-reduced-motion: no-preference) {
  .v3 .hero-intro > *, .v3 .hero-band > * {
    opacity: 0;
    transform: translateY(16px);
    animation: v3rise .6s cubic-bezier(.4,0,.2,1) forwards;
  }
  .v3 .hero-intro > *:nth-child(2) { animation-delay: .1s; }
  .v3 .hero-band > *:nth-child(1) { animation-delay: .2s; }
  .v3 .hero-band > *:nth-child(2) { animation-delay: .28s; }
  .v3 .hero-band > *:nth-child(3) { animation-delay: .36s; }
}

@keyframes v3rise { to { opacity: 1; transform: none; } }

/* ---------- credibility line ---------- */

/* no border-bottom: the .credentials strip sits directly beneath and brings its
   own border-top, so a border here would read as a double rule */
.credline { padding: 44px 0 34px; }

.credline p {
  text-align: center;
  font-size: clamp(15px, 1.6vw, 18px);
  color: var(--ink-soft);
  max-width: 900px;
  margin: 0 auto;
}

.credline span { color: var(--ink); }

/* Press pull quote sits above the experience line: the strongest proof reads
   first, the qualifying detail underneath it. */
.press {
  margin: 0 auto 26px;
  max-width: 760px;
  text-align: center;
}

/* scoped to .credline so these beat the .credline p rule above on specificity
   rather than on source order */
.credline .press p {
  font-family: var(--serif);
  font-size: clamp(21px, 2.9vw, 30px);
  line-height: 1.28;
  color: var(--ink);
  font-style: italic;
  margin: 0 auto 12px;
  max-width: 34ch;
  text-wrap: balance;
}

/* Both press quotes carry the same weight, Michael's call. The second only
   needs the gap above it closed so the pair reads as one block. */
.press-second { margin-top: -4px; }

.press cite {
  font-style: normal;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.credline .credline-sub {
  margin: 10px auto 0;
  font-size: clamp(13.5px, 1.3vw, 15px);
}

/* ---------- who this is for ---------- */

.situations {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 44px 60px;
}

.situations h3 { margin-bottom: 10px; }
.situations p { color: var(--ink-soft); font-size: 16px; }

@media (max-width: 780px) { .situations { grid-template-columns: 1fr; gap: 34px; } }

/* ---------- method: numbered editorial steps, no boxes ---------- */

.method { display: grid; grid-template-columns: repeat(3, 1fr); gap: 56px; }

.method .num {
  display: block;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 46px;
  line-height: 1;
  color: var(--ink-quiet);
  margin-bottom: 20px;
}

.method h3 { margin-bottom: 12px; }
.method p { font-size: 15.5px; color: var(--ink-soft); }

@media (max-width: 860px) { .method { grid-template-columns: 1fr; gap: 40px; } }

/* ---------- see inside a guide ---------- */

.spreads { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }

.spreads img {
  width: 100%;
  border: 1px solid var(--line);
  transition: transform .3s ease, box-shadow .3s ease;
}

.spreads figure:hover img { transform: translateY(-4px); box-shadow: 0 14px 44px rgba(0,0,0,.09); }

.spreads figcaption {
  margin-top: 16px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-quiet);
}

@media (max-width: 860px) { .spreads { grid-template-columns: 1fr; gap: 34px; } }

/* ---------- pocket guide cards (phone shaped, 9:16) ---------- */

/* minmax(0, 1fr), not 1fr: a plain 1fr track floors at the item's min-content
   width, and these images are intrinsically 540px, so the grid would overflow
   the container on narrow screens. */
.pocket-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 30px; }

.pocket-cards img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  transition: transform .3s ease, box-shadow .3s ease;
}

.pocket-cards figure:hover img { transform: translateY(-4px); box-shadow: 0 14px 44px rgba(0,0,0,.09); }

.pocket-cards figcaption {
  margin-top: 14px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-quiet);
}

/* the line that tells you the four cards above are an example, not your guide */
.sample-note {
  margin-top: 30px;
  text-align: center;
  font-size: 13.5px;
  color: var(--ink-quiet);
}

.sample-cta {
  margin-top: 26px;
  display: flex;
  justify-content: center;
}

@media (max-width: 860px) { .pocket-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; } }
@media (max-width: 520px) { .pocket-cards { grid-template-columns: minmax(0, 1fr); gap: 30px; } }

@media (prefers-reduced-motion: reduce) {
  .pocket-cards img, .pocket-cards figure:hover img { transition: none; transform: none; }
}

/* ---------- offer cards ---------- */

.offer-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }

.offer {
  display: flex;
  flex-direction: column;
  background: var(--ground);
  border: 1px solid var(--line);
  padding: 38px 32px 32px;
  text-decoration: none;
  transition: border-color .25s ease, transform .25s ease;
}

.offer:hover { border-color: var(--ink); transform: translateY(-3px); }

.offer h3 { margin-bottom: 8px; }

.offer .price {
  /* the card holds a title, one paragraph and this, and the paragraphs differ
     in length by several lines, so the prices only line up across the row if
     the last item is pushed to the foot of the card */
  margin-top: auto;
  padding-top: 22px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  color: var(--ink);
}

.offer p { font-size: 15.5px; color: var(--ink-soft); }

.offer h3 + p { margin-top: 14px; }

@media (max-width: 860px) { .offer-cards { grid-template-columns: 1fr; } }


/* ---------- services page: name and price, everything else behind a click ---------- */

/* Index of every service. One row per service, carrying the name and the price
   and nothing else, and opening in place. The selling line that used to sit
   here was removed: a ladder of five is read by comparing names and numbers,
   and a paragraph on every rung turns the comparison into reading. */
.svc-index {
  display: flex;
  flex-direction: column;
  max-width: 74ch;
  margin-top: 30px;
  border-top: 1px solid var(--line);
}

.svc-row { border-bottom: 1px solid var(--line); }

/* explicit placement, not auto: the marker below is a generated grid item, and
   left to auto-placement it lands under the name instead of beside it. */
/* three tracks on one row: the name, the price, and the marker. */
.svc-row summary {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 6px 22px;
  padding: 20px 0;
  cursor: pointer;
  list-style: none;
  transition: padding-left .2s ease;
}

.svc-row summary::-webkit-details-marker { display: none; }

.svc-index .n {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  font-family: var(--serif);
  font-size: 21px;
  line-height: 1.2;
}

/* the price, right where the eye runs down the column */
.svc-index .p {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: 19px;
  text-align: right;
}

.svc-row summary::after {
  content: "+";
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  font-size: 20px;
  font-weight: 300;
  line-height: 1;
  color: var(--ink-quiet);
}

.svc-row[open] summary::after { content: "\2212"; }

.svc-row summary:hover { padding-left: 10px; }

.svc-row summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.svc-row[open] summary { padding-bottom: 10px; }

.svc-row-body { padding: 0 0 32px; max-width: 62ch; }

.svc-row-body p { color: var(--ink-soft); }

.svc-row-body ul { margin: 18px 0 0; padding-left: 20px; }

.svc-row-body li { color: var(--ink-soft); font-size: 15.5px; margin-bottom: 7px; }

/* The Full Transformation is long enough that an undivided list of seventeen
   lines reads as a wall. These label its four modules: quiet, structural, and
   deliberately not headings, since the service name above them is a span rather
   than one and a heading here would outrank it in the outline. */
.svc-row-body .svc-mod {
  margin-top: 26px;
  font-size: 12.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
}

.svc-row-body .svc-mod + p { margin-top: 6px; }

/* The currency is a qualifier, not part of the number. In the display face at
   price size it competes with the figure it belongs to, so it drops to the body
   face at caption size, which is the treatment the Color & Style page already
   uses. Both price elements are serif italic, so both have to be unset here. */
.svc-index .p small,
.offer .price small {
  font-family: var(--font);
  font-style: normal;
  font-size: 11.5px;
  letter-spacing: .09em;
  color: var(--ink-quiet);
}

/* both of these have to be scoped under .svc-row-body to beat the rule above,
   which scores 0,1,1 and would otherwise repaint them in the body grey */
.svc-row-body .svc-price {
  margin-top: 24px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  color: var(--ink);
}

/* the qualifier inside a price line. It is one sentence with the price, so it
   stays in the same paragraph and only drops in size and face. */
.svc-price-note {
  display: block;
  font-family: var(--font);
  font-style: normal;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 27ch;
}

.svc-row-body .fine { margin-top: 12px; color: var(--ink-quiet); }

/* the close: one call to action for the whole ladder, at the foot of it. The
   line above names what the button is for, the line below says what the call
   costs and why it comes first. */
.svc-close { padding: 72px 0 96px; text-align: center; }

.svc-close-line {
  font-family: var(--serif);
  font-size: clamp(21px, 2.3vw, 27px);
  line-height: 1.3;
  max-width: 24ch;
  margin: 0 auto 26px;
}

.svc-close .fine { max-width: 52ch; margin: 18px auto 0; }

.svc-group { padding: 54px 0 0; }

.svc-group h2 { margin-bottom: 6px; }

/* ---------- carousel quotes in serif ---------- */

.v3 .qc-quote {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(20px, 2.2vw, 27px);
  line-height: 1.5;
}

/* ---------- quiet credential strip ---------- */

.credentials { padding: 70px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

/* row gap opened up: the two rows of marks were reading as one block */
.credentials .logo-row { margin-top: 34px; gap: 58px 40px; }

.credentials .logo-row img { height: 32px; opacity: .5; transition: opacity .25s ease; }

.credentials .logo-row img:hover { opacity: .85; }

/* ---------- example guide dialog ---------- */

.guide-dialog {
  /* the reset zeroes every margin, which kills the centring a modal dialog
     gets from the UA stylesheet, so it is spelled out here */
  margin: auto;
  width: min(460px, calc(100vw - 40px));
  padding: 44px 40px 40px;
  border: 1px solid var(--line);
  background: var(--ground);
  color: var(--ink);
  /* fixed, not relative: a modal dialog gets position:fixed from the UA sheet,
     and relative here would anchor it to the document and send it off screen on
     a scrolled page. The close button anchors to it either way. */
  position: fixed;
}

.guide-dialog::backdrop { background: rgba(24, 24, 22, .5); }

.guide-dialog h3 { font-family: var(--serif); font-size: 27px; font-weight: 400; margin: 10px 0 12px; }

.guide-dialog .fine { margin-bottom: 26px; }

.guide-close {
  position: absolute;
  top: 14px;
  right: 16px;
  width: 34px;
  height: 34px;
  font-size: 22px;
  line-height: 1;
  color: var(--ink-quiet);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color .2s ease;
}

.guide-close:hover { color: var(--ink); }

.guide-form label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: 22px;
}

.guide-form input[type="email"] {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 13px 14px;
  font: inherit;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line);
}

.guide-form input[type="email"]:focus-visible { outline: 1px solid var(--ink); outline-offset: 1px; }

.guide-form .btn { width: 100%; }

.guide-form .btn[disabled] { opacity: .55; cursor: default; }

/* .btn sets its own display, which beats the UA rule for [hidden], so the
   button would still show after the guide has gone out */
.guide-form .btn[hidden] { display: none; }

/* holds its line from the first render, so sending does not jump the dialog */
.guide-status {
  min-height: 20px;
  margin-top: 16px;
  font-size: 14px;
  color: var(--ink-soft);
}

.guide-status.is-error { color: #8c3b2f; }

/* ---------- footer ---------- */

.v3 .site-footer .footer-cols > div > p:not(.footer-h) { color: var(--ink-soft); margin-bottom: 16px; }

/* ---------- mobile sticky CTA ---------- */

.mobile-cta {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  background: #000;
  color: #fff;
  text-align: center;
  padding: 16px;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
}

@media (max-width: 860px) {
  .mobile-cta { display: block; }
  /* The bar is fixed, so something has to reserve its height or it sits on top
     of the last thing in the footer. It measures 53px, and 52px of padding left
     the copyright line under it by a hair.
     Selector is .v3 rather than body.v3 on purpose: the bundled preview wraps
     the pages in a div.v3 instead of putting the class on body, so a body-only
     rule reserved nothing there and the copyright was fully covered. */
  .v3 { padding-bottom: 68px; }
  /* keep the headline and the booking CTA close to the top of the first screen */
  .v3 .hero-img { max-height: 46vh; object-position: center 22%; }
  .v3 .hero-intro { padding-top: 34px; padding-bottom: 26px; }
  .v3 .credline { padding: 32px 0; }
}

/* ---------- header: wordmark left, navigation and CTA right ----------
   The base sheet stacks a centred wordmark over a centred nav and floats the
   CTA absolutely. V3 puts all three on one line: name at the left edge, nav
   and a smaller button at the right. */

.v3 .site-header .wrap {
  display: flex;
  align-items: center;
  gap: 30px;
  grid-template-columns: none;
  grid-template-areas: none;
  row-gap: 0;
}

.v3 .wordmark {
  grid-area: auto;
  grid-column: auto;
  justify-self: start;
  font-size: 19px;
  letter-spacing: 0.24em;
}

.v3 .site-nav {
  grid-area: auto;
  grid-column: auto;
  justify-self: end;
  margin-left: auto;
  align-items: center;
  gap: 30px;
}

.v3 .header-cta {
  position: static;
  padding: 11px 20px;
  font-size: 10.5px;
  letter-spacing: 0.14em;
}

/* Services live inside the My Services tab rather than as separate nav items. */
.v3 .nav-item { position: relative; }

.v3 .nav-drop {
  position: absolute;
  top: 100%;
  left: -20px;
  padding: 18px 0 10px;
  min-width: 262px;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  border: 1px solid var(--line);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.07);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s;
  z-index: 60;
}

/* The 18px top padding above doubles as the bridge between the tab and the
   panel, so the pointer can travel down without the panel closing. */
.v3 .nav-item:hover .nav-drop,
.v3 .nav-item:focus-within .nav-drop {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.v3 .nav-drop a {
  padding: 9px 22px;
  font-size: 13.5px;
  white-space: nowrap;
}

.v3 .nav-drop a::after { content: none; }
.v3 .nav-drop a:hover { background: var(--ground-alt); }

.v3 .nav-drop .drop-all {
  margin-top: 8px;
  padding-top: 13px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* the portal link is for the three people who already pay her, so it sits in
   the nav at a whisper: smaller, quieter, and never competing with the booking
   button beside it. */
.v3 .nav-portal {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink-quiet);
}

.v3 .nav-portal:hover { color: var(--ink); }

.v3 .nav-portal::after { bottom: -4px; background: var(--ink-quiet); }

.v3 .nav-ig { display: inline-flex; align-items: center; color: var(--ink); }
.v3 .nav-ig::after { content: none; }
.v3 .nav-ig svg { width: 18px; height: 18px; }
.v3 .nav-ig:hover { color: var(--ink-quiet); }

.v3 .ig-follow { text-decoration: none; }
.v3 .ig-follow:hover { color: var(--ink); }


@media (max-width: 860px) {
  /* The button hides here (the sticky mobile CTA takes over) and the panel
     with it: My Services then goes straight to the index page. */
  .v3 .site-header .wrap { flex-direction: column; gap: 12px; }
  .v3 .site-nav { margin-left: 0; justify-self: center; }
  .v3 .nav-drop { display: none; }
}

/* The brand strip label sat in the quiet grey and read as disabled text next to
   the logos, so it takes the page's ink like the rest of the copy. */
.v3 .credentials .micro-label { color: var(--ink); }

/* The example guide goes out on request, so the button carries a line of
   explanation rather than opening a file. */
.v3 .sample-cta .fine { display: block; margin-top: 14px; }

/* ---------- contact form ---------- */

.v3 .contact-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px 24px;
  max-width: 720px;
  margin-top: 40px;
}

.v3 .contact-form label {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-quiet);
}

.v3 .contact-form label.full { grid-column: 1 / -1; }

.v3 .contact-form input,
.v3 .contact-form select,
.v3 .contact-form textarea {
  font-family: var(--font);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 13px 14px;
  transition: border-color .2s ease;
}

.v3 .contact-form textarea { resize: vertical; }

.v3 .contact-form input:focus,
.v3 .contact-form select:focus,
.v3 .contact-form textarea:focus {
  outline: none;
  border-color: var(--ink);
}

.v3 .contact-form button { grid-column: 1 / -1; justify-self: start; }

@media (max-width: 620px) {
  .v3 .contact-form { grid-template-columns: 1fr; }
}

/* The brand marks read at full ink rather than as grey ghosts. The files are
   transparent PNGs, so brightness(0) renders each silhouette in solid black. */
.v3 .logo-row img,
.v3 .credentials .logo-row img { opacity: 1; filter: brightness(0); }
.v3 .credentials .logo-row img:hover { opacity: 1; }

/* ---------- services carousel ----------
   Every program lives on the homepage now, so the three-card grid becomes a
   track that scrolls. Scroll snapping keeps a card edge against the left
   margin whether the arrows or a trackpad did the scrolling. */

.offer-slider { margin-top: 52px; }

.offer-track {
  display: flex;
  gap: 28px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
}

.offer-track::-webkit-scrollbar { display: none; }

.offer-track .offer {
  flex: 0 0 calc((100% - 56px) / 3);
  scroll-snap-align: start;
}

/* the lift on hover would clip against the track's overflow */
.offer-track .offer:hover { transform: none; }

.slider-nav {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 26px;
}

.slider-nav button {
  width: 42px;
  height: 42px;
  font-size: 15px;
  color: var(--ink);
  background: none;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: border-color .25s ease, color .25s ease, opacity .25s ease;
}

.slider-nav button:hover:not(:disabled) { border-color: var(--ink); }
.slider-nav button:disabled { opacity: .3; cursor: default; }
.slider-nav button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

@media (max-width: 980px) {
  .offer-track .offer { flex-basis: calc((100% - 28px) / 2); }
}

@media (max-width: 680px) {
  .offer-track .offer { flex-basis: 84%; }
}

/* ---------- client portal front door ---------- */

/* one short column, centred, with nothing else on the page: whoever lands here
   has been sent a link and needs one field, not a sales page */
.portal-door { padding: 96px 0 120px; }

.portal-door .wrap { max-width: 470px; text-align: center; }

/* the form reads left, the page reads centred */
.portal-form { text-align: left; }

/* two lines at most: a welcome that breaks into three reads as a headline
   with nowhere to go */
.portal-door h1 { font-size: clamp(28px, 2.9vw, 36px); max-width: 12ch; margin: 0 auto; }

.portal-door .lede { margin-top: 16px; color: var(--ink-soft); font-size: 16.5px; }

.portal-form { margin-top: 38px; }

.portal-form label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: 10px;
}

/* two fields now, so the labels carry the spacing and the text sits where a
   credential belongs, at the left edge where it can be read back */
.portal-form label + input { margin-bottom: 18px; }

.portal-form input {
  width: 100%;
  padding: 13px 14px;
  font-family: var(--font);
  font-size: 16px;
  font-weight: 300;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: 0;
  text-align: left;
}

.portal-form input:focus { outline: none; border-color: var(--ink); }

.portal-form .btn { width: 100%; margin-top: 6px; }

.portal-form .fine { margin-top: 16px; }

.portal-help { margin-top: 34px; }

.portal-help a { text-decoration: underline; text-underline-offset: 3px; }

/* The portal keeps the site's footer so the space is plainly part of
   lissabarquero.com, but not the half of it that sells: no newsletter, no
   Instagram, no marketing links. A client who has arrived does not need pitching
   to, and the one thing she might want is the way back. */
.portal-footer { padding: 46px 0 40px; text-align: center; }

.portal-footer p { color: var(--ink-soft); }

.portal-footer a { text-decoration: underline; text-underline-offset: 3px; }

.portal-footer .legal { margin-top: 14px; }

/* the second price on a card. Her clients pay less, and that should read as
   recognition rather than as a footnote, so it sits on its own line in the ink
   the body uses rather than in the caption grey. */
.offer .price-note {
  display: block;
  margin-top: 8px;
  font-family: var(--font);
  font-style: normal;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ---------- contact: the calendar and what follows it ---------- */

/* The booking section carried the page's standard 90px foot, the Instagram strip
   carried another 90 on its head, and the embed reserves its full height even
   when the widget inside is shorter. Between the calendar and the photographs
   that was most of a screen of nothing. */
#book { padding-bottom: 24px; }

#book + section { padding-top: 40px; }

.calendly-embed { margin-top: 28px; }

/* ---------- services and logos on a phone ----------
   These sit at the end of the sheet on purpose. Media queries add no
   specificity, so a mobile rule written above the desktop rule it means to
   override loses to it, silently, which is exactly what happened here: the
   three column row stayed three columns on a phone and squeezed the text into
   a forty percent gutter. */

@media (max-width: 620px) {
  /* two lines: the name, then the price with the marker that opens the rest.
     The price keeps a line of its own rather than sitting beside the name,
     because two of the five carry a note under them that needs the width. */
  .svc-row summary {
    grid-template-columns: 1fr auto;
    gap: 8px 16px;
    padding: 22px 0;
  }

  .svc-index .n { grid-column: 1 / -1; grid-row: 1; }

  .svc-index .p {
    grid-column: 1;
    grid-row: 2;
    align-self: end;
    text-align: left;
    margin-top: 6px;
  }

  .svc-price-note { max-width: none; }

  .svc-row summary::after {
    grid-column: 2;
    grid-row: 2;
    align-self: end;
    justify-self: end;
  }

  /* the hover indent is a pointer affordance and only gets in the way here */
  .svc-row summary:hover { padding-left: 0; }
}

/* Ten brand marks in three columns leave one alone on the last row, hard against
   the left margin, which reads as a mistake rather than as a tenth logo. When
   the last item starts a row of its own, it takes the middle column. */
@media (max-width: 780px) {
  .logo-row img:last-child:nth-child(3n + 1) { grid-column: 2; }
}

/* Event banner: a thin link bar above the header, for one event at a time
   (first use: Maison Segunda, 2026-10-10). Markup sits at the top of each page;
   remove the markup after the event and this rule can stay. */
.v3 .event-banner {
  display: block;
  background: #000;
  color: #fff;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 10px 16px;
  line-height: 1.5;
  text-decoration: none;
}
.v3 .event-banner span { text-decoration: underline; text-underline-offset: 3px; }
.v3 .event-banner:hover span { text-decoration: none; }
