/* Mango Space, 2026-08.
   White ground, the way Bo's own WordPress draft reads. Navy headings, their blue
   for action, their logo green for proof. The hero, page headers and footer are the
   only dark surfaces; everything between them is white or the pale tint. */

:root{
  /* Counted out of Bo's draft markup: #258BCC 96 times, #133A60 86 times.
     Green #00B478 is sampled from the logo wordmark's own gradient. */
  --navy:#133A60; --navy-2:#0F2A47; --navy-3:#0B2038;
  --blue:#258BCC; --blue-dk:#1B6EA6; --blue-lt:#57AEE4;
  --green:#87C151;            /* on dark only */
  --green-ink:#4E8F2B;        /* the same green, taken dark enough for white */
  --teal:#00B478;
  --paper:#FFFFFF; --tint:#F2F9FD; --line:#E2EDF5;
  --body:#5B6B78; --muted:#8A98A4;
  --shadow:0 1px 2px rgba(19,58,96,.05),0 12px 28px -18px rgba(19,58,96,.28);
  --shadow-h:0 2px 6px rgba(19,58,96,.07),0 22px 44px -22px rgba(19,58,96,.36);
  --wrap:1200px; --nar:760px; --s:clamp(56px,7vw,104px);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--body);
  font:400 17px/1.7 'Poppins',-apple-system,'Segoe UI',system-ui,sans-serif;
  -webkit-font-smoothing:antialiased}
img{display:block;max-width:100%;height:auto}
a{color:inherit}
h1,h2,h3{margin:0;line-height:1.12;letter-spacing:-.02em;text-wrap:balance;
  font-weight:700;color:var(--navy)}
h1{font-size:clamp(33px,5vw,60px);line-height:1.06}
h2{font-size:clamp(26px,3.3vw,42px)}
h3{font-size:19px;letter-spacing:-.01em}
p{margin:0 0 1.05em}
.wrap{width:min(100% - 40px,var(--wrap));margin-inline:auto}
.narrow{width:min(100% - 40px,var(--nar));margin-inline:auto}
.muted{color:var(--muted);font-size:16px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:14px;top:14px;z-index:99;background:var(--blue);color:#fff;padding:10px 16px;border-radius:8px}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px}

.kicker{font-size:16px;letter-spacing:.15em;text-transform:uppercase;color:var(--blue-dk);
  font-weight:600;margin:0 0 14px}
.lede{font-size:clamp(17px,1.6vw,20px);color:var(--body);max-width:62ch;margin-top:16px;line-height:1.6}
.prose p{color:var(--body)}

.promo-bar{background:var(--navy);color:#fff;text-align:center;font-size:16px;
  font-weight:500;padding:10px 16px}
.promo-bar a{color:#fff;text-underline-offset:3px}
.promo-sep{opacity:.55;margin:0 8px}
.promo-tel{font-weight:700;text-decoration:none;white-space:nowrap}
.promo-tel:hover{text-decoration:underline}
/* the phone here is tap-to-call, so it needs a real target, not a 27px line box */
.promo-bar a{padding:4px 2px;display:inline-block}
@media (max-width:520px){.promo-sep{display:none}
  .promo-tel{display:block;margin-top:0;padding:8px 2px}}

/* ---------- nav ---------- */
.nav{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.94);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.nav-in{display:flex;align-items:center;gap:24px;padding:12px 0}
.brand{display:flex;align-items:center;text-decoration:none;margin-right:auto}
.brand img{height:36px;width:auto}
.nav-links{display:flex;gap:20px}
.nav-links a{text-decoration:none;font-size:16px;color:var(--navy);font-weight:500;
  padding-bottom:3px;border-bottom:2px solid transparent;transition:.2s}
.nav-links a:hover,.nav-links a[aria-current]{color:var(--blue-dk);border-color:var(--blue)}
.burger{display:none;background:none;border:0;padding:9px;cursor:pointer}
.burger span{display:block;width:23px;height:2px;background:var(--navy);margin:5px 0;border-radius:2px}
.drawer{display:none}

/* ---------- buttons ---------- */
.btn{display:inline-block;background:var(--blue);color:#fff;text-decoration:none;
  font-weight:600;font-size:16px;padding:13px 25px;border-radius:10px;
  border:2px solid var(--blue);transition:.2s;cursor:pointer;line-height:1.3}
.btn:hover{background:var(--blue-dk);border-color:var(--blue-dk)}
.btn-sm{padding:9px 17px}
.btn-ghost{background:transparent;color:var(--blue-dk);border-color:#BFDCF0}
.btn-ghost:hover{background:var(--tint);border-color:var(--blue);color:var(--blue-dk)}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px;align-items:center}

/* on the dark hero, page headers and closing band the ghost button inverts */
.hero .btn-ghost,.phead .btn-ghost,.cta .btn-ghost{
  color:#fff;border-color:rgba(255,255,255,.5)}
.hero .btn-ghost:hover,.phead .btn-ghost:hover,.cta .btn-ghost:hover{
  background:rgba(255,255,255,.14);border-color:#fff;color:#fff}

/* ---------- hero (dark, by design) ---------- */
.hero{position:relative;min-height:min(88vh,780px);display:flex;align-items:flex-end;
  padding:110px 0 64px;overflow:hidden;background:var(--navy-3)}
.hero-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 55%}
.hero-scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(11,32,56,.70),rgba(11,32,56,.52) 40%,rgba(11,32,56,.94)),
             radial-gradient(120% 80% at 12% 62%,rgba(11,32,56,.60),transparent 62%)}
.hero-in{position:relative}
.hero h1,.hero .lede{color:#fff}
.hero .lede{max-width:60ch}
.hero .kicker{color:#9FD3F5}
.proof{list-style:none;display:flex;gap:44px;flex-wrap:wrap;padding:0;margin:36px 0 0;
  border-top:1px solid rgba(255,255,255,.22);padding-top:22px}
.proof b{display:block;font-size:clamp(30px,3.4vw,38px);color:var(--green);line-height:1.1;
  font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.proof span{font-size:16px;color:rgba(255,255,255,.78)}

/* ---------- page header (dark photo band) ---------- */
.phead{position:relative;padding:96px 0 clamp(56px,6vw,84px);overflow:hidden;background:var(--navy-2)}
.phead-media{position:absolute;inset:0}
.phead-media img{width:100%;height:100%;object-fit:cover}
.phead-media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(15,42,71,.86),rgba(15,42,71,.72) 45%,rgba(15,42,71,.92))}
.phead .wrap{position:relative}
.phead h1,.phead .lede{color:#fff}
.phead .kicker{color:#9FD3F5}

/* ---------- sections ---------- */
.sec{padding:var(--s) 0;background:var(--paper)}
.sec-lift{background:var(--tint);border-block:1px solid var(--line)}
.sec h2{margin-bottom:6px}
.sec + .sec{padding-top:calc(var(--s) * .6)}

/* ---------- service cards ---------- */
.sgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:18px;margin-top:40px}
.scard{display:flex;flex-direction:column;text-decoration:none;border:1px solid var(--line);
  border-radius:14px;padding:26px 24px;background:var(--paper);box-shadow:var(--shadow);transition:.22s}
.scard:hover{border-color:#BFDCF0;box-shadow:var(--shadow-h);transform:translateY(-3px)}
.scard h3{margin:14px 0 8px}
.stag{color:var(--body);font-size:16px;margin:0 0 14px}
.sprice{color:var(--blue-dk);font-weight:600;font-size:17px;margin:auto 0 0}
.sloc{color:var(--muted);font-size:16px;margin:8px 0 0}
/* The sq ft qualifier and the per-size price tiers, both asked for by Bo on
   2026-09-22 because the live Google ads quote them and the page did not.
   16px floor, like everything else here. */
.ssize{color:var(--muted);font-size:16px;margin:4px 0 0}
.stier{display:flex;justify-content:space-between;gap:12px;font-size:16px;
  color:var(--body);margin:0;padding:7px 0;border-bottom:1px solid var(--line)}
.stier:first-of-type{margin-top:10px;border-top:1px solid var(--line)}
.stier:last-of-type{border-bottom:0}
.stier span{color:var(--muted)}
.stiernote{color:var(--muted);font-size:16px;margin:10px 0 0;line-height:1.45}
.ic{width:26px;height:26px;color:var(--blue);stroke-width:2}

/* ---------- location cards ---------- */
.lgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:22px;margin-top:40px}
.lcard{display:flex;flex-direction:column;text-decoration:none;border:1px solid var(--line);
  border-radius:14px;overflow:hidden;background:var(--paper);box-shadow:var(--shadow);transition:.22s}
.lcard:hover{border-color:#BFDCF0;box-shadow:var(--shadow-h);transform:translateY(-3px)}
.lcard img{width:100%;aspect-ratio:3/2;object-fit:cover}
.lcard-in{padding:20px 22px 24px;display:flex;flex-direction:column;gap:9px;flex:1}
.lcard-in h3{margin:0}
.lcard-in p{color:var(--body);font-size:16px;margin:0}
.badge{display:inline-block;align-self:flex-start;background:#EDF6E3;color:#3F7A21;
  font-size:16px;font-weight:600;padding:4px 12px;border-radius:999px}

/* address card, used on service pages where a photo would just repeat */
.acard-loc{display:flex;flex-direction:column;gap:10px;text-decoration:none;
  border:1px solid var(--line);border-radius:14px;padding:26px 24px;background:var(--paper);
  box-shadow:var(--shadow);transition:.22s}
.acard-loc:hover{border-color:#BFDCF0;box-shadow:var(--shadow-h);transform:translateY(-3px)}
.acard-loc h3{margin:0}
.acard-loc p{color:var(--body);font-size:16px;margin:0}
.acard-loc .go{margin-top:auto;padding-top:6px;color:var(--blue-dk);font-weight:600;font-size:16px}
.acard-loc:hover .go{text-decoration:underline;text-underline-offset:3px}

/* bookable meeting rooms, one card per real room with its own reserve link */
.rgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(288px,1fr));gap:18px;margin-top:36px}
.rcard{display:flex;flex-direction:column;gap:6px;border:1px solid var(--line);border-radius:14px;
  padding:24px;background:var(--paper);box-shadow:var(--shadow);transition:.22s}
.rcard:hover{border-color:#BFDCF0;box-shadow:var(--shadow-h);transform:translateY(-3px)}
.rcard-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.rcard-top h3{margin:0}
.rrate{color:var(--blue-dk);font-weight:700;font-size:17px;white-space:nowrap}
.rmeta{color:var(--body);font-size:16px;margin:0}
.rcard .btn{align-self:flex-start;margin-top:14px}

/* ---------- amenities ---------- */
.agrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(244px,1fr));gap:20px 24px;margin-top:40px}
.acard{border-top:2px solid var(--line);padding-top:20px}
.acard h3{margin:12px 0 7px;font-size:18px}
.acard p{color:var(--body);font-size:16px;margin:0}

.chips{display:flex;flex-wrap:wrap;gap:10px;margin-top:32px}
.chip{border:1px solid var(--line);border-radius:999px;padding:9px 18px;font-size:16px;
  color:var(--navy);background:var(--paper)}

/* ---------- matterport tours ---------- */
.ttabs{display:flex;gap:10px;flex-wrap:wrap;margin:34px 0 18px}
.ttab{background:var(--paper);border:1px solid var(--line);color:var(--navy);border-radius:999px;
  padding:11px 20px;font-size:16px;font-family:inherit;cursor:pointer;transition:.2s}
.ttab:hover{border-color:var(--blue);color:var(--blue-dk)}
.ttab.on{background:var(--blue);border-color:var(--blue);color:#fff;font-weight:600}
.tours{position:relative;border:1px solid var(--line);border-radius:14px;overflow:hidden;
  background:var(--navy-3);box-shadow:var(--shadow)}
.tframe{display:none}
.tframe.on{display:block}
.tframe iframe{width:100%;height:min(68vh,600px);border:0;display:block}

/* ---------- booking ---------- */
.steps{list-style:none;padding:0;margin:34px 0 28px;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:18px}
.steps li{border-left:3px solid var(--blue);padding:2px 0 2px 18px}
.steps b{display:block;margin-bottom:5px;color:var(--navy)}
.steps span{color:var(--body);font-size:16px}
.book-frame{border:1px solid var(--line);border-radius:14px;overflow:hidden;
  background:var(--paper);box-shadow:var(--shadow);min-height:640px}
.book-frame iframe{width:100%;height:660px;border:0;display:block}

/* their FlexEngine contact widget. Fixed height on purpose: the auto-sizing script
   breaks the booking widget (see the note in gen.py), so both frames carry a measured
   height instead. 780px clears the six fields plus the consent paragraph at this width. */
.form-frame{border:1px solid var(--line);border-radius:14px;overflow:hidden;
  background:var(--paper);box-shadow:var(--shadow);margin-top:34px;max-width:720px}
/* Erring tall on purpose: .form-frame is overflow:hidden, so a frame that is too
   short would clip the CONTACT US button and make the form unusable. A little
   whitespace is the safe side of that trade. */
.form-frame iframe{width:100%;height:700px;border:0;display:block}
@media (max-width:600px){.form-frame iframe{height:940px}}

/* ---------- closing band (dark, by design) ---------- */
.cta{background:var(--navy);padding:var(--s) 0}
.cta-in{text-align:center;max-width:720px;margin-inline:auto}
.cta h2{color:#fff}
.cta .lede{color:rgba(255,255,255,.86);margin-inline:auto}
.cta-in .cta-row{justify-content:center}

/* ---------- contact ---------- */
.contact-in{display:grid;grid-template-columns:1fr 1fr;gap:44px}
.fh{font-size:16px;letter-spacing:.13em;text-transform:uppercase;color:var(--blue-dk);
  font-weight:600;margin:24px 0 8px}
.fh:first-child{margin-top:0}
.big{font-size:22px;font-weight:600;color:var(--navy)}
.big a,.contact-in a{text-decoration:none}
.contact-in p{color:var(--body)}

/* ---------- footer (dark, by design) ---------- */
.foot{background:var(--navy-2);color:rgba(255,255,255,.80);padding:64px 0 0}
.foot-in{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:36px}
.foot .fh{color:#fff;margin-top:0}
.foot-brand img{height:40px;width:auto;margin-bottom:14px}
.foot-brand{margin-bottom:12px}
.foot a{color:rgba(255,255,255,.80);text-decoration:none;font-size:16px}
.foot a:hover{color:#fff;text-decoration:underline;text-underline-offset:3px}
.foot p{font-size:16px;color:rgba(255,255,255,.80)}
.foot .muted{color:rgba(255,255,255,.66)}
.foot b{color:#fff;font-weight:600}
.foot-base{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border-top:1px solid rgba(255,255,255,.16);margin-top:50px;padding:20px 0}
.foot-base p{margin:0;color:rgba(255,255,255,.66)}
.foot-legal{display:flex;gap:18px;flex-wrap:wrap}

/* ---------- member video reviews ---------- */
/* Cards are flex so a two-line name can never leave a black gap under a
   shorter neighbour, which is what the old five-across grid was doing. */
/* 320px floor gives exactly 3 columns at the 1200px wrap (3x320+2x22 fits, 4 does not),
   so each clip lands near 385px instead of the 285px a 4-across grid was giving. Drops
   to 2 on tablet and 1 on phone on its own, no media query needed. */
.vgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:22px;margin-top:40px}
/* margin:0 is load-bearing. .vcard is a <figure>, and the UA default margin is
   1em 40px, so every card was silently 80px narrower than its own grid column. */
.vcard{margin:0;display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;
  overflow:hidden;background:var(--paper);box-shadow:var(--shadow)}
.vcard iframe{width:100%;aspect-ratio:16/9;border:0;display:block;background:#000}
.vcard figcaption{padding:13px 15px;font-size:16px;color:var(--navy);font-weight:600;
  display:flex;justify-content:space-between;gap:10px;align-items:center;margin-top:auto}
.vcard figcaption span{color:var(--muted);font-size:16px;font-weight:400;flex:none}

/* ---------- google reviews ---------- */
.tgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:22px;margin-top:36px}
.tcard{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;
  padding:26px 26px 24px;background:var(--paper);box-shadow:var(--shadow);margin:0}
.tcard p{color:var(--body);margin:0 0 16px;font-size:16px;line-height:1.68}
.tcard cite{color:var(--navy);font-style:normal;font-size:16px;font-weight:600;
  display:block;margin-top:auto;padding-top:4px}
.stars{color:#F5A623;letter-spacing:.14em;font-size:16px;margin:0 0 12px}
.glogo{width:22px;height:22px;display:block;margin-bottom:14px}

/* ---------- legal pages ---------- */
.legal h2{font-size:21px;margin:38px 0 12px;color:var(--navy)}
.legal h2:first-child{margin-top:0}
.legal p{font-size:16px;line-height:1.72;color:var(--body)}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(22px)}
.no-motion .rv,.rv.in{opacity:1;transform:none}

@media (max-width:940px){
  .nav-links,.nav .btn-sm{display:none}
  .burger{display:block}
  .drawer[data-open]{display:flex;flex-direction:column;gap:16px;padding:20px;
    border-top:1px solid var(--line);background:var(--paper)}
  .drawer a{text-decoration:none;color:var(--navy);font-size:17px;font-weight:500}
  .drawer .btn{text-align:center}
  .contact-in,.foot-in{grid-template-columns:1fr 1fr}
}
@media (max-width:600px){
  .contact-in,.foot-in{grid-template-columns:1fr}
  .proof{gap:26px}
  .tframe iframe{height:clamp(320px,54vh,470px)}
  .foot-base{flex-direction:column;gap:10px}
}
@media (prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none}
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
  html{scroll-behavior:auto}
}

/* buyable plan tiers, each linking to the real FlexSpace offering */
.pgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:18px;margin-top:34px}
.pcard{display:flex;flex-direction:column;gap:5px;border:1px solid var(--line);border-radius:14px;
  padding:24px;background:var(--paper);box-shadow:var(--shadow);transition:.22s}
.pcard:hover{border-color:#BFDCF0;box-shadow:var(--shadow-h);transform:translateY(-3px)}
.pcard h3{margin:0}
.pprice{color:var(--blue-dk);font-weight:700;font-size:22px;margin:0}
.pnote{color:var(--body);font-size:16px;margin:0}
.pcard .btn{align-self:flex-start;margin-top:auto;padding-top:9px}

/* Locations submenu, matching their live nav. Hover on pointer devices, and it stays
   open while the cursor travels into it because the wrapper owns the hover, not the link. */
.has-sub{position:relative;display:inline-flex;align-items:center}
.has-sub > a{display:inline-flex;align-items:center;gap:5px}
.has-sub > a svg{width:15px;height:15px;transition:transform .2s}
.has-sub:hover > a svg{transform:rotate(180deg)}
.submenu{position:absolute;top:100%;left:-14px;min-width:196px;background:var(--paper);
  border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-h);
  padding:7px;display:none;flex-direction:column;z-index:60}
.has-sub:hover .submenu,.has-sub:focus-within .submenu{display:flex}
.submenu a{display:block;padding:9px 12px;border-radius:8px;border:0;text-decoration:none;
  color:var(--navy);font-size:16px;font-weight:500;white-space:nowrap}
.submenu a:hover{background:var(--tint);color:var(--blue-dk)}
.drawer-sub{padding-left:16px;color:var(--body) !important;font-weight:400 !important}

/* Footer links were rendering 21px tall on a phone, stacked, with no padding between
   them. That is well under a comfortable tap target and adjacent rows are easy to
   mis-hit. inline-block keeps the existing <br> layout intact while the padding gives
   each link real height. */
.foot a{display:inline-block;padding:6px 0;line-height:1.45}
.foot-legal a{padding:8px 0}
@media (max-width:600px){
  .foot a{padding:9px 0}
  .foot-base{gap:4px}
}

/* Member videos: swipe strip on phones.
   Eight clips stacked one-up were adding roughly 1,700px to the home page. This is a
   user-driven scroll with snap points, NOT an auto-running marquee. The strip bleeds to
   the screen edges so the next card peeks in and the affordance is obvious without a
   label telling people to swipe. Desktop keeps the three-across grid untouched. */
@media (max-width:760px){
  .vgrid{
    display:flex;
    grid-template-columns:none;
    gap:14px;
    overflow-x:auto;
    overflow-y:hidden;
    scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    scroll-padding-left:20px;
    /* bleed past the wrap so cards run to the edge, then pad back so the first card
       lines up with the copy above it */
    margin-inline:-20px;
    padding:2px 20px 14px;
    scrollbar-width:thin;
  }
  .vgrid > .vcard{
    /* 78% on a phone so the next card peeks. Capped at 330px so a wide phone or small
       tablet shows two and a bit, rather than one enormous card. */
    flex:0 0 min(78%,330px);
    scroll-snap-align:start;
  }
  .vgrid::-webkit-scrollbar{height:5px}
  .vgrid::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
  .vgrid::-webkit-scrollbar-track{background:transparent}
}


/* Location pages: the live site shows a photo for every way to work, ours showed
   an icon on a bare card. The photos were already in assets/img and every service
   already carried one in model.json, so this only surfaces them. */
.scard-photo{padding:0;overflow:hidden}
.scard-photo img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;object-position:center;display:block;border-bottom:1px solid var(--line)}
.scard-photo .scard-body{padding:22px 24px 26px;display:flex;flex-direction:column;flex:1}
.scard-photo .scard-body h3{margin:12px 0 8px}
.scard-photo .sprice{margin:auto 0 0}
@media (max-width:640px){.scard-photo img{aspect-ratio:16/9}}

/* Full amenity cards. Bo asked for the photo and the outbound hyperlink back:
   the rebuild had reduced 22 published amenities to an 8 item icon grid. */
.adet{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:28px;margin-top:44px}
.acard-full{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;
  overflow:hidden;background:#fff;box-shadow:var(--shadow)}
.acard-full img{width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;display:block;
  border-bottom:1px solid var(--line)}
.acard-full .acard-body{padding:22px 24px 24px;display:flex;flex-direction:column;flex:1;gap:10px}
.acard-full h3{margin:0;font-size:20px;line-height:1.3}
.acard-full p{margin:0;color:var(--body);font-size:16px;line-height:1.6}
.acard-full a{color:var(--blue-dk);text-decoration:underline;text-underline-offset:2px}
.acard-full a:hover{text-decoration-thickness:2px}
.aval{margin-top:auto;padding-top:6px;font-size:16px;font-weight:600;color:var(--blue-dk)}
@media (max-width:640px){.adet{grid-template-columns:1fr;gap:22px}}

/* Shown only when the booking widget fails to arrive. See gen.py BOOK_FALLBACK.
   flexeng.in and leadconnectorhq.com sit on common ad and privacy blocklists, and
   a blocked widget leaves an empty box on the one page whose whole job is booking. */
.book-fallback{padding:48px 32px;text-align:center;max-width:52ch;margin:0 auto}
.book-fallback h3{font-size:22px;color:var(--navy);margin:0 0 10px}
.book-fallback p{font-size:16px;color:var(--body);margin:0 0 18px;line-height:1.6}
.book-fallback-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
/* The frame keeps a 640px min-height for the widget it expected; once we know
   nothing is coming, that is 640px of blank box above the fold. */
/* ⚠️ DO NOT PUT display:none BACK ON THIS IFRAME. It used to, and a hidden
   iframe can never load, so the fallback it triggered became permanent. The
   panel now sits above the frame and the frame stays in the layout, so a
   widget that arrives late still replaces the message. */
.book-frame-blocked{min-height:0}
.book-frame-blocked iframe{height:0;border:0}

/* Jump straight to a building. Bo asked for fewer clicks to reach the three
   locations, so the choice the group widget used to ask for inside the iframe
   is made here instead, in one press. 16px floor holds: these are 1rem. */
.loc-picks{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;
  margin:0 0 18px}
.loc-picks-l{font-weight:600;font-size:1rem;line-height:1.4;font-family:inherit;
  color:var(--muted,#5b6b63)}
.loc-picks-b{display:flex;flex-wrap:wrap;gap:9px}
.loc-pick{font-weight:600;font-size:1rem;line-height:1;font-family:inherit;
  padding:12px 18px;border-radius:999px;
  border:1px solid var(--line,#dfe6e1);background:#fff;color:inherit;
  cursor:pointer;min-height:44px;
  transition:background .18s,border-color .18s,color .18s}
.loc-pick:hover{border-color:currentColor}
.loc-pick.on{background:var(--green,#1f7a5a);border-color:var(--green,#1f7a5a);
  color:#fff}
.loc-pick:focus-visible{outline:3px solid var(--green,#1f7a5a);outline-offset:2px}
@media(max-width:560px){.loc-picks-b{width:100%}.loc-pick{flex:1 1 auto}}

/* The how-to sits BELOW the calendar. Bo 2026-09-24: "a working booking
   calendar above the fold, no scrolling past a long hero or how-to first."
   With the list above it the calendar began at 932px on an 844px phone. */
.steps-after{margin-top:28px}

/* The Westshore only offer. Bo 2026-09-25: it must not appear on any shared
   surface or on Lutz / Wesley Chapel, so it renders from the location's own
   promo_note and nowhere else. */
.promo-note{background:var(--tint);border-left:4px solid var(--blue);
  padding:18px 22px;border-radius:0 10px 10px 0;margin:0;font-size:1.0625rem;line-height:1.55}

/* ---------------------------------------------------------------- Westshore
   Bo's /locations/tampa copy and the sitewide /faq, 2026-09-25.

   .rows / .row-i were emitted by the location "extra_sections" path since
   2026-09-22 with NO rule anywhere in this file, so the four product lines Bo
   asked for rendered as unstyled divs on the live page and nothing flagged it.
   qa.py now fails the build on a class the CSS never defines. Every font size
   below is at or above 1rem. */
.rows{display:grid;gap:18px;margin-top:26px}
.row-i{padding:22px 24px;border:1px solid var(--line);border-radius:12px;
  background:var(--paper)}
.row-i h3{margin:0 0 8px;font-size:1.25rem;line-height:1.3}
.row-i p{margin:0;font-size:1rem;line-height:1.6;color:var(--body)}

.ws-h3{margin:30px 0 12px;font-size:1.1875rem;line-height:1.3}
.ws-note{margin:16px 0 0;font-size:1rem;line-height:1.65;color:var(--body);max-width:72ch}
.wslist{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.wslist li{position:relative;padding-left:30px;font-size:1rem;line-height:1.6;
  color:var(--body)}
.wslist li::before{content:"";position:absolute;left:8px;top:.58em;width:7px;height:7px;
  border-radius:50%;background:var(--teal)}
@media(min-width:760px){.wslist-2{grid-template-columns:1fr 1fr;gap:11px 34px}}

.ws-tablewrap{margin:26px 0 0;overflow-x:auto}
.ws-table{border-collapse:collapse;width:100%;max-width:520px;font-size:1rem}
.ws-table th,.ws-table td{text-align:left;padding:14px 18px;
  border-bottom:1px solid var(--line);line-height:1.4}
.ws-table thead th{font-size:1rem;letter-spacing:.02em;color:var(--muted);
  font-weight:600;border-bottom:2px solid var(--line)}
.ws-table tbody th{font-weight:600;color:inherit}
.ws-table tbody td{font-variant-numeric:tabular-nums;white-space:nowrap}

/* A long amenity list twice on one page is noise, so it collapses. It stays in
   the markup, so it is still indexed and still reachable by keyboard. */
.ws-amen{margin:22px 0 0;border:1px solid var(--line);border-radius:12px;
  background:var(--paper)}
.ws-amen>summary{cursor:pointer;padding:16px 20px;font-weight:600;font-size:1rem;
  line-height:1.45;list-style:none}
.ws-amen>summary::-webkit-details-marker{display:none}
.ws-amen>summary::after{content:"+";float:right;font-weight:600;color:var(--blue);display:inline-block;transition:transform .2s}
.ws-amen[open]>summary::after{transform:rotate(45deg)}
.ws-amen[open]>summary{border-bottom:1px solid var(--line)}
.ws-amen>.wslist{padding:18px 20px 22px}
.ws-amen>summary:focus-visible{outline:3px solid var(--blue);outline-offset:2px}

.faq{margin-top:26px;border-top:1px solid var(--line)}
.faq-i{border-bottom:1px solid var(--line)}
.faq-i>summary{cursor:pointer;padding:20px 44px 20px 0;position:relative;
  font-weight:600;font-size:1.0625rem;line-height:1.45;list-style:none}
.faq-i>summary::-webkit-details-marker{display:none}
.faq-i>summary::after{content:"+";position:absolute;right:8px;top:19px;display:inline-block;transition:transform .2s;
  font-size:1.25rem;font-weight:600;color:var(--blue)}
.faq-i[open]>summary::after{transform:rotate(45deg)}
.faq-i>summary:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.faq-a{padding:0 44px 22px 0;max-width:74ch}
.faq-a p{margin:0 0 12px;font-size:1rem;line-height:1.68;color:var(--body)}
.faq-a p:last-child{margin-bottom:0}

/* A few of Bo's answers end in a colon and then list items. They are rendered as
   a real list rather than a column of loose paragraphs, which is what 16 flat
   amenity lines looked like. The schema still joins the same words in the same
   order, so the visible answer and the FAQPage text still match. */
.faq-a .wslist{margin:14px 0 4px}
.faq-a .wslist li{font-size:1rem;line-height:1.6}
