/* ============================================================
   Dream Charters ATX — Design System
   Mobile-first. WCAG AA contrast on all text + buttons.

   COLOR RULES (do not break these):
   - --brand (#147EFE) is the logo blue. It is ONLY 3.86:1 on white,
     so it must NEVER carry white text as a solid button fill.
     Use it for graphics, icons, and text sitting ON dark surfaces.
   - Solid buttons + links on light backgrounds use --action (5.90:1).
   - --accent-light is the accent for dark surfaces (6.66:1 on --navy).
   - --border is decorative only. Form fields + focus rings use
     --border-input, which clears 3:1 against white.
   Colors below that are not a token are either pure white/black
   neutrals at alpha, or a token expressed at alpha (noted inline).
   ============================================================ */

:root{
  /* ---- The palette. Every color in this file derives from these. ---- */
  --brand:        #147EFE;  /* logo blue — graphics/icons/text on dark. NOT a button fill */
  --action:       #0A5FD0;  /* solid buttons + links on light bg (5.90:1 w/ white) */
  --action-hover: #0B4EA8;  /* (7.87:1 w/ white) */
  --accent-light: #4DA3FF;  /* accent on dark bg (6.66:1 on --navy) */
  --navy:         #0B1A2E;  /* dark sections, nav, footer */
  --text:         #0B1A2E;  /* body text on light (17.48:1) */
  --text-muted:   #4A5C72;  /* secondary text (6.85:1 on white) */
  --surface:      #FFFFFF;
  --surface-alt:  #F3F6FA;  /* off-white sections, chips, wells */
  --border:       #DCE4ED;  /* decorative dividers only */
  --border-input: #6B7F94;  /* form fields + focus rings (4.07:1 on white) */

  /* ---- Semantic ---- */
  /* Rating gold. 9.43:1 on --navy, but only 1.85:1 on white — so star
     glyphs are DECORATIVE everywhere: every cluster is aria-hidden and
     paired with an .sr-only text rating. Never let a star be the only
     thing carrying the score. */
  --rating:       #F5B301;
  --success:      #0B6432;  /* white text on it = 7.28:1 */

  /* ---- Non-color primitives ---- */
  --shadow-sm: 0 1px 3px rgba(11,26,46,.10);   /* --navy at alpha */
  --shadow-md: 0 8px 24px rgba(11,26,46,.14);  /* --navy at alpha */
  --shadow-lg: 0 18px 50px rgba(11,26,46,.22); /* --navy at alpha */

  --radius: 14px;
  --radius-lg: 22px;
  --maxw: 1180px;

  --font-head:"Outfit","Segoe UI",system-ui,sans-serif;
  --font-body:"Inter","Segoe UI",system-ui,sans-serif;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family:var(--font-body);
  color:var(--text);
  background:var(--surface);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
h1,h2,h3,h4{font-family:var(--font-head);color:var(--navy);line-height:1.12;margin:0 0 .5em;font-weight:800;letter-spacing:-.01em}
h1{font-size:clamp(2rem,7vw,3.6rem)}
h2{font-size:clamp(1.6rem,5vw,2.5rem)}
h3{font-size:clamp(1.2rem,3.5vw,1.5rem)}
p{margin:0 0 1rem}
a{color:var(--action);text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%;display:block}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
.section{padding:clamp(60px,9vw,96px) 0}
.section--tight{padding:clamp(36px,6vw,56px) 0}
.bg-soft{background:var(--surface-alt)}
.bg-navy{background:var(--navy);color:#fff}
.bg-navy h1,.bg-navy h2,.bg-navy h3{color:#fff}
.center{text-align:center}
.eyebrow{font-family:var(--font-head);text-transform:uppercase;letter-spacing:.14em;font-size:.8rem;font-weight:700;color:var(--action);margin:0 0 .6rem}
.bg-navy .eyebrow,.hero .eyebrow,.page-hero .eyebrow,.cta-band .eyebrow{color:var(--accent-light)}
.lead{font-size:1.12rem;color:var(--text-muted);max-width:60ch}
.center .lead{margin-left:auto;margin-right:auto}
.bg-navy .lead,.cta-band .lead{color:rgba(255,255,255,.88)}

/* One gold for every star glyph, light surface or dark. Safe because the
   glyphs are decorative — see --rating above. */
.stars{letter-spacing:1px;color:var(--rating)}

/* ---------- Buttons (high contrast, obviously clickable) ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  font-family:var(--font-head);font-weight:700;font-size:1rem;
  padding:.85rem 1.5rem;border-radius:999px;border:2px solid transparent;
  cursor:pointer;transition:transform .12s ease,background .18s ease,box-shadow .18s ease;
  text-decoration:none;line-height:1;white-space:nowrap;
}
.btn:hover{text-decoration:none;transform:translateY(-2px)}
.btn:active{transform:translateY(0) scale(.98)}
.btn:focus-visible{outline:3px solid var(--border-input);outline-offset:2px}
.btn-ghost-light:focus-visible,.text-fab:focus-visible{outline-color:rgba(255,255,255,.8)}
/* Solid fill is --action, never --brand: white on --brand is only 3.86:1. */
.btn-primary{background:var(--action);color:#fff;box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--action-hover);color:#fff;box-shadow:0 10px 26px rgba(10,95,208,.35)} /* --action at alpha */
/* On navy the --action fill is only 2.96:1 against the background, so the
   button gets an --accent-light edge (6.66:1) to define its shape. */
.nav .btn-primary,.hero .btn-primary,.page-hero .btn-primary,
.bg-navy .btn-primary,.cta-band .btn-primary,.footer .btn-primary{border-color:var(--accent-light)}
.btn-secondary{background:#fff;color:var(--navy);border-color:var(--navy)}
.btn-secondary:hover{background:var(--navy);color:#fff}
.btn-ghost-light{background:rgba(255,255,255,.12);color:#fff;border-color:#fff}
.btn-ghost-light:hover{background:#fff;color:var(--navy)}
.btn-lg{font-size:1.08rem;padding:1rem 1.9rem}
.btn-block{width:100%}
/* Long labels ("Read all 74 reviews on Google", "Book your day on the water")
   have an intrinsic one-line width of ~360px. With .btn's white-space:nowrap
   they could not shrink, so they punched out of the viewport on phones
   (reviews.html overflowed at 320/360/375, gallery.html at 320). max-width is
   a hard backstop; the wrap is scoped to narrow screens so shrink-to-fit keeps
   every button on one line at 430px and up — desktop is unchanged. */
.btn{max-width:100%}
@media(max-width:429px){.btn{white-space:normal;line-height:1.25}}

/* ---------- Sticky nav ---------- */
.nav{position:sticky;top:0;z-index:50;background:var(--navy);box-shadow:0 2px 12px rgba(11,26,46,.28);transition:box-shadow .25s ease}
.nav--scrolled{box-shadow:0 8px 28px rgba(11,26,46,.45)}
.nav__inner{display:flex;align-items:center;justify-content:space-between;gap:1rem;height:66px}
.brand{display:flex;align-items:center;gap:.6rem;text-decoration:none}
.brand:hover{text-decoration:none}
.brand__name{font-family:var(--font-head);font-weight:800;color:#fff;font-size:1.15rem;letter-spacing:.01em;line-height:1}
.brand__name small{display:block;font-size:.62rem;font-weight:600;letter-spacing:.22em;color:rgba(255,255,255,.72);margin-top:2px}
.nav__links{display:none}
/* nowrap: multi-word labels ("Contact Us", "Waiver Form") must never break
   across two lines — that deforms the bar. The list is 8 items wide now, so
   it only unhides once there is genuinely room for it (see breakpoint below). */
.nav__links a{color:rgba(255,255,255,.86);font-family:var(--font-head);font-weight:600;font-size:.95rem;padding:.4rem 0;position:relative;white-space:nowrap}
.nav__links a::after{content:"";position:absolute;left:0;right:0;bottom:-4px;height:2px;background:var(--accent-light);transform:scaleX(0);transform-origin:left;transition:transform .22s ease}
.nav__links a:hover{color:#fff;text-decoration:none}
.nav__links a:hover::after{transform:scaleX(1)}
.nav__links a.active{color:#fff}
.nav__links a.active::after{transform:scaleX(1)}
.nav__cta{display:flex;align-items:center;gap:.5rem}
.nav__burger{display:inline-flex;flex-direction:column;gap:4px;background:none;border:0;cursor:pointer;padding:8px}
.nav__burger span{width:24px;height:2px;background:#fff;border-radius:2px;transition:.2s}
.nav__mobile{display:none;flex-direction:column;background:var(--navy);border-top:1px solid rgba(255,255,255,.14)}
.nav__mobile.open{display:flex;animation:menuDown .22s ease both}
@keyframes menuDown{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.nav__mobile a{color:rgba(255,255,255,.9);font-family:var(--font-head);font-weight:600;padding:14px 20px;border-bottom:1px solid rgba(255,255,255,.08)}
.nav__mobile a:hover{background:rgba(255,255,255,.06);text-decoration:none}
.nav__mobile a.active{color:var(--accent-light)}
/* width:auto cancels .btn-block's width:100% here. In the drawer the button
   also carries a 20px side margin (to line its edges up with the 20px padding
   on the text links above it), and margins sit OUTSIDE the border box — so
   100% + 20 + 20 rendered 40px wider than the drawer and pushed the document
   20px past the viewport. The drawer is a column flexbox, so width:auto lets
   the button stretch to the drawer minus its own margins, with no hardcoded
   gutter math to keep in sync. */
.nav__mobile .btn{margin:14px 20px;width:auto}
/* .nav__mobile a (0,1,1) outranks .btn-secondary (0,1,0), so the white nav-link
   colour was landing on the secondary button's white background and rendering
   the label invisible. Restate it at (0,2,1). Only .btn-secondary needs this —
   .btn-primary is white-on-blue and reads correctly. */
.nav__mobile a.btn-secondary{color:var(--navy)}

/* Eight text links + logo + wordmark + Book Now does not fit at 960px — the
   labels wrapped and the bar deformed. The burger now holds until there is
   real room, and the gap opens up again on wide screens. */
/* Measured: the 8-link bar + logo + wordmark + Book Now needs 945px. 1024
   gives ~79px of slack and keeps the full nav on standard laptops; below it
   the burger takes over. (Was 960px, which fit 7 shorter labels.) */
@media(min-width:1024px){
  .nav__links{display:flex;gap:1.15rem;align-items:center}
  .nav__burger{display:none}
  .nav__mobile{display:none !important}
}
@media(min-width:1200px){
  .nav__links{gap:1.5rem}
}

/* ---------- Logo ----------
   True-alpha PNG sitting directly on the background — no chip.
   Nav and footer are both --navy, so both use the white lockup.
   The mark is 1.85:1, noticeably wider than the 44px chip it replaced, so
   below 480px the nav shows the mark alone and drops the wordmark — the
   img alt still carries "Dream Charters ATX", so nothing is lost to AT.
   The footer has room, so it keeps the full lockup at every width. */
.brand__logo{height:36px;width:auto;flex:0 0 auto;display:block}
@media(min-width:640px){.brand__logo{height:42px}}
.nav .brand__name{display:none}
@media(min-width:480px){.nav .brand__name{display:block}}
@media(max-width:479px){.nav__cta .btn{padding:.75rem 1.1rem;font-size:.95rem}}

/* ---------- Hero ---------- */
.hero{position:relative;min-height:86vh;display:flex;align-items:flex-end;color:#fff;overflow:hidden}
.hero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  animation:heroZoom 18s ease-out both;transform-origin:center 60%}
@keyframes heroZoom{from{transform:scale(1.08)}to{transform:scale(1)}}
.hero::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(11,26,46,.42) 0%,rgba(11,26,46,.18) 42%,rgba(11,26,46,.62) 74%,rgba(11,26,46,.92) 100%)}
.hero__content{position:relative;z-index:2;padding:0 20px 64px;max-width:var(--maxw);margin:0 auto;width:100%}
/* Scrim anchored to the content block, not to a fixed % of the hero, so it follows
   the text as the block grows taller on narrow screens. Keeps the all-caps H1 above
   WCAG AA over the bright sky (mobile) and the boat's pale upholstery (desktop). */
.hero__content::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  left:calc(50% - 50vw);right:calc(50% - 50vw);top:-72px;bottom:0;
  background:linear-gradient(180deg,rgba(11,26,46,0) 0%,rgba(11,26,46,.24) 8%,rgba(11,26,46,.46) 20%,rgba(11,26,46,.54) 100%)}
.rating-pill{display:inline-flex;align-items:center;gap:.5rem;background:rgba(11,26,46,.62);backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.28);border-radius:999px;padding:.45rem 1rem;margin-bottom:1rem;
  font-family:var(--font-head);font-weight:600;font-size:.9rem;color:#fff}
/* All-caps hero headline. Deliberately set on --font-body (Inter), not the
   --font-head display face (Outfit) the other headings use: at hero size the
   heavy display caps read as shouty, and Inter is already loaded so this costs
   no extra font request. Weight 600, not the 800 the h1..h4 rule sets.
   Sized well below the global h1 clamp so the photograph carries the hero and
   the words sit on top of it.
   17em fits "YOUR PREFERRED AUSTIN, TEXAS" on one line on desktop; because that
   cap is in em it tracks the font-size, so the break points survive a size
   change. The nowrap spans mean it can only ever break after "PREFERRED" or
   after "TEXAS", never mid-phrase. At 320px the widest span ("YOUR PREFERRED")
   measured 278px inside a 280px content box at the old size — 2px of clearance,
   i.e. one rounding error away from clipping, which is what the old bug report
   was seeing. It now measures 219px in that same box (61px clear), so the
   margin no longer depends on which font actually loaded. */
.hero h1{color:#fff;text-shadow:0 2px 24px rgba(0,0,0,.45);max-width:17em;
  font-family:var(--font-body);font-weight:600;font-size:clamp(1.55rem,5.2vw,2.6rem);letter-spacing:0}
.hero h1 span{white-space:nowrap}
.hero__cta{display:flex;flex-wrap:wrap;gap:.8rem}
.page-hero{position:relative;color:#fff;padding:60px 0;background:var(--navy);overflow:hidden}
.page-hero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.42;z-index:0}
.page-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,26,46,.58),rgba(11,26,46,.88));z-index:1}
.page-hero .wrap{position:relative;z-index:2}
.page-hero h1{color:#fff}
.page-hero p{color:rgba(255,255,255,.88);max-width:60ch}

/* ---------- Cards / grids ---------- */
.grid{display:grid;gap:22px}
.grid-2{grid-template-columns:1fr}
.grid-3{grid-template-columns:1fr}
.grid-4{grid-template-columns:1fr}
@media(min-width:640px){.grid-2{grid-template-columns:1fr 1fr}.grid-3{grid-template-columns:1fr 1fr}.grid-4{grid-template-columns:1fr 1fr}}
@media(min-width:960px){.grid-3{grid-template-columns:repeat(3,1fr)}.grid-4{grid-template-columns:repeat(4,1fr)}}

.card{background:#fff;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-sm);transition:transform .22s ease,box-shadow .22s ease,border-color .22s ease;display:flex;flex-direction:column}
.card:hover{transform:translateY(-5px);box-shadow:var(--shadow-lg);border-color:var(--brand)}
.card__img{aspect-ratio:4/3;object-fit:cover;width:100%;background:var(--surface-alt);transition:transform .6s cubic-bezier(.2,.7,.3,1)}
.card:hover .card__img{transform:scale(1.05)}
.card:hover .card__title{color:var(--action)}
.card__title{transition:color .2s ease}
.card__body{padding:18px 18px 20px;display:flex;flex-direction:column;gap:.5rem;flex:1}
.card__title{margin:0;font-size:1.3rem}
.card__meta{display:flex;flex-wrap:wrap;gap:.4rem .9rem;color:var(--text-muted);font-size:.9rem;margin:.1rem 0}
.card__meta b{color:var(--navy)}
.price{font-family:var(--font-head);font-weight:800;color:var(--navy);font-size:1.15rem}
.price small{font-weight:600;color:var(--text-muted);font-size:.8rem}
/* Sits once per page that shows prices — the ranges are unconfirmed, so the
   season/day caveat travels with them. Muted but AA (6.85:1 on white). */
.rate-note{font-size:.85rem;color:var(--text-muted);margin:16px 0 0;max-width:60ch}
.card__foot{margin-top:auto;padding-top:.4rem}

.pill{display:inline-flex;align-items:center;gap:.35rem;background:var(--surface-alt);color:var(--navy);
  font-family:var(--font-head);font-weight:600;font-size:.8rem;padding:.28rem .7rem;border-radius:999px}

/* ---------- Feature / experience cards ---------- */
.feature{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:26px;box-shadow:var(--shadow-sm);height:100%}
.feature__icon{width:52px;height:52px;border-radius:14px;display:flex;align-items:center;justify-content:center;background:var(--surface-alt);color:var(--action);margin-bottom:14px}
.feature h3{margin-bottom:.35rem}
.feature p{color:var(--text-muted);margin:0}

/* ---------- Experience sections (experiences.html) ----------
   ONE component renders all four experiences: identical markup per card, no
   per-section inline styles. The alternation is positional — .xp-list flips
   the image side and the background on even children — so adding, removing or
   reordering an experience needs no class changes and no new CSS.
   scroll-margin-top clears the sticky .nav (66px measured) so a deep link like
   #sunset-cruises lands below the header instead of behind it. */
.xp{scroll-margin-top:88px}
.xp__inner{display:grid;gap:26px;align-items:center}
.xp__media{width:100%}
.xp__chip{margin:0 0 .7rem}
.xp__label{font-family:var(--font-head);font-weight:700;color:var(--navy);
  font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;margin:1.3rem 0 .7rem}
.xp__price{margin:1.4rem 0 0}
.xp__cta{margin-top:1.5rem}
.xp__price + .xp__cta{margin-top:1rem}
.xp-list > .xp:nth-child(even){background:var(--surface-alt)}
@media(min-width:860px){
  .xp__inner{grid-template-columns:1fr 1fr;gap:48px}
  .xp-list > .xp:nth-child(even) .xp__media{order:2}
}

/* ---------- Occasions strip ---------- */
.occasion{position:relative;border-radius:var(--radius);overflow:hidden;min-height:150px;display:flex;align-items:flex-end;color:#fff;padding:18px;background:var(--navy)}
.occasion::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,26,46,.10),rgba(11,26,46,.85))}
.occasion img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.occasion__label{position:relative;z-index:1}
.occasion__label h3{color:#fff;margin:0 0 .2rem;font-size:1.15rem}
.occasion__label span{font-size:.86rem;color:rgba(255,255,255,.85)}

/* ---------- Reviews ---------- */
.review{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:22px;box-shadow:var(--shadow-sm);height:100%;display:flex;flex-direction:column}
.review .stars{letter-spacing:2px;font-size:1.05rem;margin-bottom:.5rem}
.review__img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:10px;margin-bottom:14px;background:var(--surface-alt)}
.review__text{color:var(--text);font-size:1.02rem;margin:0 0 1rem;flex:1}
.review__by{font-family:var(--font-head);font-weight:700;color:var(--navy)}
.review__tag{font-size:.78rem;color:var(--text-muted);font-weight:600}

/* review carousel (home) */
.carousel{position:relative}
.carousel__track{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:8px;-webkit-overflow-scrolling:touch}
.carousel__track::-webkit-scrollbar{height:8px}
.carousel__track::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px}
.carousel__track > *{scroll-snap-align:start;flex:0 0 86%}
@media(min-width:640px){.carousel__track > *{flex:0 0 46%}}
@media(min-width:960px){.carousel__track > *{flex:0 0 31.5%}}

/* filter chips */
.chips{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center;margin-bottom:26px}
.chip{font-family:var(--font-head);font-weight:600;font-size:.9rem;padding:.5rem 1rem;border-radius:999px;border:2px solid var(--navy);background:#fff;color:var(--navy);cursor:pointer;transition:.15s}
.chip:hover{background:var(--surface-alt)}
.chip.active{background:var(--navy);color:#fff}

/* ---------- FAQ accordion ---------- */
.acc{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;background:#fff;box-shadow:var(--shadow-sm)}
.acc__item+ .acc__item{border-top:1px solid var(--border)}
.acc__q{width:100%;text-align:left;background:none;border:0;cursor:pointer;padding:18px 20px;
  font-family:var(--font-head);font-weight:700;font-size:1.08rem;color:var(--navy);
  display:flex;justify-content:space-between;align-items:center;gap:1rem}
.acc__q:hover{background:var(--surface-alt)}
.acc__icon{flex:0 0 auto;width:26px;height:26px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:1.2rem;transition:transform .2s}
.acc__item.open .acc__icon{transform:rotate(45deg)}
.acc__a{max-height:0;overflow:hidden;transition:max-height .25s ease;color:var(--text-muted)}
.acc__a p{padding:0 20px 18px;margin:0}
.acc__item.open .acc__a{max-height:320px}

/* ---------- Included list ---------- */
.included{list-style:none;padding:0;margin:0;display:grid;gap:.7rem}
.included li{display:flex;gap:.7rem;align-items:flex-start;color:var(--text)}
.included svg{flex:0 0 auto;color:var(--action);margin-top:2px}

/* ---------- Spec row ----------
   All four boats carry 4 tiles (guests / lake / minimum / price), but the
   track count is still never hardcoded so a future boat with a different
   tile count can't break the row.
   The hairlines are the container's background showing through a 1px gap
   between opaque tiles — which means a PARTIAL ROW is not just an alignment
   problem, it renders each empty cell as a solid --border block. Because
   auto-fit collapses surplus empty tracks, any track count >= the tile count
   is a clean single row; the only unsafe counts are strictly between 1 and
   the tile count (3 tracks / 4 tiles, or 2 tracks / 3 tiles). So there are
   exactly two safe regimes: one column, or at least 4 tracks.
   4 tracks of minmax(150px,1fr) need 603px of container, i.e. a 643px
   viewport before the gutters — 680px clears that with room for a desktop
   scrollbar, so the grid never lands in the unsafe middle. */
.specs{display:grid;grid-template-columns:1fr;gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}
@media(min-width:680px){.specs{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}}
.spec{background:#fff;padding:18px 16px;text-align:center}
.spec b{display:block;font-family:var(--font-head);font-size:1.3rem;color:var(--navy)}
.spec span{font-size:.82rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em}

/* ---------- Charter package options (boat detail pages) ----------
   Flat package prices, not hourly rates. Duration is the row label because
   that is what the guest picks at booking. The note slot carries the booking
   system's own option name when it differs from the real duration (the
   Centurion's 6 hr 30 min package is listed there as "6hr Centurion Charter").
   Rows wrap price under label below ~420px rather than squeezing both. */
.pkgs{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:1px;background:var(--border);
  border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}
.pkgs li{background:#fff;padding:14px 16px;display:flex;flex-wrap:wrap;gap:.2rem .9rem;align-items:baseline}
.pkg__dur{font-family:var(--font-head);font-weight:700;color:var(--navy);font-size:1.05rem}
.pkg__note{color:var(--text-muted);font-size:.85rem;flex:1 1 100%;order:3}
@media(min-width:420px){.pkg__note{flex:0 1 auto;order:0}}
.pkg__price{font-family:var(--font-head);font-weight:800;color:var(--navy);font-size:1.15rem;margin-left:auto}

/* ---------- Embedded Square booking widget (book.html) ----------
   Cross-origin iframe, so it cannot self-size and the height has to be set
   here. The Square flow is multi-step and grows as you advance (service list →
   calendar → details), so the box is deliberately tall and scrolls internally
   rather than being clipped to the height of the first step. 800px floor, then
   it tracks the viewport on taller screens. width:100% inside the 760px .wrap
   with border-box keeps it off the horizontal axis at every width. The frame
   wrapper means a blocked iframe (privacy extensions) reads as an empty panel
   instead of a hole in the page — the fallback link sits directly below. */
.book-embed__frame{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;background:#fff}
.book-embed{display:block;width:100%;border:0;background:#fff;
  min-height:800px;height:clamp(800px,95vh,1150px)}
.book-embed__fallback{font-size:.92rem;color:var(--text-muted);margin:14px 0 0}

/* ---------- Gallery ---------- */
.gallery{columns:1;column-gap:16px}
@media(min-width:560px){.gallery{columns:2}}
@media(min-width:900px){.gallery{columns:3}}
.gallery img{width:100%;margin:0 0 16px;border-radius:12px;break-inside:avoid;box-shadow:var(--shadow-sm)}
.gallery figure{margin:0 0 16px;break-inside:avoid;position:relative;border-radius:12px;overflow:hidden;box-shadow:var(--shadow-sm)}
.gallery figure img{margin:0;border-radius:0;box-shadow:none;transition:transform .6s cubic-bezier(.2,.7,.3,1)}
.gallery figcaption{font-size:.82rem;color:var(--text-muted);padding:6px 2px}
/* Desktop hover: caption becomes a gradient overlay that slides in */
@media(hover:hover) and (min-width:560px){
  .gallery figcaption{position:absolute;left:0;right:0;bottom:0;margin:0;padding:26px 14px 12px;color:#fff;
    background:linear-gradient(180deg,rgba(11,26,46,0),rgba(11,26,46,.88));font-weight:600;font-family:var(--font-head);
    opacity:0;transform:translateY(8px);transition:opacity .3s ease,transform .3s ease}
  .gallery figure:hover figcaption{opacity:1;transform:none}
  .gallery figure:hover img{transform:scale(1.05)}
}

/* ---------- Forms ---------- */
.form{display:grid;gap:16px;background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);padding:26px;box-shadow:var(--shadow-md)}
.field{display:flex;flex-direction:column;gap:.35rem}
.field label{font-family:var(--font-head);font-weight:600;color:var(--navy);font-size:.92rem}
.field input,.field select,.field textarea{
  font-family:var(--font-body);font-size:1rem;padding:.8rem .9rem;border:1.5px solid var(--border-input);border-radius:10px;color:var(--text);background:#fff}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--action);box-shadow:0 0 0 3px rgba(10,95,208,.22)} /* --action at alpha */
.field textarea{min-height:96px;resize:vertical}
.field--req label::after{content:" *";color:var(--action)}
.form__row{display:grid;gap:16px;grid-template-columns:1fr}
.field input,.field select,.field textarea{width:100%;min-width:0}
@media(min-width:560px){.form__row{grid-template-columns:1fr 1fr}}
.form-note{font-size:.85rem;color:var(--text-muted)}
.form-success{background:var(--success);color:#fff;padding:14px 16px;border-radius:12px;font-family:var(--font-head);font-weight:700}
.text-banner{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;background:var(--surface-alt);border:1px dashed var(--action);border-radius:12px;padding:14px 16px;margin-bottom:6px}
.text-banner b{color:var(--navy);font-family:var(--font-head)}

/* ---------- Embedded WaiverElectronic form (waiver.html) ----------
   Same cross-origin constraint as .book-embed: the frame cannot self-size, so
   the height is set here. This form is longer than the Square flow — the full
   agreement, then ~10 fields, a signature pad and nine acknowledgement
   checkboxes — and it scrolls internally rather than being clipped. The titled
   bar is kept from the old preview so the third-party form still reads as part
   of the site. No radius on the iframe itself: the parent's overflow:hidden
   clips it, which avoids a hairline of --surface-alt at the rounded corners. */
.waiver-frame{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface-alt);box-shadow:var(--shadow-md);overflow:hidden}
.waiver-frame__bar{display:flex;align-items:center;gap:.5rem;padding:12px 16px;background:var(--navy);color:#fff;font-family:var(--font-head);font-weight:600;font-size:.9rem}
.waiver-frame__dots{display:flex;gap:6px}
.waiver-frame__dots i{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.5)}
.waiver-embed{display:block;width:100%;border:0;background:#fff;
  min-height:800px;height:clamp(800px,95vh,1150px)}

/* ---------- CTA band ---------- */
.cta-band{position:relative;color:#fff;text-align:center;overflow:hidden}
.cta-band img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.cta-band::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,26,46,.78),rgba(11,26,46,.92));z-index:1}
.cta-band .wrap{position:relative;z-index:2;padding:64px 20px}
.cta-band h2{color:#fff}
.cta-band .hero__cta{justify-content:center}

/* ---------- Footer ---------- */
.footer{background:var(--navy);color:rgba(255,255,255,.82);padding:56px 0 28px;border-top:3px solid rgba(77,163,255,.35)} /* --accent-light at alpha */
.footer a{color:rgba(255,255,255,.82)}
.footer a:hover{color:#fff}
.footer__grid{display:grid;gap:30px;grid-template-columns:1fr}
@media(min-width:760px){.footer__grid{grid-template-columns:1.4fr 1fr 1fr}}
.footer h4{color:#fff;font-size:1rem;letter-spacing:.04em;margin-bottom:.9rem}
.footer ul{list-style:none;padding:0;margin:0;display:grid;gap:.5rem}
.footer__brand .brand__name{color:#fff}
.footer__socials{display:flex;gap:.6rem;margin-top:14px}
.footer__socials a{width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;color:#fff;transition:transform .18s ease,background .18s ease}
.footer__socials a:hover{background:var(--action);transform:translateY(-3px)}
.footer__bottom{border-top:1px solid rgba(255,255,255,.14);margin-top:40px;padding-top:20px;font-size:.85rem;color:rgba(255,255,255,.72);display:flex;flex-wrap:wrap;gap:.6rem;justify-content:space-between}
.footer__phone{font-family:var(--font-head);font-weight:800;color:#fff;font-size:1.6rem;letter-spacing:.01em}
.footer__phone a{color:#fff}
.footer__phone a:hover{color:var(--accent-light);text-decoration:none}

/* ---------- Floating "Call us" button ----------
   Class name is historical (it was an SMS button until 2026-07-27); it now
   styles the tel: FAB injected by js/layout.js. */
.text-fab{position:fixed;right:16px;bottom:16px;z-index:60;display:inline-flex;align-items:center;gap:.5rem;
  background:var(--action);color:#fff;font-family:var(--font-head);font-weight:700;font-size:.98rem;
  padding:.8rem 1.15rem;border-radius:999px;box-shadow:var(--shadow-lg);border:2px solid #fff;transition:transform .12s ease,background .18s}
.text-fab:hover{background:var(--action-hover);color:#fff;text-decoration:none;transform:translateY(-2px)}
.text-fab svg{flex:0 0 auto}
.text-fab__label{display:none}
@media(min-width:420px){.text-fab__label{display:inline}}

/* ---------- Consistent inline image treatment (split sections) ---------- */
.img-frame{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:var(--radius-lg);
  box-shadow:var(--shadow-md),0 0 0 1px var(--border)}

/* ---------- Scroll reveal (JS adds .reveal, .in when visible) ---------- */
.reveal{opacity:0;transform:translateY(18px);transition:opacity .6s ease,transform .6s cubic-bezier(.2,.7,.3,1)}
.reveal.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
  .hero__img{animation:none}
  .card__img,.gallery figure img{transition:none}
}

/* ---------- Utility ---------- */
/* Visually hidden, still read aloud. Carries the rating text that the
   decorative gold star glyphs are not allowed to carry on their own. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.mt-0{margin-top:0}.mb-0{margin-bottom:0}
.stack>*+*{margin-top:1rem}
.divider{height:1px;background:var(--border);border:0;margin:0}
.note-owner{font-size:0}/* hidden owner markers via html comments only */
