/* noir.css — self-contained Noir design system for the public homepage.
   Loaded ONLY by layouts/noir.php. Does NOT load tokens.css/app.css, so it
   cannot affect the admin or other public pages. Mobile-first.
   Fonts + images are self-hosted so the strict CSP (self only) is satisfied. */

@font-face{
  font-family:"Fraunces";font-style:normal;font-weight:300 600;font-display:swap;
  src:url("/assets/fonts/fraunces-var-latin.woff2") format("woff2");
}

:root{
  --bg:#0a0907;--bg2:#12100d;--bg3:#0f0d0b;--panel:#191410;--panel2:#1f1913;
  --cream:#f4ede1;--muted:#a99d8a;--muted2:#847a6b;
  --gold:#c9a24b;--gold2:#e8cd82;--green:#7ec98a;--amber:#d9a441;
  --line:rgba(201,162,75,.22);--line2:rgba(244,237,225,.08);
  --shadow:0 30px 70px -30px rgba(0,0,0,.8);
  --on-gold:#171208;                 /* text that sits on a gold fill */
  /* Text burned over a PHOTOGRAPH. Light in BOTH themes: the image beneath is
     dark by design in either theme, so this must not follow --cream, which
     flips to near-black in light mode and made every caption unreadable. */
  --on-media:#f6f1e8;
  --on-media-dim:#c4baa9;
  --on-media-accent:#e8cd82;
  --bar:rgba(10,9,7,.94);            /* mobile action-bar ground */
  --hdr:var(--bg);                   /* site header ground */
  --ag-veil:rgba(10,9,7,.22);        /* age-gate veil — keep the site visible */
  /* Spacing scale — power of two off a 4px base (×1,2,4,8,16,32).
     Every margin / padding / gap / dimension uses one of these steps. */
  --s1:4px;   /* 1  */
  --s2:8px;   /* 2  */
  --s3:16px;  /* 4  */
  --s4:32px;  /* 8  */
  --s5:64px;  /* 16 */
  --s6:128px; /* 32 */
  --s0:2px;   /* hairline half-step */
}

/* ── Light theme ──────────────────────────────────────────────────────────
   Sand, not white: the brand is warm and a pure-white ground would read as a
   different product. Only the tokens change — every component keeps its rules.
   Overlays burned onto photographs (.badge, .cty .ov, hero gradient) stay dark
   on purpose: they exist for legibility over an image, not for the page ground.
   Set by [data-theme] on <html>; see the switch in layouts/noir.php. */
:root[data-theme="light"]{
  --bg:#e3ded3;
  --bg2:#dbd2c4;
  --bg3:#e7e2da;
  --panel:#ddd4c6;
  --panel2:#d3cab9;
  --cream:#221c14;                   /* primary text, now dark on sand */
  --muted:#5c5346;
  --muted2:#645b4d;
  --gold:#765818;                     /* lightest gold that keeps 4.5:1 as small text on --panel */
  --gold2:#775516;
  --green:#2f6b3c;
  --amber:#8a5f1e;
  --line:rgba(154,113,31,.34);
  --line2:rgba(34,28,20,.14);
  --shadow:0 24px 60px -34px rgba(70,52,20,.34);
  --on-gold:#fff8ec;                 /* light text on the darker gold fill */
  --bar:rgba(227,222,211,.94);
  --hdr:#d3cab9;                     /* header a step darker than the #e3ded3 body, so the menu bar reads as its own band */
  --ag-veil:rgba(227,222,211,.3);
}
/* Photos were graded for a dark ground; lift them on sand. The service and city
   tiles keep a scrim gradient over them, so their captions stay legible. */
:root[data-theme="light"] nav.main{background:var(--hdr)}
:root[data-theme="light"] .brand-logo{filter:brightness(0.62) contrast(1.2) saturate(1.0) drop-shadow(0 1px 0 rgba(255,250,240,.45))}   /* the logo is pale gold ink drawn for a dark ground (~1.6:1 on the sand header); deepen it to the site gold (~4.0:1) with a light hairline edge so small strokes stay crisp */
:root[data-theme="light"] .card .ph img{filter:grayscale(.14) contrast(1.02) brightness(1)}
:root[data-theme="light"] .hero-media img{filter:grayscale(.06) contrast(1.02) brightness(.96)}
:root[data-theme="light"] .svc img{filter:grayscale(.06) brightness(.94)}
:root[data-theme="light"] .svc:hover img{filter:grayscale(0) brightness(1)}
:root[data-theme="light"] .cty img{filter:grayscale(.1) brightness(.9)}
:root[data-theme="light"] .cty:hover img{filter:grayscale(0) brightness(.98)}
/* Keep the picture bright and buy legibility locally instead of globally: the
   scrim starts far down the tile, and the text carries its own shadow. A big
   dark gradient was making the tile read as dark even at 0.94 brightness. */
:root[data-theme="light"] .svc .ov{background:linear-gradient(180deg,transparent 55%,rgba(10,9,7,.5) 76%,rgba(10,9,7,.88))}
:root[data-theme="light"] .cty .ov{background:radial-gradient(ellipse at center,rgba(10,9,7,.42),rgba(10,9,7,.22) 60%,transparent)}
:root[data-theme="light"] .svc h3,:root[data-theme="light"] .svc p,
:root[data-theme="light"] .cty h3,:root[data-theme="light"] .cty p,
:root[data-theme="light"] .cty-c{text-shadow:0 1px 3px rgba(10,9,7,.85),0 2px 14px rgba(10,9,7,.6)}
:root[data-theme="light"] .fbig img,:root[data-theme="light"] .fsm img{filter:grayscale(.1) brightness(.96)}

*{margin:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--cream);font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;line-height:1.5}
img{display:block;max-width:100%}
a{color:inherit}
.serif{font-family:Fraunces,Georgia,serif;font-optical-sizing:auto}
/* utility classes (replace inline styles — strict CSP forbids style attrs) */
.badge .d.lim{background:var(--amber)}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.foot-bot .discreet{display:flex;gap:var(--s3);align-items:center}
.board-empty{color:var(--muted);padding:var(--s4) 0}
/* Board filter: pill row by default, one dropdown once the row would wrap.
   The swap point is measured in JS, not a fixed breakpoint, so it holds for
   any locale's label lengths. `.board-select` stays hidden without JS. */
.board-filter.is-compact .filters{display:none}
.board-select{width:100%;min-height:44px;margin-bottom:var(--s4);
  background-color:rgba(255,255,255,.04);border:1px solid var(--line2);border-radius:999px;
  color:var(--cream);font-family:inherit;font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  font-weight:600;padding:9px 44px 9px 20px;cursor:pointer;
  -webkit-appearance:none;appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23c9a24b' d='M6 8 0 0h12z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 20px center}
.board-select:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.board-select option{background:var(--panel);color:var(--cream);text-transform:none;letter-spacing:normal}

/* Board grid while an AJAX filter is in flight — dim, and don't take clicks. */
[data-board-grid].is-loading{opacity:.4;pointer-events:none;transition:opacity .15s ease}
.eyebrow{font-size:11px;letter-spacing:.34em;text-transform:uppercase;color:var(--gold);font-weight:500}
.wrap{max-width:1300px;margin:0 auto;padding-inline:var(--s4)}
.sec{padding-block:var(--s5)}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s3);border-bottom:1px solid var(--line);padding-bottom:var(--s3);margin-bottom:var(--s4)}
.sec-head h2{font-family:Fraunces,serif;font-size:clamp(30px,3.4vw,44px);font-weight:400;color:var(--cream);letter-spacing:-.01em}
.sec-head p{color:var(--muted);font-size:14px;max-width:34ch}
.btn{display:inline-flex;align-items:center;gap:var(--s2);padding:var(--s3) var(--s4);font-size:12px;letter-spacing:.16em;text-transform:uppercase;text-decoration:none;font-weight:600;border:1px solid transparent;transition:.3s;cursor:pointer}
.btn-solid{background:var(--gold);color:var(--on-gold)}.btn-solid:hover{background:var(--gold2)}
.btn-sec{background:var(--panel);color:var(--gold2);border-color:var(--line)}.btn-sec:hover{background:var(--panel2);border-color:var(--gold)}
.pulse{width:8px;height:8px;border-radius:50%;background:var(--green);flex:none;animation:p 2s infinite}
@keyframes p{0%{box-shadow:0 0 0 0 rgba(126,201,138,.5)}70%{box-shadow:0 0 0 9px rgba(126,201,138,0)}100%{box-shadow:0 0 0 0 rgba(126,201,138,0)}}

/* utility bar */
.util{background:var(--bg3);border-bottom:1px solid var(--line2);font-size:11px;letter-spacing:.1em;color:var(--muted2);text-transform:uppercase}
.util .wrap{display:flex;align-items:center;justify-content:space-between;padding-top:var(--s2);padding-bottom:var(--s2)}
.util .l{display:flex;gap:var(--s3)}
.util .r{display:flex;gap:var(--s3);align-items:center}
.util a{text-decoration:none;color:var(--muted);transition:.2s}.util a:hover{color:var(--gold2)}
.util .age{color:var(--gold);border:1px solid var(--line);padding:var(--s0) var(--s2);letter-spacing:.14em}

/* header — sticky nav that stays fixed on scroll. Background is fully OPAQUE so
   page content scrolling underneath never shows through / over the menu bar. */
/* body>header scopes these to the SITE nav only — the article title block on
   landing pages is also a <header> (.art-hero) and must NOT inherit sticky/bg. */
body>header{position:sticky;top:0;z-index:60;background:var(--hdr);border-bottom:1px solid var(--line)}
body>header .wrap{display:flex;align-items:center;justify-content:space-between;padding-top:var(--s3);padding-bottom:var(--s3)}
.brand{font-family:Fraunces,serif;font-size:25px;letter-spacing:.02em;color:var(--gold2);font-weight:500;text-decoration:none}
.brand.has-logo{display:inline-flex;align-items:center;line-height:0}
.brand-logo{display:block;height:64px;width:auto;max-width:min(60vw,340px);object-fit:contain}
@media(max-width:640px){.brand-logo{height:44px;max-width:48vw}.hgroup .book{display:none}}
nav.main{display:flex;gap:var(--s4)}
nav.main a{color:var(--muted);text-decoration:none;font-size:14.5px;letter-spacing:.13em;text-transform:uppercase;transition:.3s}
nav.main a:hover{color:var(--cream)}
.hgroup{display:flex;align-items:center;gap:var(--s3)}
.avnow{display:flex;align-items:center;gap:var(--s2);font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.book{font-size:12px;letter-spacing:.15em;text-transform:uppercase;color:var(--on-gold);background:var(--gold);text-decoration:none;padding:var(--s2) var(--s3);font-weight:600;transition:.3s}
.book:hover{background:var(--gold2)}

/* hero */
.hero{position:relative;min-height:82vh;display:grid;grid-template-columns:1fr 1fr;overflow:hidden}
.hero-media{position:absolute;inset:0;left:41%}
.hero-media img{width:100%;height:100%;object-fit:cover;object-position:50% 20%;filter:grayscale(.14) contrast(1.05) brightness(.84)}
.hero-media:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--bg) 2%,rgba(10,9,7,.28) 40%,rgba(10,9,7,.5) 100%)}
.hero-copy{position:relative;z-index:3;align-self:center;padding:var(--s5) 0 var(--s5) var(--s4);max-width:600px}
.hero h1{font-size:clamp(46px,6vw,94px);line-height:.96;font-weight:330;letter-spacing:-.02em;margin:var(--s3) 0 var(--s3);color:var(--cream)}
.hero h1 em{font-style:italic;color:var(--gold2)}
.rule{width:60px;height:1px;background:var(--gold);margin:var(--s1) 0 var(--s3)}
.lede{color:var(--muted);font-size:18px;line-height:1.6;max-width:40ch;margin-bottom:var(--s4)}
.cta{display:flex;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s4)}
.hero-copy .cta{justify-content:flex-end}
.trust{display:flex;justify-content:space-between;gap:var(--s3);border-top:1px solid var(--line);padding-top:var(--s3)}
.trust .k{font-family:Fraunces,serif;font-size:28px;color:var(--gold2);line-height:1}
.trust .v{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-top:var(--s1)}

/* trust strip */
.tstrip{background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.tstrip .wrap{display:grid;grid-template-columns:repeat(4,1fr);gap:0}
.tstrip .t{display:flex;align-items:center;gap:var(--s3);padding:var(--s4) var(--s3);border-right:1px solid var(--line2)}
.tstrip .t:last-child{border-right:0}
.tstrip svg{width:26px;height:26px;stroke:var(--gold);flex:none}
.tstrip .th{font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--cream)}
.tstrip .ts{font-size:11px;color:var(--muted);letter-spacing:.03em;margin-top:var(--s0)}

/* board */
.filters{display:flex;gap:8px;margin-bottom:var(--s4);flex-wrap:wrap}
/* Pill — ONE shape, shared by the board filter here and the profile About tabs
   (.pf-tab). Hover = gold outline, selected = gold fill, so "hovered" never
   reads as "selected". Keep the two selectors together when editing. */
.chip,.pf-tab{appearance:none;display:inline-block;background:rgba(255,255,255,.04);border:1px solid var(--line2);border-radius:999px;color:var(--cream);font-family:inherit;font-size:12px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;padding:9px 20px;text-decoration:none;cursor:pointer;transition:.18s}
.chip:hover,.pf-tab:hover{border-color:var(--gold);color:var(--gold);background:rgba(255,255,255,.04)}
.chip.on,.pf-tab.is-active{background:var(--gold);border-color:var(--gold);color:var(--on-gold)}
.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s3)}
.card{position:relative;background:var(--panel);border:1px solid var(--line2);transition:.3s}
.card:hover{border-color:var(--line);box-shadow:var(--shadow)}
/* Padding cards: real roster, but OUTSIDE the visitor's filter. Marked with a
   single accent line on the caption block — not the card border, and no label.
   The photo treatment stays identical to a matching card. */
.card.is-off .cap{border-left:3px solid var(--muted2);padding-left:10px}
.card.is-off:hover .cap{border-left-color:var(--on-media-accent)}
.card .ph{position:relative;aspect-ratio:4/5;overflow:hidden}
.card .ph img{width:100%;height:100%;object-fit:cover;filter:grayscale(.26) contrast(1.03) brightness(.92);transition:.55s}
.card:hover .ph img{filter:grayscale(0) contrast(1) brightness(1);transform:scale(1.04)}
.card .ph:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 42%,rgba(25,20,16,.9))}
.badge{position:absolute;top:12px;left:12px;display:flex;align-items:center;gap:var(--s1);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--on-media);z-index:2;background:rgba(10,9,7,.55);backdrop-filter:blur(4px);padding:var(--s1) var(--s2);border:1px solid var(--line)}
.badge .d{width:7px;height:7px;border-radius:50%;background:var(--green)}
.veri{position:absolute;top:12px;right:12px;z-index:2;color:var(--on-media-accent);font-size:10px;background:rgba(10,9,7,.55);backdrop-filter:blur(4px);padding:var(--s1) var(--s2);border:1px solid var(--line);letter-spacing:.08em;text-transform:uppercase}
/* Superseded: .cap is position:static below the photo at every breakpoint
   (see the mobile-first block further down). Kept only so the older
   .grid .cap offsets still parse. It is NOT a photo overlay. */
.cap{position:absolute;left:16px;right:16px;bottom:14px;z-index:2}
.cap .n{font-family:Fraunces,serif;font-size:23px;color:var(--cream);display:flex;align-items:baseline;gap:var(--s2)}
.cap .n small{font-family:Archivo;font-size:13px;color:var(--muted);font-weight:400}
.cap .meta{display:flex;gap:var(--s2);margin:var(--s1) 0 var(--s2);font-size:11px;letter-spacing:.03em;color:var(--muted);flex-wrap:wrap}
.cap .meta b{color:var(--cream);font-weight:500}
.cfoot{display:flex;align-items:center;justify-content:space-between}
.cfoot .rate{font-size:11px;letter-spacing:.04em;color:var(--muted)}
.cfoot .rate b{font-family:Fraunces,serif;font-size:19px;color:var(--gold2);letter-spacing:0}
.cfoot .bk{font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--on-gold);background:var(--gold);padding:var(--s2) var(--s3);text-decoration:none;font-weight:600;transition:.25s}
.cfoot .bk:hover{background:var(--gold2)}
.more{text-align:center;margin-top:var(--s4)}

/* why */
.why{background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.why-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.wc{padding:var(--s4) var(--s4);border:1px solid var(--line2);background:var(--bg);transition:.3s}
.wc:hover{border-color:var(--line)}
.wc svg{width:30px;height:30px;stroke:var(--gold);margin-bottom:var(--s3)}
.wc h3{font-family:Fraunces,serif;font-weight:400;font-size:24px;color:var(--cream);margin-bottom:var(--s2)}
.wc p{color:var(--muted);font-size:14px;line-height:1.65}

/* services */
.serv-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.svc{position:relative;overflow:hidden;aspect-ratio:3/2;border:1px solid var(--line2);display:block;text-decoration:none;color:inherit}
.svc img{width:100%;height:100%;object-fit:cover;filter:grayscale(.3) brightness(.6);transition:.5s}
.svc:hover img{filter:grayscale(0) brightness(.72);transform:scale(1.04)}
.svc .ov{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:var(--s3);background:linear-gradient(180deg,transparent 30%,rgba(10,9,7,.85))}
.svc h3{font-family:Fraunces,serif;font-size:24px;color:var(--on-media)}
.svc p{font-size:12px;color:var(--on-media-dim);margin-top:var(--s1);letter-spacing:.02em}
.svc .from{position:absolute;top:16px;right:16px;font-size:11px;letter-spacing:.08em;color:var(--on-media-accent);background:rgba(10,9,7,.55);backdrop-filter:blur(4px);padding:var(--s1) var(--s2);border:1px solid var(--line)}

/* steps */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.stp{padding:var(--s4) var(--s4);border:1px solid var(--line);background:linear-gradient(180deg,var(--bg2),var(--bg));position:relative;transition:.3s}
.stp:hover{border-color:var(--gold)}
.stp .no{font-family:Fraunces,serif;font-size:15px;color:var(--gold);letter-spacing:.1em}
.stp h3{font-family:Fraunces,serif;font-weight:400;font-size:26px;margin:var(--s3) 0 var(--s2);color:var(--cream)}
.stp p{color:var(--muted);font-size:14px;line-height:1.65}

/* rates */
.rate-grid{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line)}
.rate-grid .r{padding:var(--s4) var(--s4);border-right:1px solid var(--line)}
.rate-grid .r:last-child{border-right:0}
.rate-grid .r.feat{background:var(--panel)}
.rate-grid .rl{font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted)}
.rate-grid .rp{font-family:Fraunces,serif;font-size:38px;color:var(--gold2);margin-top:var(--s2);line-height:1}
.rate-grid .rs{font-size:12px;color:var(--muted);margin-top:var(--s2)}
.rate-note{font-size:12px;color:var(--muted2);margin-top:var(--s3);letter-spacing:.03em}

/* featured */
.feat-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:var(--s3)}
.fbig{position:relative;overflow:hidden;border:1px solid var(--line2)}
.fbig img{width:100%;height:100%;object-fit:cover;min-height:440px;filter:grayscale(.2) contrast(1.03) brightness(.9);transition:.5s}
.fbig:hover img{filter:grayscale(0);transform:scale(1.03)}
.fbig .ov,.fsm .ov{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:var(--s3);background:linear-gradient(180deg,transparent 45%,rgba(10,9,7,.88))}
.fbig .tag,.fsm .tag{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--on-media-accent);margin-bottom:var(--s2)}
.fbig .n,.fsm .n{font-family:Fraunces,serif;font-size:26px;color:var(--on-media)}
.fbig .m,.fsm .m{font-size:12px;color:var(--on-media-dim);margin-top:var(--s1)}
.fcol{display:grid;grid-template-rows:1fr 1fr;gap:var(--s3)}
.fsm{position:relative;overflow:hidden;border:1px solid var(--line2)}
.fsm img{width:100%;height:100%;object-fit:cover;min-height:210px;filter:grayscale(.2) brightness(.9);transition:.5s}
.fsm:hover img{filter:grayscale(0);transform:scale(1.03)}

/* cities */
.cities{background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.city-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.cty{position:relative;overflow:hidden;aspect-ratio:4/3;border:1px solid var(--line2)}
.cty img{width:100%;height:100%;object-fit:cover;filter:grayscale(.5) brightness(.5);transition:.5s}
.cty:hover img{filter:grayscale(.15) brightness(.62);transform:scale(1.04)}
.cty .ov{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;background:linear-gradient(180deg,rgba(10,9,7,.2),rgba(10,9,7,.62))}
/* Fluid, not a breakpoint override: at 2-up on a phone the tile is ~164px and
   "Copenhagen" overflowed at the fixed 30px. clamp() scales with the viewport
   and caps at the original 30px, so there is no mobile rule to leak upward. */
.cty h3{font-family:Fraunces,serif;font-size:clamp(17px,4.4vw,30px);color:var(--on-media)}
.cty p{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--on-media-accent);margin-top:var(--s1)}

/* reviews */
.rev-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.rev{padding:var(--s4) var(--s4);border:1px solid var(--line2);background:var(--bg2)}
.stars{color:var(--gold);letter-spacing:3px;font-size:14px;margin-bottom:var(--s3)}
.rev p{font-family:Fraunces,serif;font-style:italic;font-weight:300;font-size:18px;line-height:1.5;color:var(--cream)}
.rev .by{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-top:var(--s3)}

/* faq */
.faq-wrap{max-width:820px}
details{border-bottom:1px solid var(--line2);padding:var(--s3) 0}
details summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;font-family:Fraunces,serif;font-size:20px;color:var(--cream)}
details summary::-webkit-details-marker{display:none}
details summary .ic{color:var(--gold);font-size:22px;transition:.3s;flex:none;margin-left:var(--s3)}
details[open] summary .ic{transform:rotate(45deg)}
details p{color:var(--muted);font-size:14px;line-height:1.7;margin-top:var(--s3);max-width:70ch}

/* join */
.join{position:relative;overflow:hidden;border:1px solid var(--line);background:var(--bg2)}
.join-in{display:grid;grid-template-columns:1.3fr 1fr;gap:0}
.join-copy{padding:var(--s5) var(--s4)}
.join-copy h2{font-family:Fraunces,serif;font-size:clamp(28px,3vw,40px);font-weight:400;color:var(--cream);margin:var(--s3) 0 var(--s3)}
.join-copy p{color:var(--muted);font-size:15px;line-height:1.7;max-width:44ch;margin-bottom:var(--s4)}
.join-img{position:relative}
.join-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:grayscale(.3) brightness(.8)}
.join-img:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--bg2),transparent 60%)}

/* contact / booking */
.contact{background:var(--bg2);border-top:1px solid var(--line)}
.contact-in{display:grid;grid-template-columns:1fr 1.1fr;gap:var(--s5);align-items:start}
.contact h2{font-family:Fraunces,serif;font-size:clamp(30px,3.4vw,44px);font-weight:400;color:var(--cream);margin:var(--s3) 0 var(--s3);letter-spacing:-.01em}
.contact .lede{margin-bottom:var(--s4)}
.recep{display:flex;flex-direction:column;gap:var(--s3)}
.recep .row{display:flex;align-items:center;gap:var(--s3)}
.recep svg{width:22px;height:22px;stroke:var(--gold);flex:none}
.recep .rk{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.recep .rv{font-family:Fraunces,serif;font-size:20px;color:var(--cream)}
.form{background:var(--bg);border:1px solid var(--line);padding:var(--s4)}
.form .fr{margin-bottom:var(--s3)}
.form label{display:block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:var(--s2)}
.form input,.form select,.form textarea{width:100%;background:var(--panel);border:1px solid var(--line2);color:var(--cream);padding:var(--s3) var(--s3);font-family:inherit;font-size:14px;transition:.2s}
.form input:focus,.form select:focus,.form textarea:focus{outline:none;border-color:var(--gold)}
.form .two{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3)}
.form textarea{resize:vertical;min-height:84px}
.form .btn{width:100%;justify-content:center;margin-top:var(--s1)}
.form .fine{font-size:11px;color:var(--muted2);margin-top:var(--s3);line-height:1.6}

/* footer */
footer{background:var(--bg3);border-top:1px solid var(--line)}
.foot-top{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:var(--s4);padding-block:var(--s5) var(--s4)}
.foot-brand .brand{font-size:24px}
.foot-brand p{color:var(--muted);font-size:13px;line-height:1.7;margin-top:var(--s3);max-width:34ch}
.foot-col h4{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold);margin-bottom:var(--s3)}
.foot-col a{display:block;color:var(--muted);text-decoration:none;font-size:13px;margin-bottom:var(--s2);transition:.2s}
.foot-col a:hover{color:var(--cream)}
.foot-bot{border-top:1px solid var(--line2);padding:var(--s3) 0;display:flex;align-items:center;justify-content:space-between;color:var(--muted2);font-size:12px;letter-spacing:.06em;flex-wrap:wrap;gap:var(--s2)}
.foot-bot .age{color:var(--gold);border:1px solid var(--line);padding:var(--s0) var(--s2);letter-spacing:.12em}

/* ============================================================
   MOBILE-FIRST  —  base rules below target the phone.
   min-width breakpoints below progressively enhance upward.
   ============================================================ */
.wrap{padding-inline:var(--s3)}
.sec{padding-block:var(--s4)}
.sec-head{flex-direction:column;align-items:flex-start;gap:var(--s2);margin-bottom:var(--s4)}
.sec-head p{max-width:none}
/* hero stacks: image on top, copy beneath */
.hero{display:block;min-height:0}
/* One source of truth for the stacked image height so the CTA that overlays
   its bottom-right corner can never drift out of step with it. */
.hero{--hero-media-h:max(52vh,320px)}
.hero-media{position:relative;left:0;height:var(--hero-media-h);min-height:0}
/* "See who's available" sits ON the hero image, bottom-right. Anchored to the
   image's bottom edge and lifted by its own height (translateY(-100%)), so no
   button-height constant to keep in sync. */
.hero-copy .cta{position:absolute;top:var(--hero-media-h);right:var(--s3);
  transform:translateY(calc(-100% - 14px));margin:0;z-index:4}
.hero-media:after{background:linear-gradient(0deg,var(--bg) 1%,rgba(10,9,7,.12) 58%,transparent)}
/* static on mobile so the CTA below anchors to .hero (the image's box) and not
   to .hero-copy, which begins BELOW the image. z-index is moot here — stacked
   layout, nothing overlaps. */
.hero-copy{position:static;padding:var(--s4) var(--s3) var(--s4);max-width:none}
.hero h1{font-size:clamp(38px,9vw,62px)}
.trust{flex-wrap:nowrap;gap:var(--s2)}
@media(max-width:559px){.trust{gap:var(--s1)}.trust .k{font-size:19px}.trust .v{font-size:9px;letter-spacing:.04em;white-space:nowrap}}
/* toggle-menu */
/* Theme switch — same 42px chrome button as the mobile menu toggle. Only the
   icon for the CURRENT theme is shown: moon while dark (tap for light), sun
   while light (tap for dark). */
/* Two controls, one per breakpoint: the header button on desktop, a row inside
   the hamburger on mobile. Both carry data-theme-toggle; the handler is
   delegated so neither can end up unbound. */
.themetoggle.themetoggle--desk{display:none}
@media (min-width:900px){.themetoggle.themetoggle--desk{display:inline-flex}}
.navtheme{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);width:100%;
  padding:var(--s3);background:transparent;border:0;border-top:1px solid var(--line2);
  color:var(--gold2);font-family:inherit;font-size:14.5px;letter-spacing:.13em;
  text-transform:uppercase;cursor:pointer;text-align:left}
.navtheme .ic-sun{display:none}
:root[data-theme="light"] .navtheme{color:#714f16}   /* gold2 is 4.17:1 on the darker light-mode header; this is the lightest gold that clears 4.5 */
:root[data-theme="light"] .navtheme .ic-sun{display:block}
:root[data-theme="light"] .navtheme .ic-moon{display:none}
@media (min-width:900px){.navtheme{display:none}}
.themetoggle{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;
  background:transparent;border:1px solid var(--line);color:var(--gold2);cursor:pointer;padding:0;transition:.25s}
.themetoggle:hover{border-color:var(--gold);color:var(--gold)}
.themetoggle .ic-sun{display:none}
:root[data-theme="light"] .themetoggle .ic-sun{display:block}
:root[data-theme="light"] .themetoggle .ic-moon{display:none}
.navtoggle{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;background:var(--panel);border:1px solid var(--line);color:var(--gold2);cursor:pointer;padding:0}
.navtoggle svg{width:20px;height:20px;stroke:currentColor;fill:none}
nav.main{display:none;flex-direction:column;gap:0;position:absolute;top:100%;left:0;right:0;background:var(--bg2);border-bottom:1px solid var(--line);padding:var(--s1) 0;z-index:39}
nav.main.open{display:flex}
nav.main a{padding:var(--s3) var(--s3);border-bottom:1px solid var(--line2)}
body>header .avnow{display:none}
.util .l{display:none}
/* single-column stacks */
.why-grid,.serv-grid,.steps,.rate-grid,.feat-grid,.city-grid,.rev-grid,.join-in,.form .two,.foot-top{grid-template-columns:1fr}
.grid{grid-template-columns:1fr 1fr;gap:var(--s3)}   /* companion cards: 2-up on mobile */

.contact-in{grid-template-columns:1fr;gap:var(--s4)}
.tstrip .wrap{grid-template-columns:1fr 1fr}   /* 2×2 on mobile */
.tstrip .t{border-right:0;border-bottom:0}
.tstrip .t:nth-child(odd){border-right:1px solid var(--line2)}
.tstrip .t:nth-child(-n+2){border-bottom:1px solid var(--line2)}
.rate-grid .r{border-right:0;border-bottom:1px solid var(--line)}
.rate-grid .r:last-child{border-bottom:0}
.fbig img{min-height:340px}
.foot-top{gap:var(--s4);padding-block:var(--s4)}
/* join image sits above copy on mobile */
.join-img{position:relative;min-height:220px}
.join-img img{position:relative}
.join-img:after{background:linear-gradient(0deg,var(--bg2),transparent 62%)}
.join-copy{padding:var(--s4) var(--s3)}

@media (min-width:560px){
  .grid,.tstrip .wrap,.serv-grid,.rev-grid,.city-grid,.form .two,.foot-top{grid-template-columns:1fr 1fr}
  .rate-grid{grid-template-columns:1fr 1fr}
  .rate-grid .r{border-right:0;border-bottom:1px solid var(--line)}
  .rate-grid .r:nth-child(odd){border-right:1px solid var(--line)}
  .rate-grid .r:nth-child(-n+2){border-bottom:1px solid var(--line)}
  .rate-grid .r:nth-last-child(-n+2){border-bottom:0}
  .util .l{display:flex;gap:var(--s3)}
}
@media (min-width:900px){
  .wrap{padding-inline:var(--s4)}
  .sec{padding-block:var(--s5)}
  .sec-head{flex-direction:row;align-items:flex-end;gap:var(--s3);margin-bottom:var(--s4)}
  .sec-head p{max-width:34ch}
  .hero{display:grid;grid-template-columns:1fr 1fr;min-height:82vh}
  .hero-media{position:absolute;inset:0;left:41%;height:auto;min-height:0}
  .hero-media:after{background:linear-gradient(90deg,var(--bg) 2%,rgba(10,9,7,.28) 40%,rgba(10,9,7,.5) 100%)}
  /* Undo the mobile-base overlay: on desktop the copy is its own positioned
     column again and the CTA sits back in normal flow within it. */
  .hero-copy{position:relative;padding:var(--s5) 0 var(--s5) var(--s4);max-width:600px}
  .hero-copy .cta{position:static;transform:none;right:auto;top:auto;
    margin-bottom:var(--s4);justify-content:flex-end}
  .hero h1{font-size:clamp(46px,6vw,94px)}
  .navtoggle{display:none}
  nav.main{display:flex;flex-direction:row;gap:var(--s4);position:static;background:none;border:0;padding:0;z-index:auto;transform:translateY(14px)}
  nav.main a{padding:0;border:0}
  /* match the nav's drop so lang-switch + Book sit on the logo wordmark line */
  .hgroup{transform:translateY(14px)}
  body>header .avnow{display:flex}
  .grid{grid-template-columns:repeat(3,1fr)}
  .tstrip .wrap{grid-template-columns:repeat(4,1fr)}
  .tstrip .t{border-bottom:0;border-right:1px solid var(--line2)}
  .tstrip .t:last-child{border-right:0}
  .why-grid,.serv-grid,.steps,.rev-grid,.city-grid{grid-template-columns:repeat(3,1fr)}
  .rate-grid{grid-template-columns:repeat(4,1fr)}
  .rate-grid .r{border-right:1px solid var(--line);border-bottom:0}
  .rate-grid .r:last-child{border-right:0}
  .feat-grid{grid-template-columns:1.4fr 1fr 1fr}
  .join-in{grid-template-columns:1.3fr 1fr}
  .join-img{position:relative;min-height:0}
  .join-img img{position:absolute}
  .join-img:after{background:linear-gradient(90deg,var(--bg2),transparent 60%)}
  .join-copy{padding:var(--s5) var(--s4)}
  .contact-in{grid-template-columns:1fr 1.1fr;gap:var(--s5)}
  .foot-top{grid-template-columns:1.6fr 1fr 1fr 1fr;gap:var(--s4);padding-block:var(--s5) var(--s4)}
}
@media (min-width:1100px){
  .grid{grid-template-columns:repeat(4,1fr)}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}

/* ============================================================
   Listing / filter bar / language switch  (mobile-first)
   ============================================================ */
/* language dropdown (scales past a couple of languages) */
/* reset the global `details` FAQ styling (border-bottom + padding) that would
   otherwise draw a box under the flag */
.lang-drop{position:relative;margin-right:var(--s1);border:0;padding:0}
.lang-drop summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;font-size:19px;line-height:1;-webkit-user-select:none;user-select:none}
.lang-drop summary::-webkit-details-marker{display:none}
.lang-drop summary .caret{color:var(--muted2);transition:transform .2s}
.lang-drop[open] summary .caret{transform:rotate(180deg)}
.lang-menu{position:absolute;top:calc(100% + 12px);right:0;margin:0;padding:6px;list-style:none;min-width:186px;background:var(--panel);border:1px solid var(--line);border-radius:10px;box-shadow:0 14px 38px rgba(0,0,0,.55)}
.lang-menu li{margin:0}
.lang-menu a{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:7px;text-decoration:none;color:var(--muted);font-size:14px;letter-spacing:.01em;text-transform:none}
.lang-menu a .fl{font-size:19px;line-height:1}
.lang-menu a:hover{background:var(--bg2);color:var(--cream)}
.lang-menu a.on{color:var(--gold2)}

.listing .sec-head{align-items:flex-start}
.listing-count{color:var(--muted);font-size:13px;letter-spacing:.03em;text-align:left}
.avail-inline{display:inline-flex;align-items:center;gap:var(--s2);color:var(--green);font-size:11px;letter-spacing:.12em;text-transform:uppercase}
/* separator so "2 companions" and "2 available now" read as one line */
.avail-inline::before{content:'\00b7';color:var(--muted);margin-right:var(--s2)}
.avail-inline .dot{width:7px;height:7px;border-radius:50%;background:var(--green);display:inline-block}

.filterbar{display:grid;grid-template-columns:1fr;gap:var(--s3);margin:0 0 var(--s4);padding:var(--s3);border:1px solid var(--line);background:var(--bg2)}
.fb-field{display:flex;flex-direction:column;gap:var(--s2);min-width:0}
.fb-field label{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.filterbar select{width:100%;background:var(--panel);border:1px solid var(--line2);color:var(--cream);
  padding:var(--s2) var(--s4) var(--s2) var(--s3);font-family:inherit;font-size:14px;cursor:pointer;
  -webkit-appearance:none;appearance:none;border-radius:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23c9a24b' d='M6 8 0 0h12z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center}
.filterbar select:focus{outline:none;border-color:var(--gold)}
.fb-actions{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2)}
.fb-actions .btn{width:100%;justify-content:center;padding:var(--s3)}

.listing-grid{margin-top:var(--s1)}

@media (min-width:700px){
  .listing .sec-head{align-items:flex-end}
  .listing-count{text-align:right}
}

/* ============================================================
   Smarter filtration: off-canvas drawer on mobile, inline on desktop
   + active-filter chips. Overrides the earlier .filterbar block.
   ============================================================ */
.filter-toggle{display:inline-flex;align-items:center;gap:var(--s2);font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--gold2);background:var(--panel);
  border:1px solid var(--line);padding:var(--s2) var(--s3);cursor:pointer;margin-bottom:var(--s3)}
.filter-toggle svg{stroke:var(--gold)}
.filter-toggle .fcount{background:var(--gold);color:var(--on-gold);border-radius:999px;min-width:19px;height:19px;
  display:inline-flex;align-items:center;justify-content:center;font-size:11px;padding:0 var(--s1)}

/* Filters button + active chips + Clear on one row (mobile). On desktop the
   button is display:none, so the row collapses to just the chips. */
.filter-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2);margin-bottom:var(--s3)}
.filter-row .filter-toggle{margin-bottom:0}
/* display:contents dissolves the .chips box so each chip becomes a flex item of
   the row itself. Without it .chips is ONE item and wraps as a whole block, which
   put the whole group on its own line under the button. */
.filter-row .chips{display:contents}
.chips{display:flex;flex-wrap:wrap;gap:var(--s2);margin-bottom:var(--s3)}
.chip-x,.chip-clear{display:inline-flex;align-items:center;gap:var(--s2);font-size:11px;letter-spacing:.07em;
  text-transform:uppercase;padding:var(--s2) var(--s2);border:1px solid var(--line);color:var(--cream);
  text-decoration:none;background:var(--panel);transition:.25s}
.chip-x span{color:var(--gold2);font-size:14px;line-height:1}
.chip-x:hover{border-color:var(--gold)}
.chip-clear{color:var(--muted);background:transparent}
.chip-clear:hover{color:var(--cream);border-color:var(--gold)}

.fb-head{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--s3);margin-bottom:var(--s0);
  border-bottom:1px solid var(--line);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.fb-close{background:none;border:0;color:var(--cream);font-size:26px;line-height:1;cursor:pointer;padding:0 var(--s1)}
.filter-scrim{position:fixed;inset:0;background:rgba(0,0,0,.62);z-index:44}

/* mobile (base): off-canvas drawer, slides from the right */
.filterbar{position:fixed;top:0;right:0;height:100dvh;width:min(360px,88vw);transform:translateX(100%);
  transition:transform .3s ease;z-index:45;display:flex;flex-direction:column;gap:var(--s3);overflow-y:auto;
  background:var(--bg2);border-left:1px solid var(--line);padding:var(--s3);margin:0}
.filterbar.open{transform:none}

@media (min-width:820px){
  .filter-toggle,.fb-head,.fb-close{display:none}
  .filter-scrim{display:none!important}
  /* inline filter bar = a bare column grid flush to the container edges, so its
     columns line up exactly with the card columns below (no inset box). */
  .filterbar{position:static;transform:none;height:auto;width:auto;overflow:visible;
    display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s3);
    border:0;background:none;padding:0 0 var(--s4);margin:0 0 var(--s4);
    border-bottom:1px solid var(--line)}
  .filterbar .fb-field{min-width:0}
  .filterbar .fb-actions{align-self:end}
}
@media (min-width:900px){ .filterbar{grid-template-columns:repeat(3,1fr)} }   /* matches 3-up cards */
@media (min-width:1100px){ .filterbar{grid-template-columns:repeat(4,1fr)} } /* matches 4-up cards */

.cfoot{justify-content:flex-end}
.cty-c{font-family:inherit;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--on-media-accent);display:block;margin-top:var(--s1)}

/* 2-up companion cards on small phones — tighten caption density */
@media (max-width:559px){
  .grid{gap:var(--s2)}
  .grid .cap{left:11px;right:11px;bottom:11px}
  .grid .cap .n{font-size:16px;gap:var(--s1)}
  .grid .cap .n small{font-size:10px}
  .grid .cap .meta{font-size:9px;gap:var(--s1);margin:var(--s0) 0 var(--s2)}
  .grid .badge{font-size:8px;letter-spacing:.03em;padding:var(--s1) var(--s2);gap:var(--s1);top:8px;left:8px}
  .grid .veri{display:none}                 /* verified chip returns ≥560px; keeps the badge unclipped at 2-up */
  .grid .cfoot .bk{font-size:9px;padding:var(--s1) var(--s2)}
}

/* ============================================================
   Card redesign: companion info BELOW the photo (not overlaid),
   no "verified" chip. Overrides the earlier overlay-card rules.
   ============================================================ */
.card{display:flex;flex-direction:column}
.card .ph:after{display:none}          /* no gradient — nothing overlays the photo now */
.veri{display:none}                    /* verified removed everywhere */
.cap{position:static;left:auto;right:auto;bottom:auto;z-index:auto;
  padding:var(--s3);display:flex;flex-direction:column;gap:var(--s1)}
.cap .n{font-family:Fraunces,Georgia,serif;font-size:20px;color:var(--cream);display:block;line-height:1.15}
.cap .loc{font-size:12px;color:var(--muted);letter-spacing:.02em}
.cap .meta{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s2);font-size:11px;color:var(--muted);margin-top:var(--s0)}
.cap .meta span:first-child{color:var(--cream);font-weight:500}
.cap .bk{align-self:flex-start;margin-top:var(--s2);font-size:10px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--on-gold);background:var(--gold);padding:var(--s2) var(--s3);text-decoration:none;font-weight:600;transition:.25s}
.cap .bk:hover{background:var(--gold2)}

@media (max-width:559px){
  .grid .cap{padding:var(--s2) var(--s2) var(--s3);gap:var(--s1)}
  .grid .cap .n{font-size:16px}
  .grid .cap .loc{font-size:10px}
  .grid .cap .meta{font-size:9px;gap:var(--s1) var(--s2)}
  .grid .cap .bk{margin-top:var(--s1);font-size:9px;padding:var(--s2) var(--s2)}
}

/* ============================================================
   Interior pages: profile, forms/auth/cms (narrow), error pages
   ============================================================ */
.crumb{display:inline-block;color:var(--muted);text-decoration:none;font-size:12px;letter-spacing:.14em;text-transform:uppercase;margin-bottom:var(--s4)}
.crumb:hover{color:var(--gold2)}
.profile-top{display:grid;grid-template-columns:1fr;gap:var(--s4)}
.profile-photo{position:relative;overflow:hidden;border:1px solid var(--line2);background:var(--panel);aspect-ratio:4/5}
.profile-photo img,.profile-photo picture{width:100%;height:100%;object-fit:cover}
.profile-photo .badge{position:absolute;top:14px;left:14px}
.profile-intro .eyebrow{display:block;margin-bottom:var(--s2)}
.profile-intro h1{font-family:Fraunces,serif;font-size:clamp(38px,6vw,68px);font-weight:340;color:var(--cream);letter-spacing:-.02em;line-height:1}
.profile-quote{font-family:Fraunces,serif;font-style:italic;font-weight:300;font-size:20px;color:var(--gold2);margin:var(--s3) 0}
.profile-facts{display:grid;grid-template-columns:1fr 1fr;gap:var(--s0);background:var(--line2);border:1px solid var(--line2);margin:var(--s3) 0}
.profile-facts>div{background:var(--bg);padding:var(--s3) var(--s3)}
.profile-facts dt{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.profile-facts dd{font-family:Fraunces,serif;font-size:18px;color:var(--cream);margin-top:var(--s1)}
.profile-bio{color:var(--muted);font-size:16px;line-height:1.7;margin:var(--s2) 0 var(--s4);max-width:52ch}
.profile-intro .cta{margin-bottom:0}
.curator-note{border-left:2px solid var(--gold);padding:var(--s1) 0 var(--s1) var(--s4);margin:var(--s5) 0}
.curator-note p{font-family:Fraunces,serif;font-style:italic;font-weight:300;font-size:clamp(20px,2.4vw,28px);line-height:1.4;color:var(--cream);max-width:46ch;margin:var(--s2) 0}
.curator-sign{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
.profile-gallery{display:grid;grid-template-columns:1fr;gap:var(--s3);margin:var(--s4) 0}
.profile-gallery .shot{overflow:hidden;border:1px solid var(--line2)}
.profile-gallery .shot img,.profile-gallery video{width:100%;display:block}
.profile-related{margin-top:var(--s5)}
@media (min-width:560px){ .profile-gallery{grid-template-columns:repeat(2,1fr)} }
@media (min-width:820px){
  .profile-top{grid-template-columns:.85fr 1fr;gap:var(--s4);align-items:start}
  .profile-gallery{grid-template-columns:repeat(3,1fr)}
}

.contact-narrow,.page-doc{max-width:720px;margin:0 auto}
.contact-narrow.center{text-align:center}
.page-h1{font-family:Fraunces,serif;font-size:clamp(34px,5vw,58px);font-weight:340;color:var(--cream);letter-spacing:-.02em;line-height:1.02;margin:var(--s3) 0 var(--s3)}
.form .field-err{display:block;color:#e0785f;font-size:12px;margin-top:var(--s1)}
.form-alert{background:rgba(224,120,95,.12);border:1px solid rgba(224,120,95,.4);color:#f4a184;padding:var(--s2) var(--s3);font-size:14px;margin-bottom:var(--s3)}
.form .form-back{margin-top:var(--s2)}
.page-doc-body p{color:var(--muted);font-size:16px;line-height:1.8;margin-bottom:var(--s3)}
.page-doc .cta{margin-top:var(--s4)}
/* landing reference list — text links to the models involved, no photos */
.ref-block{margin-top:var(--s5);border-top:1px solid var(--line);padding-top:var(--s4)}
.ref-h{font-size:22px;color:var(--cream);margin-bottom:var(--s3)}
.ref-list{list-style:none;margin:0 0 var(--s3);padding:0;display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4)}
.ref-list li{display:inline-flex;align-items:baseline;gap:var(--s1)}
.ref{font-family:Fraunces,serif;font-size:18px;color:var(--gold2);text-decoration:none;border-bottom:1px solid transparent;transition:border-color .2s}
.ref:hover{border-bottom-color:var(--gold2)}
.ref-loc{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.ref-all{display:inline-block;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);text-decoration:none;transition:color .2s}
.ref-all:hover{color:var(--gold2)}
.page-doc-cta{margin-top:var(--s5)}
/* editorial landing article */
.art{padding-block:var(--s5)}
.art-hero{max-width:780px;margin:0 auto;text-align:center}
.art-title{font-family:Fraunces,serif;font-size:clamp(36px,6vw,64px);font-weight:340;color:var(--cream);letter-spacing:-.02em;line-height:1.03;margin:var(--s3) 0 0}
.art-standfirst{font-size:19px;line-height:1.65;color:var(--cream);max-width:62ch;margin:var(--s3) auto 0}
.art-figure{float:right;width:min(340px,42%);margin:.4em 0 var(--s3) var(--s4)}
.art-figure img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;border:1px solid var(--line2);border-radius:3px;filter:grayscale(.14) brightness(.84)}
@media(max-width:640px){.art-figure{float:none;width:100%;margin:0 0 var(--s3)}}
.art-body{max-width:720px;margin:var(--s5) auto 0}
.art-body p{color:var(--muted);font-size:17px;line-height:1.85;margin-bottom:var(--s3)}
.art-h{font-family:Fraunces,serif;font-size:26px;color:var(--cream);margin:var(--s4) 0 var(--s2)}
.art-model{color:var(--gold2);text-decoration:none;border-bottom:1px solid rgba(201,162,75,.38);transition:border-color .2s}
.art-model:hover{border-bottom-color:var(--gold2)}
.art-cta{margin-top:var(--s5);display:flex;gap:var(--s3);flex-wrap:wrap}
/* Landing roster: every companion this page is about, linked. Sits outside the
   720px reading column so the cards use the same 4-up grid as the listing. */
.art-roster{margin-top:var(--s6,var(--s5));padding-bottom:var(--s5)}

.error-page{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:var(--s3);padding:var(--s4) var(--s3)}
.error-page .eyebrow{font-size:14px}
.error-page h1{font-family:Fraunces,serif;font-size:clamp(30px,5vw,52px);font-weight:340;color:var(--cream)}
.error-page .lede{color:var(--muted);max-width:40ch;margin-bottom:var(--s1)}

/* Card Book button — bottom-right corner of the companion photo (index + listing) */
.card .ph-wrap{position:relative}
.card .cap .bk{display:none}                 /* old below-photo Book removed */
.bk-corner{position:absolute;right:10px;bottom:10px;z-index:4;
  font-size:10px;letter-spacing:.13em;text-transform:uppercase;font-weight:600;
  color:var(--on-gold);background:var(--gold);padding:var(--s2) var(--s3);text-decoration:none;
  box-shadow:0 8px 22px -6px rgba(0,0,0,.7);transition:.25s}
.bk-corner:hover{background:var(--gold2)}
@media (max-width:559px){
  .grid .bk-corner{right:8px;bottom:8px;font-size:9px;padding:var(--s2) var(--s2)}
}

/* availability status stays on the photo (top-left badge) */

/* ============================================================
   Rich profile page — hero, gallery, video, expanded details
   ============================================================ */
.pf-hero{display:grid;grid-template-columns:1fr;gap:var(--s4);margin-bottom:var(--s3)}
.pf-lead .ph-wrap{position:relative;border:1px solid var(--line2);background:var(--panel);overflow:hidden}
.pf-lead .ph-wrap img,.pf-lead .ph-wrap picture{width:100%;display:block;aspect-ratio:4/5;object-fit:cover}
.pf-lead .badge{top:14px;left:14px}
/* hero photo + non-hero thumb strip (both open the gallery lightbox) */
.pf-shot{display:block;width:100%;padding:0;margin:0;border:0;background:none;cursor:zoom-in;position:relative}
.pf-thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s2);margin-top:var(--s2)}
.pf-thumb img{width:100%;aspect-ratio:4/5;object-fit:cover;display:block;border:1px solid var(--line2);transition:border-color .3s}
.pf-thumb:hover img{border-color:var(--gold)}
/* gallery lightbox */
.lb{position:fixed;inset:0;z-index:100;background:rgba(8,7,5,.95);display:flex;align-items:center;justify-content:center}
.lb[hidden]{display:none}
.lb-img{max-width:92vw;max-height:92vh;object-fit:contain;border:1px solid var(--line2)}
.lb-btn{position:absolute;background:rgba(0,0,0,.45);color:var(--cream);border:1px solid var(--line);cursor:pointer;font-size:26px;line-height:1;width:48px;height:48px;display:flex;align-items:center;justify-content:center}
.lb-btn:hover{color:var(--gold2)}
.lb-close{top:16px;right:16px}
.lb-prev{left:16px;top:50%;transform:translateY(-50%)}
.lb-next{right:16px;top:50%;transform:translateY(-50%)}
.pf-intro .eyebrow{display:block;margin-bottom:var(--s2)}
.pf-intro h1{font-family:Fraunces,serif;font-size:clamp(40px,6vw,72px);font-weight:340;line-height:1;letter-spacing:-.02em;color:var(--cream);margin-top:var(--s1)}
/* name row with the Book button right-aligned beside the name */
.pf-namebar{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s3);flex-wrap:wrap}
.pf-namebar-l{min-width:0}
.pf-book{flex:0 0 auto;white-space:nowrap}
/* ── Age verification + cookie consent gate ───────────────────────────────
   Ported from Meretrix's .warningPop. The page behind is blurred while the gate
   is up, and the blur is keyed off the SAME <html> class that reveals the gate,
   so the site can never end up blurred with no dialog to clear it — the failure
   Meretrix carries an explicit guard against. */
/* Barely-there veil, like Meretrix's .warningPop which carries NO background at
   all — the site stays visible behind the gate, softened rather than hidden. A
   heavy scrim plus a heavy blur left nothing of the page to see. */
.agegate{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  padding:var(--s3);background:var(--ag-veil);overflow-y:auto}
html.needs-agegate body>*:not(.agegate){filter:blur(7px)}
html.needs-agegate body{overflow:hidden}
.ag-panel{width:100%;max-width:460px;background:var(--bg2);border:1px solid var(--line);
  padding:var(--s4) var(--s4) var(--s3);text-align:center;box-shadow:var(--shadow)}
/* Logo centred and full-width in its own block, heading and body beneath it —
   the Meretrix .warningLogo arrangement (176px, margin:auto, padding-bottom). */
.ag-brand{width:176px;max-width:64%;margin:0 auto var(--s3);display:block}
.ag-brand img{width:100%;height:auto;display:block}
.ag-brand .serif{font-family:Fraunces,serif;font-size:28px;color:var(--gold2);display:block;text-align:center}
.ag-h{font-size:26px;color:var(--cream);margin-bottom:var(--s2)}
/* Scrollable if the operator writes a long notice — Meretrix caps .wContent at
   250px on small screens for the same reason. */
.ag-body{color:var(--muted);font-size:14px;line-height:1.7;margin-bottom:var(--s3);
  max-height:260px;overflow-y:auto;text-align:left}
.ag-body p+p{margin-top:var(--s2)}
.ag-row{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:var(--s3) 0;border-top:1px solid var(--line2);text-align:left;cursor:pointer}
.ag-text{color:var(--cream);font-size:13.5px;line-height:1.5}
.ag-req{color:#e0645c}
.ag-switch{position:relative;flex:0 0 46px;width:46px;height:26px}
.ag-switch input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer;z-index:2}
.ag-slider{position:absolute;inset:0;background:var(--panel2);border:1px solid var(--line2);
  border-radius:999px;transition:.2s}
.ag-slider:after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;
  background:var(--muted);transition:.2s}
.ag-switch input:checked+.ag-slider{background:var(--gold);border-color:var(--gold)}
.ag-switch input:checked+.ag-slider:after{transform:translateX(20px);background:var(--on-gold)}
.ag-switch input:focus-visible+.ag-slider{outline:2px solid var(--gold2);outline-offset:2px}
.ag-error{color:#e0645c;font-size:13px;margin-top:var(--s2);text-align:left}
/* The two buttons need ~371px of intrinsic width (measured); a 320px phone
   offers ~288px inside the panel. `flex:1 1 auto` will not shrink below content
   because min-width defaults to auto — so set min-width:0 and let them wrap. */
.ag-actions{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s3)}
.ag-actions .btn{flex:1 1 140px;min-width:0;justify-content:center;padding-inline:var(--s3)}
.ag-fine{margin-top:var(--s3);font-size:11.5px;line-height:1.6;color:var(--muted2)}
.ag-fine a{color:var(--gold2)}
@media (max-width:480px){.ag-panel{padding:var(--s3)}.ag-h{font-size:22px}.ag-brand{width:150px}}

/* ── Mobile profile action bar ────────────────────────────────────────────
   Prev / BOOK / Next pinned to the bottom on mobile; desktop keeps the in-page
   CTA and never renders this, so there is exactly one CTA per breakpoint.
   Square, not rounded — the bar is chrome; the pills are for filters and tabs.
   Rendered at body level (layouts/noir.php) so nothing can become its
   containing block.

   Plain `position:fixed; bottom:0`, the same recipe as the Meretrix bar this
   was modelled on (.cAgency in escortservices/assets/css/media.css). It only
   misbehaved here because the layout carried `viewport-fit=cover`, which
   extends the viewport under the browser's own chrome; that is now gone. No
   dvh maths, no visualViewport probe, no translateZ — all of those were
   attempts to compensate for a problem that was in the viewport meta. */
.pf-bottombar{display:none}
@media (max-width:640px){
  .pf-bottombar{
    --bb-ctl:38px;
    display:flex;align-items:center;gap:10px;
    position:fixed;left:0;bottom:0;width:100%;z-index:60;
    padding:7px var(--s3);
    background:var(--bar);
    border-top:1px solid var(--line);
  }
  .pf-bb-arrow{
    flex:0 0 44px;height:var(--bb-ctl);
    display:inline-flex;align-items:center;justify-content:center;
    background:rgba(255,255,255,.04);border:1px solid var(--line2);
    color:var(--gold2);text-decoration:none;transition:.18s}
  .pf-bb-arrow:active{border-color:var(--gold);color:var(--gold)}
  .pf-bb-book{
    flex:1 1 auto;height:var(--bb-ctl);
    display:inline-flex;align-items:center;justify-content:center;
    padding:0 var(--s3);border:1px solid var(--gold);cursor:pointer;
    background:var(--gold);color:var(--on-gold);font-family:inherit;font-size:11.5px;
    letter-spacing:.14em;text-transform:uppercase;font-weight:600;
    text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* One CTA per breakpoint: the bar replaces the in-page button on mobile. */
  .pf-book{display:none}
  /* Clear the fixed bar so it never covers the last of the content. */
  .sec.pf{padding-bottom:calc(var(--bb-ctl,38px) + 34px)}
}
.pf-lede{color:var(--muted);font-size:16px;line-height:1.7;margin:var(--s3) 0;max-width:54ch}
.pf-quick{display:flex;flex-wrap:wrap;gap:var(--s2);margin:var(--s3) 0 var(--s3)}
.pf-tag{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--cream);border:1px solid var(--line);padding:var(--s2) var(--s3);background:var(--panel)}
.pf-intro .cta{margin-bottom:0}

.pf-block{padding-block:var(--s4);border-top:1px solid var(--line2)}
.pf-block-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s3)}
.pf-block-head h2{font-family:Fraunces,serif;font-size:clamp(24px,3vw,34px);font-weight:400;color:var(--cream)}

.pf-gallery{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s3)}
.pf-gallery .shot{overflow:hidden;border:1px solid var(--line2);background:var(--panel)}
.pf-gallery .shot img,.pf-gallery .shot picture,.pf-gallery .shot picture img{width:100%;height:100%;aspect-ratio:4/5;object-fit:cover;display:block;transition:.5s}
.pf-gallery .shot:hover img{transform:scale(1.04)}

.pf-video-tile{position:relative;overflow:hidden;border:1px solid var(--line2)}
.pf-video-tile video{width:100%;display:block}
/* video sits inside .pf-lead, directly under the thumbnails: left column (~50%)
   on desktop, full width after the thumbs on mobile. */
.pf-video-block{margin-top:var(--s3)}
.pf-video-block .pf-block-head{margin-bottom:var(--s2)}
.pf-video-empty img{width:100%;aspect-ratio:16/9;object-fit:cover;filter:brightness(.5)}
.pf-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:66px;height:66px;border-radius:50%;background:var(--gold);color:var(--on-gold);display:flex;align-items:center;justify-content:center;box-shadow:0 12px 34px -8px rgba(0,0,0,.7)}
.pf-video-note{position:absolute;left:18px;bottom:15px;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--cream)}

.pf-details{display:grid;grid-template-columns:1fr;gap:var(--s4)}
.pf-spec-h{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--gold);margin:0 0 var(--s3);font-weight:500}
.pf-spec .chips{margin-bottom:var(--s3)}
/* Social tab — same label/value rhythm as .pf-rate so the panes look related. */
.pf-socials{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.pf-social{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:var(--s2) 0;border-bottom:1px solid var(--line)}
.pf-social:last-child{border-bottom:0}
.pf-social .ps-label{color:var(--muted);font-size:11px;letter-spacing:.12em;text-transform:uppercase}
.pf-social .ps-val{color:var(--cream);font-size:15px;text-decoration:none;word-break:break-word;text-align:right}
.pf-social a.ps-val{color:var(--gold2);border-bottom:1px solid transparent;transition:.25s}
.pf-social a.ps-val:hover{border-bottom-color:var(--gold)}
.pf-dl{display:grid;grid-template-columns:1fr 1fr;gap:var(--s0);background:var(--line2);border:1px solid var(--line2)}
.pf-dl>div{background:var(--bg);padding:var(--s3) var(--s3)}
.pf-dl dt{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.pf-dl dd{font-family:Fraunces,serif;font-size:18px;color:var(--cream);margin-top:var(--s1)}
.chip-tag{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--cream);border:1px solid var(--line);padding:var(--s2) var(--s3);background:var(--panel)}
.pf-loc-main{font-family:Fraunces,serif;font-size:22px;color:var(--cream);margin-bottom:var(--s3)}
.pf-loc-list{list-style:none;display:flex;flex-direction:column;gap:var(--s2)}
.pf-loc-list li{color:var(--muted);font-size:14px;padding-left:var(--s3);position:relative}
.pf-loc-list li:before{content:"·";position:absolute;left:3px;color:var(--gold)}

@media (min-width:820px){
  .pf-hero{grid-template-columns:1fr 1fr;gap:var(--s4);align-items:start}
  .pf-gallery{grid-template-columns:repeat(3,1fr);gap:var(--s3)}
  .pf-details{grid-template-columns:1fr 1fr 1fr;gap:var(--s4)}
}
@media (min-width:1100px){ .pf-gallery{grid-template-columns:repeat(4,1fr)} }

/* profile: details live in the hero-right column, at the top (reference layout) */
.pf-facts{margin-top:var(--s3)}
.pf-intro .cta{margin:var(--s3) 0 var(--s2)}
.pf-intro .pf-lede{margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid var(--line2)}
@media (min-width:820px){
  /* .pf-lead is NOT sticky: it now holds the video under the thumbs, and a
     column taller than the viewport would pin and hide the video's lower half. */
  .pf-intro .pf-dl{grid-template-columns:repeat(3,1fr)}
}

/* profile: prominent description + individual rate card */
.pf-about{margin-top:var(--s3)}
.pf-desc{color:var(--cream);font-size:17px;line-height:1.75;max-width:60ch}
/* About / Selfies / Interview tabs on the profile — clear segmented control */
.pf-tabnav{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:var(--s3)}
/* Mobile: the pills must stay on ONE row. Measured at 375px the four profile
   tabs came to 407px against 343px available, and 160px of that was side
   padding — so trim the padding and the tracking rather than let a tab wrap.
   nowrap + overflow-x is the safety net: a longer label in another language
   (or a fifth tab later) scrolls instead of silently dropping to a second row. */
@media (max-width:640px){
  .chip,.pf-tab{padding:9px 12px;letter-spacing:.06em}
  .pf-tabnav{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .pf-tabnav::-webkit-scrollbar{display:none}
  .pf-tabnav .pf-tab{flex:0 0 auto}
}
/* .pf-tab is styled with .chip in the board block above — one pill, one rule. */
.pf-pane{display:none}
.pf-pane.is-active{display:block;animation:pfFade .25s ease}
@keyframes pfFade{from{opacity:0}to{opacity:1}}
.pf-selfies{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s2)}
.pf-selfie{display:block;overflow:hidden;border:1px solid var(--line2)}
.pf-selfie img{width:100%;height:100%;aspect-ratio:4/5;object-fit:cover;display:block;transition:.4s}
.pf-selfie:hover img{transform:scale(1.05)}
.pf-interview{color:var(--cream);font-size:16px;line-height:1.75;max-width:66ch}
.pf-interview h2{font-family:Fraunces,serif;font-size:24px;font-weight:400;margin:1em 0 .3em}
.pf-interview h3{font-family:Fraunces,serif;font-size:19px;font-weight:400;margin:1em 0 .3em;color:var(--gold)}
.pf-interview p{margin:0 0 1em}
.pf-interview blockquote{border-left:2px solid var(--gold);margin:1em 0;padding-left:var(--s3);color:var(--muted);font-style:italic}
.pf-interview a{color:var(--gold)}
.pf-rates{display:grid;grid-template-columns:1fr 1fr;gap:var(--s0);background:var(--line2);border:1px solid var(--line2)}
.pf-rate{background:var(--bg);padding:var(--s3) var(--s3);display:flex;flex-direction:column;gap:var(--s1)}
.pf-rate .rl{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.pf-rate .ra{font-family:Fraunces,serif;font-size:24px;color:var(--gold2);line-height:1}
.pf-rate-note{font-size:12px;color:var(--muted2);margin-top:var(--s2);letter-spacing:.02em}
@media (min-width:520px){ .pf-rates{grid-template-columns:repeat(4,1fr)} }

/* ============================================================
   SHARED 12-COLUMN GRID — every section snaps to the same lines.
   Uniform gutter (--s3). Blocks span whole columns, never ragged.
   4-up = span 3 · 3-up = span 4 · 2-up = span 6 · 1-up = span 12.
   ============================================================ */
.grid,.why-grid,.serv-grid,.city-grid,.rev-grid,.feat-grid,.foot-top{
  display:grid;grid-template-columns:repeat(12,1fr);gap:var(--s3)}
/* base (mobile) */
.grid>*{grid-column:span 6}                                   /* cards 2-up */
.why-grid>*,.serv-grid>*,.rev-grid>*{grid-column:span 12}     /* 1-up */
.city-grid>*{grid-column:span 6}                              /* locations 2-up on mobile */
.feat-grid>*{grid-column:span 12}
.foot-top>*{grid-column:span 6}
@media (min-width:560px){
  .serv-grid>*,.city-grid>*,.rev-grid>*{grid-column:span 6}   /* 2-up */
  .foot-top>*{grid-column:span 6}
}
@media (min-width:900px){
  .grid>*{grid-column:span 4}                                 /* board 3-up */
  .why-grid>*,.serv-grid>*,.city-grid>*,.rev-grid>*{grid-column:span 4}  /* 3-up */
  .feat-grid .fbig{grid-column:span 6}
  .feat-grid .fcol{grid-column:span 3}
  /* three children now (brand + menu + agency): brand takes half, the two link
     columns split the rest. Was 4 × span 3 when a Companions column existed. */
  .foot-brand{grid-column:span 6}
  .foot-col{grid-column:span 3}
}
@media (min-width:1100px){
  .grid>*{grid-column:span 3}                                 /* board 4-up */
}
/* Casting: multi-photo picker hint sits tight under its input. */
.cast-photo-hint{margin-top:var(--s1)}

/* --- Companion picker (booking form) ------------------------------------
   A native <select> can't show a photo, so this is a button + listbox. It is
   sized and coloured to match the form's own inputs so it doesn't read as a
   different control. Without JS the list is simply visible and still usable. */
.cpick{position:relative}
.cpick-trigger{display:flex;align-items:center;gap:var(--s3);width:100%;text-align:left;cursor:pointer;
  background:var(--panel);border:1px solid var(--line2);color:var(--cream);
  font-family:inherit;font-size:14px;padding:10px 14px;transition:.2s}
.cpick-trigger:hover,.cpick-trigger[aria-expanded="true"]{border-color:var(--gold)}
.cpick-trigger:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.cpick-face{flex:none;width:40px;height:40px;overflow:hidden;background:var(--bg2);
  border:1px solid var(--line2);display:flex;align-items:center;justify-content:center}
.cpick-face img{width:100%;height:100%;object-fit:cover;display:block}
.cpick-ini{font-size:12px;letter-spacing:.08em;color:var(--muted)}
.cpick-text{min-width:0;flex:1}
.cpick-name{display:block;color:var(--cream);font-size:14px;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cpick-meta{display:block;color:var(--muted);font-size:11px;letter-spacing:.04em;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cpick-caret{flex:none;color:var(--gold2);transition:transform .2s}
.cpick-trigger[aria-expanded="true"] .cpick-caret{transform:rotate(180deg)}
.cpick-list{position:absolute;z-index:30;left:0;right:0;margin-top:4px;max-height:320px;overflow-y:auto;overflow-x:hidden;
  list-style:none;padding:0;background:var(--bg2);border:1px solid var(--gold);box-shadow:var(--shadow)}
.cpick-opt{display:flex;align-items:center;gap:var(--s3);padding:8px 14px;cursor:pointer}
.cpick-opt:hover,.cpick-opt.is-active{background:rgba(201,162,75,.12)}
.cpick-opt.is-on{background:rgba(201,162,75,.2)}
.cpick-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--green)}
.cpick-list[hidden]{display:none}
/* .form label is (0,1,1) and would beat a bare .cpick-lab, leaving the row as a
   block and knocking the photo out of line — scope it to win. */
.cpick .cpick-lab{display:flex;align-items:center;gap:var(--s3);width:100%;cursor:pointer;margin:0;
  font-size:14px;letter-spacing:normal;text-transform:none;color:inherit}
/* The radio IS the value; it is hidden visually, not removed, so the control
   still works with a keyboard and without JavaScript. */
.cpick-radio{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.cpick-radio:focus-visible + .cpick-face{outline:2px solid var(--gold);outline-offset:2px}

/* --- Human check: a dialog on Send, so the form itself stays short -------- */
.puzzle-modal{border:1px solid var(--gold);background:var(--bg2);color:var(--cream);
  padding:var(--s4);max-width:380px;width:calc(100% - 2rem);box-shadow:var(--shadow);
  /* The site reset zeroes margins, which defeats the UA's `margin:auto`
     centring for a modal dialog — put it back explicitly. */
  margin:auto}
.puzzle-modal::backdrop{background:rgba(6,5,4,.78)}
.puzzle-title{font-size:22px;margin:0 0 var(--s1)}
.puzzle-lede{color:var(--muted);font-size:13px;margin:0 0 var(--s3)}
.puzzle-canvas{display:block;width:100%;height:auto;border:1px solid var(--line2);background:var(--panel)}
.puzzle-range{display:block;width:100%;margin-top:var(--s3);accent-color:var(--gold);cursor:grab}
.puzzle-range:active{cursor:grabbing}
.puzzle-range:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.puzzle-actions{display:flex;gap:var(--s2);justify-content:flex-end;margin-top:var(--s3)}
.puzzle-sronly{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* Browsers without <dialog>: it falls back to an inline panel rather than
   vanishing, so the check is still reachable. */
.puzzle-modal[open]{display:block}
@media (prefers-reduced-motion:no-preference){.puzzle-modal[open]{animation:puzIn .18s ease}}
@keyframes puzIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Required marker + the "what's still missing" line under a form. */
.req{color:var(--gold2);margin-left:.15em;font-weight:600}
.form-missing{color:var(--gold2);margin:0 0 var(--s2)}
.form-missing:empty{display:none}
.btn.is-waiting,.btn:disabled,.btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed}

/* --- Booking panel (reception-booked companions) -------------------------
   Wears .direct-modal, so the border, ground, padding and width all come from
   that one rule and the two panels cannot drift apart.
   What is added here is about holding a form on a phone: the whole thing has to
   land inside one screen, so the vertical rhythm is tightened and every block
   of prose that is not a field has been dropped from the markup. The height cap
   stays as a safety net for very short screens. */
.book-modal{max-height:calc(100dvh - 2rem);overflow-y:auto}
.book-modal .form{background:none;border:0;padding:0;margin:0}
.book-modal .direct-title{margin:var(--s1) 0 var(--s3)}

/* Reception above the form: phone, WhatsApp, Signal — three separate boxes on
   ONE line at every width, including a 375px phone. Separate boxes because they
   are separate numbers; one line because that is what was asked for, so the
   number's type and padding are sized to fit beside the two icon squares rather
   than the other way round. */
.recep-line{display:flex;align-items:stretch;gap:var(--s2)}
.recep-tel,.recep-wa,.recep-signal{border:1px solid var(--line2);background:var(--panel);
  display:flex;align-items:center;text-decoration:none;transition:.2s}
.recep-tel{flex:1 1 auto;min-width:0;gap:6px;padding:8px 10px;
  color:var(--cream);font-size:15px;letter-spacing:0}
.recep-tel svg{width:18px;height:18px;color:var(--gold2);flex:none}
.recep-tel span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.recep-tel:hover{border-color:var(--gold);color:var(--gold)}
.recep-wa,.recep-signal{flex:0 0 44px;justify-content:center;padding:8px}
.recep-wa svg,.recep-signal svg{width:22px;height:22px}
.recep-wa{color:#25d366}
.recep-wa:hover{border-color:#25d366}
.recep-signal{color:#3a76f0}
.recep-signal:hover{border-color:#3a76f0}
/* No phone at all: the app boxes share the whole row instead of huddling left. */
.recep-line:not(:has(.recep-tel)) > a{flex:1 1 0}
@media (min-width:560px){
  .recep-tel{gap:var(--s2);padding:10px 12px;font-size:16px}
  .recep-tel svg{width:20px;height:20px}
  .recep-wa,.recep-signal{flex:0 0 auto;padding:8px 16px}
  .recep-wa svg,.recep-signal svg{width:24px;height:24px}
}

/* "— or —": a rule either side of the word. */
.or-sep{display:flex;align-items:center;gap:var(--s3);margin:var(--s3) 0;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted2)}
.or-sep::before,.or-sep::after{content:"";flex:1;height:1px;background:var(--line2)}

/* Compact rhythm: same fields, less air between them. */
.form--compact .fr{margin-bottom:var(--s2)}
.form--compact label{margin-bottom:var(--s1)}
.form--compact input,.form--compact textarea{padding:10px var(--s3)}
.form--compact textarea{min-height:56px}
.form--compact .two{gap:var(--s2)}
.book-modal .form .btn{margin-top:var(--s2)}
.book-modal .direct-actions{margin-top:var(--s2)}
/* Short screens only (a 640px-tall Android, or any phone in landscape): shave
   the last ~20px so the panel closes inside the viewport instead of leaving a
   scrollbar. Taller phones keep the roomier message box. */
@media (max-height:700px){
  .form--compact textarea{min-height:44px}
  .book-modal .direct-actions{margin-top:0}
  /* The panel's own bottom padding was the last thing forcing a scrollbar.
     Trimmed on the booking panel only, and only where the screen is short. */
  .book-modal{padding-bottom:var(--s3)}
}

/* Date and time are short values; keeping them paired at every width stops the
   message field being pushed below the fold on a phone. Desktop already pairs
   them, so this changes nothing there. */
.form .two-keep{grid-template-columns:1fr 1fr}
/* Grid blowout: a native date/time control has a wide intrinsic minimum, and a
   grid item defaults to min-width:auto, so the column refuses to shrink and the
   field spills past the panel's border. */
.form .two > *{min-width:0}
.form input[type=date],.form input[type=time]{max-width:100%}
/* Half-width on a phone leaves a date barely 130px wide; the standard field
   padding then crowds the value against the browser's own calendar/clock icon. */
.form .two-keep input{padding-left:var(--s2);padding-right:var(--s2)}

/* --- Independent companion: direct-contact panel ------------------------- */
.direct-modal{border:1px solid var(--gold);background:var(--bg2);color:var(--cream);
  padding:var(--s4);max-width:420px;width:calc(100% - 2rem);box-shadow:var(--shadow);margin:auto}
.direct-modal::backdrop{background:rgba(6,5,4,.78)}
.direct-eyebrow{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold2);margin:0}
.direct-title{font-size:26px;margin:var(--s1) 0 var(--s2)}
.direct-lede{color:var(--muted);font-size:13px;margin:0 0 var(--s3)}
/* Independent companion's channels: one row each, stacked — logo, label, value. */
.direct-list{list-style:none;padding:0;margin:0;display:grid;gap:var(--s2)}
.direct-row{display:flex;align-items:center;gap:var(--s3);padding:12px 14px;text-decoration:none;
  border:1px solid var(--line2);background:var(--panel);color:var(--cream);transition:.2s}
.direct-row:hover{border-color:var(--gold);background:rgba(201,162,75,.10)}
.direct-ico{flex:none;width:26px;height:26px;display:flex;align-items:center;justify-content:center;color:var(--gold2)}
.direct-ico svg{width:22px;height:22px}
.direct-whatsapp .direct-ico{color:#25d366}
.direct-telegram .direct-ico{color:#26a5e4}
.direct-signal .direct-ico{color:#3a76f0}
.direct-text{min-width:0}
.direct-label{display:block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.direct-value{display:block;font-size:16px;letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.direct-note{color:var(--muted);margin:var(--s3) 0 0}
.direct-actions{display:flex;justify-content:flex-end;margin-top:var(--s3)}

/* No photos yet — an honest empty state instead of somebody else's picture. */
.pf-noshot{position:relative;display:flex;align-items:center;justify-content:center;aspect-ratio:4/5;
  background:var(--panel);border:1px dashed var(--line)}
.pf-noshot-text,.card-noshot{color:var(--muted);font-size:11px;letter-spacing:.16em;text-transform:uppercase}
.card-noshot{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:var(--panel);border-bottom:1px dashed var(--line)}
