/* ==========================================================================
   THEME TOKENS  (≈ Boatr _BRAND.md, as code)
   Change these per-site to re-skin the entire system. Nothing else should
   hard-code a color, font, or spacing value — always reference a token.
   Matched to live triton-charters.com.
   ========================================================================== */
:root{
  /* Brand */
  --indigo:#2E3B93;      /* primary CTA / brand */
  --indigo-dark:#232d73;
  --navy:#1f2a5e;        /* wordmark / dark sections */
  --ink:#222222;         /* body text */
  --muted:#5b6472;
  --bg:#f6ffff;          /* page background */
  --bg-alt:#eaf4f8;      /* alt section */
  --line:#e2e8ee;
  --white:#ffffff;
  --gold:#f5a623;        /* review stars */
  --teal:#3aa8b8;        /* price figures — the hull colour */
  --sky:#2f7fd4;         /* pricing card link-buttons */
  --navy-deep:#24356f;   /* hero ground behind the photo */
  --navy-mid:#33427f;    /* use-case / boat card ground */
  --ink-soft:#3d4663;    /* card + list body copy */
  --ink-prose:#26304d;   /* long-form article body */
  --tint:#eef2ff;        /* pale blue fills */
  --tint-2:#f2f6ff;      /* pale blue fills, lighter */

  /* Type */
  --font-body:'Cabin',Helvetica,Arial,sans-serif;
  --font-head:'Raleway',Helvetica,Arial,sans-serif;

  /* Shape / layout */
  --radius:6px;
  --shadow:0 8px 30px rgba(31,42,94,.10);
  --maxw:1180px;
}

/* ==========================================================================
   BASE + COMPONENT STYLES  (uses only tokens from tokens.css)
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:var(--font-body);color:var(--ink);background:var(--bg);
  line-height:1.65;font-size:17px;-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
a{color:var(--indigo);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{font-family:var(--font-head);color:var(--navy);line-height:1.15;margin:0 0 .5em;font-weight:800}
h1{font-size:clamp(2.2rem,5vw,4.4rem);color:#fff}
h2{font-size:clamp(1.6rem,3.2vw,2.5rem)}
h3{font-size:1.3rem}
p{margin:0 0 1.1em}
.container{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 22px}
.section{padding:70px 0}
.section--alt{background:var(--bg-alt)}
.section--navy{background:var(--navy);color:#dfe6f5}
.section--navy h2,.section--navy h3{color:#fff}
.center{text-align:center}
.lead{font-size:1.15rem;color:var(--muted);max-width:760px;margin:0 auto 1.5em}
.eyebrow{font-family:var(--font-head);font-weight:700;letter-spacing:2px;text-transform:uppercase;
  color:var(--indigo);font-size:.8rem;margin-bottom:.6em}

.btn{display:inline-block;background:var(--indigo);color:#fff;font-family:var(--font-head);font-weight:700;
  letter-spacing:.3px;padding:14px 30px;border-radius:var(--radius);border:2px solid var(--indigo);
  cursor:pointer;transition:.18s;text-align:center}
.btn:hover{background:var(--indigo-dark);border-color:var(--indigo-dark);text-decoration:none;color:#fff}
.btn--ghost{background:#fff;color:var(--indigo)}
.btn--ghost:hover{background:#fff;color:var(--indigo-dark)}
.btn--lg{padding:17px 40px;font-size:1.1rem}

.topbar{background:var(--navy);color:#cdd8f0;font-size:.86rem}
.topbar .container{display:flex;align-items:center;justify-content:center;gap:26px;padding:8px 22px;flex-wrap:wrap}
.topbar a{color:#cdd8f0}.topbar a:hover{color:#fff}
.topbar .social{display:flex;gap:14px}

.site-header{position:sticky;top:0;z-index:60;background:var(--bg);box-shadow:0 2px 14px rgba(31,42,94,.07)}
.nav{display:flex;align-items:center;justify-content:space-between;padding:14px 22px;max-width:var(--maxw);margin:0 auto;gap:20px}
.nav__logo img{height:52px;width:auto}
.nav__menu{display:flex;align-items:center;gap:26px;list-style:none;margin:0;padding:0}
.nav__menu a{color:var(--navy);font-family:var(--font-head);font-weight:600;font-size:.98rem}
.nav__menu a:hover{color:var(--indigo);text-decoration:none}
.nav__item{position:relative}
.nav__item--has>a::after{content:" \25BE";font-size:.7em;color:var(--muted)}
.nav__sub{position:absolute;top:100%;left:0;background:#fff;box-shadow:var(--shadow);border-radius:var(--radius);
  padding:10px 0;min-width:220px;display:none;z-index:70}
.nav__item--has:hover .nav__sub{display:block}
.nav__item--has:hover::after{content:"";position:absolute;left:0;right:0;top:100%;height:16px}
.nav__sub li{list-style:none}
.nav__sub a{display:block;padding:9px 20px;white-space:nowrap}
.nav__cta{margin-left:6px}
.nav__menu a.btn,.nav__menu a.btn:hover{color:#fff}
.nav__menu a.btn--ghost,.nav__menu a.btn--ghost:hover{color:var(--indigo)}
.nav__toggle{display:none;background:none;border:0;font-size:1.6rem;color:var(--navy);cursor:pointer}

.hero{position:relative;min-height:78vh;display:flex;align-items:center;color:#fff;background-color:var(--navy-deep);
  background-image:var(--hero-veil,linear-gradient(rgba(20,30,70,.5),rgba(20,30,70,.6))),var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)));
  background-size:cover;background-position:center;background-repeat:no-repeat}
.hero__inner{max-width:var(--maxw);margin:0 auto;padding:60px 22px;width:100%}
.hero h1{max-width:15ch;text-shadow:0 3px 18px rgba(0,0,0,.35)}
.hero p{font-size:1.3rem;max-width:640px;color:var(--tint);margin-bottom:1.8em}
.hero__cta{display:flex;gap:16px;flex-wrap:wrap}
.hero__sublinks:not(:has(a:only-child)){display:flex;gap:8px 28px;margin-top:30px;flex-wrap:wrap;
  align-items:baseline;max-width:760px;padding-top:15px;border-top:1px solid rgba(255,255,255,.26);
  background:none;border-radius:0;overflow:visible}
.hero__sublinks:not(:has(a:only-child)) a{flex:0 0 auto;min-width:0;padding:0;text-align:left;
  color:rgba(255,255,255,.88);font-family:var(--font-head);font-size:.95rem;font-weight:600;
  text-shadow:0 1px 8px rgba(0,0,0,.45);border-bottom:1px solid rgba(255,255,255,.28);padding-bottom:2px}
.hero__sublinks:not(:has(a:only-child)) a:hover{color:#fff;border-bottom-color:#fff;
  background:none;text-decoration:none}
/* Opt-in via `"compact": true` on a hero. For pages whose frozen H1 is a
   title-tag-shaped string — "San Diego Harbor Cruises | 2.5 Hour Cruise through
   San Diego Bay!" — the full hero size sets three lines of 60px type that read
   as an article headline. The text cannot change (SEO freeze), so the type
   drops a step and the measure widens enough to hold it in two lines. */
.hero--tight h1{font-size:clamp(1.9rem,3.2vw,2.9rem);max-width:34ch}
.hero--compact{min-height:40vh}
.hero--compact h1{font-size:clamp(2rem,4vw,3.2rem);max-width:22ch}
.hero .crumbs--hero{color:var(--tint);margin-bottom:14px;padding:0;text-shadow:0 1px 8px rgba(0,0,0,.55)}
.hero .crumbs--hero a{color:var(--tint)}
.hero--compact p{font-size:1.1rem;max-width:640px;margin-bottom:0;color:var(--tint)}

.reviews{background:#fff;border-bottom:1px solid var(--line)}
.reviews__head{display:flex;align-items:center;justify-content:center;gap:14px;padding:22px;flex-wrap:wrap}
.reviews__score{font-family:var(--font-head);font-weight:800;color:var(--navy);font-size:1.1rem;text-transform:uppercase;letter-spacing:1px}
.stars{color:var(--gold);letter-spacing:2px;font-size:1.2rem}
.review-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:18px;padding-bottom:10px}
.review-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.review-card .who{font-weight:700;color:var(--navy)}
.review-card .when{color:var(--muted);font-size:.8rem;margin-bottom:8px}
.review-card p{font-size:.92rem;margin:0}

.grid{display:grid;gap:26px}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.feature{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px;box-shadow:var(--shadow)}
.feature h3{color:var(--indigo);margin-bottom:.4em}
.feature p{margin:0;color:var(--muted);font-size:.97rem}
.feature--photo{padding:0;overflow:hidden}
.feature__img{height:210px;background-size:cover;background-position:center}
.feature--photo .feature__body{padding:24px}

/* ===== ARTICLE TEMPLATE (collection:"article") ===== */
.post__hero{position:relative;min-height:46vh;display:flex;align-items:flex-end;color:#fff;background-color:var(--navy-deep);
  background-image:linear-gradient(rgba(20,30,70,.32),rgba(20,30,70,.8)),var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)));
  background-size:cover;background-position:center;background-repeat:no-repeat}
.post__hero-inner{max-width:820px;margin:0 auto;width:100%;padding:52px 22px}
.post__hero h1{font-size:clamp(2rem,4.2vw,3.3rem);max-width:22ch;color:#fff;text-shadow:0 3px 18px rgba(0,0,0,.4)}
.post__hero .crumbs--hero{margin-bottom:14px}
.post__wrap{background:#fff}
.post__body{max-width:760px;margin:0 auto;padding:54px 22px 24px;font-size:1.09rem;line-height:1.75;color:var(--ink-prose)}
.post__body h2{font-size:clamp(1.5rem,2.6vw,1.85rem);margin:1.8em 0 .5em;text-align:left;color:var(--navy)}
.post__body h2:first-child{margin-top:0}
.post__body h3{font-size:1.24rem;margin:1.5em 0 .4em;text-align:left;color:var(--navy)}
.post__body p{margin:0 0 1.15em}
.post__body a{color:var(--indigo);text-decoration:underline;text-underline-offset:2px}
.post__lead{font-size:1.3rem;line-height:1.6;color:var(--navy);font-weight:500;margin-bottom:1.5em}
.post__list{padding-left:22px;margin:0 0 1.3em}
.post__list li{margin-bottom:.5em}
.post__figs{margin:1.5em 0}
.post__figs--multi{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.post__figure{margin:0 0 1.5em}
.post__figs--multi .post__figure{margin:0}
.post__figure img{width:100%;border-radius:var(--radius);box-shadow:var(--shadow);display:block}
@media(max-width:600px){.post__figs--multi{grid-template-columns:1fr}}
.post__toc{background:var(--bg-alt);border:1px solid var(--line);border-radius:var(--radius);padding:20px 26px;margin:0 0 2.2em}
.post__toc-title{font-family:var(--font-head);font-weight:800;color:var(--navy);text-transform:uppercase;letter-spacing:1px;font-size:.8rem;margin:0 0 .7em}
.post__toc ul{margin:0;padding-left:18px}
.post__toc li{margin-bottom:.4em}
.post__toc a{color:var(--indigo);text-decoration:none}
.post__toc a:hover{text-decoration:underline}
.post__faq{margin:1em 0 0}
.post__faq-item{border:1px solid var(--line);border-radius:var(--radius);margin-bottom:10px;padding:0 18px;background:#fff}
.post__faq-item summary{cursor:pointer;font-family:var(--font-head);font-weight:700;color:var(--navy);padding:14px 0;list-style:none;display:flex;justify-content:space-between;gap:12px;align-items:center}
.post__faq-item summary::-webkit-details-marker{display:none}
.post__faq-item summary::after{content:"+";color:var(--indigo);font-size:1.3rem;line-height:1}
.post__faq-item[open] summary::after{content:"\2013"}
.post__faq-item p{padding-bottom:14px;margin:0;color:var(--muted)}
.post__related{background:var(--bg-alt);padding:56px 0;border-top:1px solid var(--line)}
.post__related h2{margin-bottom:1em}
@media(max-width:820px){.post__hero{min-height:40vh}.post__body{padding-top:38px}}

.artgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:20px}
.artcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:22px;box-shadow:var(--shadow);transition:.18s;color:var(--ink)}
.artcard:hover{text-decoration:none;transform:translateY(-3px);box-shadow:0 10px 26px rgba(31,42,94,.14);border-color:var(--indigo)}
.artcard h3{color:var(--navy);margin-bottom:.4em;font-size:1.1rem}
.artcard p{color:var(--muted);font-size:.92rem;margin:0 0 14px}
.artcard__more{margin-top:auto;color:var(--indigo);font-family:var(--font-head);font-weight:700;font-size:.9rem}

.embed{position:relative;max-width:960px;margin:0 auto;aspect-ratio:16/9;border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow);background:#0d1533}
.embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.checklist--stack{grid-template-columns:1fr;gap:6px;margin:0 0 18px}

.media{display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:center}
.media__img img{width:100%;border-radius:var(--radius);box-shadow:var(--shadow);display:block}
.media__body h2{margin-top:0}
.media__body p:last-child{margin-bottom:0}
@media(max-width:820px){.media{grid-template-columns:1fr;gap:24px}.media__img{order:-1}}

.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}
.gallery__cell{margin:0;border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow);background:#fff;position:relative}
.gallery__cell img{width:100%;height:100%;object-fit:cover;aspect-ratio:400/284}
.gallery__cell figcaption{position:absolute;left:0;right:0;bottom:0;padding:10px 14px;font-size:.85rem;font-weight:700;
  color:#fff;font-family:var(--font-head);background:linear-gradient(transparent,rgba(20,30,70,.85))}

/* A cell holding a logo, a badge or a screenshot rather than a photograph.
   object-fit:cover crops to the cell's window, which on a 275x138 press logo
   takes the ends off the wordmark - FOX 5 rendered as "OX 5" on the Black
   Friday page. Contained, the whole mark sits inside the same cell on a white
   ground, so the row still lines up. Set by `fit:"contain"` on the section or
   the item; the build also contains anything much wider than the cell. */
.gallery__cell--contain{background:var(--white);border:1px solid var(--line);box-shadow:none}
.gallery__cell--contain img{object-fit:contain;padding:14px}

.usecase{position:relative;border-radius:var(--radius);overflow:hidden;min-height:230px;display:flex;align-items:flex-end;color:#fff;
  background-color:var(--navy-mid);
  background-image:linear-gradient(rgba(23,34,80,.15),rgba(23,34,80,.82)),var(--card-img,linear-gradient(160deg,#41579f,#26356e));
  background-size:cover;background-position:center;background-repeat:no-repeat}
.usecase h3{color:#fff;margin:0}
.usecase .body{padding:22px}
.usecase p{font-size:.9rem;color:#e7ecfb;margin:.3em 0 0}

/* A linked overlay card. The whole card is the anchor, so it takes the same
   lift-and-deepen hover as .artcard — one card-hover language across the site,
   not two. The global a:hover underline is cancelled: underlining a 230px
   photo card underlines the heading, the paragraph and the cue all at once. */
a.usecase--link{text-decoration:none;color:#fff;transition:.18s}
a.usecase--link:hover{text-decoration:none;color:#fff;transform:translateY(-3px);
  box-shadow:0 10px 26px rgba(31,42,94,.20)}
a.usecase--link:hover h3{color:#fff}
/* Keyboard focus. A whole-card link is the easy one to get wrong: without this
   the only focus indicator is the browser default outline drawn INSIDE
   overflow:hidden, against a dark photo, where it is invisible. Indigo at an
   offset puts the ring on the page ground outside the card, where it reads on
   both the plain and the --bg-alt section backgrounds. */
a.usecase--link:focus-visible{outline:3px solid var(--indigo);outline-offset:3px}
/* The "Explore →" cue. Present only when the card is a link, so a linked card
   is distinguishable from a decorative one without relying on hover. */
.usecase__more{display:block;margin-top:12px;color:#fff;font-family:var(--font-head);
  font-weight:700;font-size:.88rem;letter-spacing:.3px}
a.usecase--link:hover .usecase__more{text-decoration:underline;text-underline-offset:3px}

.pricing{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px}
.price-card{background:#fff;border:1px solid var(--line);border-top:4px solid var(--indigo);border-radius:var(--radius);
  padding:22px;text-align:center;box-shadow:var(--shadow)}
.price-card .guests{font-family:var(--font-head);font-weight:700;color:var(--navy)}
.price-card .amt{font-size:1.9rem;font-family:var(--font-head);font-weight:800;color:var(--indigo);margin:6px 0}
.price-card .amt span{font-size:.9rem;color:var(--muted);font-weight:400}

.fleet{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:22px}
.boat{background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow)}
.boat__img{height:160px;background-color:var(--navy-mid);background-image:var(--boat-img,linear-gradient(160deg,#4a63b5,#243a7a));
  background-size:cover;background-position:center;background-repeat:no-repeat}
.boat__body{padding:20px}
.boat__body h3{margin-bottom:.3em}
.boat__cap{color:var(--muted);font-size:.9rem;margin-bottom:12px}

.checklist{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px}
.checklist li{padding-left:30px;position:relative;color:var(--ink)}
.checklist li::before{content:"\2713";position:absolute;left:0;top:0;color:var(--indigo);font-weight:800}

.faq{max-width:820px;margin:0 auto}
.faq details{background:#fff;border:1px solid var(--line);border-radius:var(--radius);margin-bottom:12px;padding:0 20px}
.faq summary{cursor:pointer;font-family:var(--font-head);font-weight:700;color:var(--navy);padding:16px 0;list-style:none;
  display:flex;justify-content:space-between;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--indigo);font-size:1.4rem}
.faq details[open] summary::after{content:"\2013"}
.faq details p{padding-bottom:16px;margin:0;color:var(--muted)}

.band{background:var(--indigo);color:#fff;text-align:center;padding:54px 22px}
.band h2{color:#fff}
.band .btn{background:#fff;color:var(--indigo);border-color:#fff;margin-top:10px}
.band .btn:hover{background:#eef1ff}

.site-footer{background:var(--navy);color:#b9c4e2;padding:56px 0 26px;font-size:.94rem}
.site-footer h3{color:#fff;font-size:1rem;margin-bottom:1em;text-transform:uppercase;letter-spacing:.5px}
.footer-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:30px}
.site-footer a{color:#b9c4e2}.site-footer a:hover{color:#fff}
.site-footer ul{list-style:none;padding:0;margin:0}
.site-footer li{margin-bottom:8px}
.footer-bottom{border-top:1px solid rgba(255,255,255,.13);margin-top:36px;padding-top:20px;text-align:center;color:#8595c0;font-size:.85rem}

.crumbs{font-size:.85rem;color:var(--muted);padding:14px 0}
.crumbs a{color:var(--muted)}

.prose{max-width:820px;margin:0 auto}
.prose h2{margin-top:1.6em}
.prose ul,.prose ol{padding-left:22px}
.prose li{margin-bottom:.5em}

@media(max-width:900px){
  .nav__menu{position:fixed;inset:0 0 0 auto;top:0;width:min(320px,86vw);height:100vh;background:#fff;
    flex-direction:column;align-items:flex-start;padding:80px 28px;gap:18px;transform:translateX(100%);
    transition:.25s;box-shadow:var(--shadow)}
  .nav__menu.open{transform:translateX(0)}
  .nav__toggle{display:block}
  .nav__sub{position:static;display:block;box-shadow:none;padding:6px 0 6px 14px}
  .hero{min-height:70vh}
}



/* ==========================================================================
   Live-site match, corrected. The first pass at this was built against a
   reference render that never loaded Divi's per-post stylesheet, so the live
   pages looked left-aligned and unboxed when they are neither. The live site
   centres its section headings and uses white cards with a soft shadow.
   ========================================================================== */
.section h2{text-align:center}
.section h2.left{text-align:left}
.prose h2,.media__body h2{text-align:center}
.section .lead{max-width:70ch}

/* Feature cards: white card, inset photo, title and copy beneath. */
.feature__img{height:170px;border-radius:6px;background-size:cover;background-position:center}
.feature--photo{padding:18px}
.feature--photo .feature__body{padding:16px 4px 4px}
.feature h3{color:var(--navy);font-size:1.05rem;margin-bottom:.4em}
.feature p{color:var(--ink-soft);font-size:.92rem;line-height:1.65}

/* Price tiers: boxed, left-aligned inside, teal amount, plain availability link. */
.price-card{text-align:left;border-top:1px solid var(--line);padding:20px}
.price-card .guests{font-size:.95rem;color:var(--ink-soft);font-weight:500}
.price-card .amt{font-size:1.85rem;color:var(--teal);margin:6px 0 10px}
.price-card .amt span{font-size:1.1rem;color:var(--teal)}
.price-card .btn--ghost{border:0;padding:0;background:none;color:var(--sky);font-size:.9rem;font-weight:500}
.price-card .btn--ghost:hover{background:none;text-decoration:underline}

/* Google review strip. */
.reviews__head{justify-content:flex-start;gap:12px;padding:26px 0 16px}
.reviews__count{color:var(--muted);font-size:.9rem}
.reviews__brand{font-family:var(--font-head);font-weight:800;color:#4285f4;letter-spacing:.5px}
.stars--lg{font-size:1.15rem}
.review-card__top{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.review-card .avatar{width:32px;height:32px;border-radius:50%;background:var(--indigo);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem;flex:0 0 32px}
.review-card .who{display:flex;flex-direction:column;line-height:1.2;flex:1}
.review-card .when{color:var(--muted);font-size:.78rem;font-weight:400;margin:0}
.review-card .src{color:#4285f4;font-weight:800;font-family:var(--font-head)}

/* FAQ groups sit in two columns on the live pages. */
.faq-cols{display:grid;grid-template-columns:1fr 1fr;gap:10px 46px;text-align:left}
.faq-cols h3{margin-top:.2em}
@media(max-width:820px){.faq-cols{grid-template-columns:1fr}}

/* Hero headline breaks in two lines at desktop width. */
.hero h1{max-width:24ch}
.hero p{max-width:64ch}
.hero__sublinks{width:100%;max-width:920px}

/* Paired lists, as on the live "What You Can Expect" block. */
.pair{display:grid;grid-template-columns:1.1fr .9fr;gap:20px 50px;align-items:start;text-align:left}
.pair__col h3{text-align:left;font-size:1.5rem;color:var(--navy);margin:0 0 .55em;font-family:var(--font-head);font-weight:800}
.checklist--plain{grid-template-columns:1fr;gap:6px;list-style:disc;padding-left:20px}
.checklist--plain li{padding-left:0}
.checklist--plain li::before{content:none}
@media(max-width:820px){.pair{grid-template-columns:1fr;gap:26px}}

/* Homepage links into the money pages. The card title is the anchor so the
   internal link carries the keyword the destination is meant to rank for. */
.feature__body h3 a{color:var(--navy);text-decoration:none}
.feature__body h3 a:hover{color:var(--indigo)}
.feature__more{margin:10px 0 0}
.feature__more a{color:var(--indigo);font-family:var(--font-head);font-weight:700;font-size:.88rem}

/* Live interior pages: headings left, body in a wide single column. */
.prose--wide{max-width:1080px}
.prose--wide h2.left{text-align:left}
.section .prose--wide h2{text-align:left}

/* Split hero with the enquiry form, as on the live yacht-rental page. */
.hero--split .hero__inner{display:grid;grid-template-columns:1fr 420px;gap:48px;align-items:center}
.hero--split .hero__copy h1{font-size:clamp(2rem,4vw,3.4rem);max-width:14ch}
.hero--split .hero__copy p{font-size:1rem;max-width:46ch;color:#dbe3f7}
@media(max-width:900px){.hero--split .hero__inner{grid-template-columns:1fr}}
.inquiry{background:#fff;border-radius:6px;padding:26px 24px;box-shadow:0 18px 44px rgba(0,0,20,.28)}
.inquiry h2{font-size:1.35rem;margin:0 0 16px;text-align:left;color:var(--navy)}
.fld{display:block;margin-bottom:10px}
.inquiry input,.inquiry select{width:100%;padding:12px 13px;border:0;background:#f2f4f8;border-radius:3px;
  font:inherit;font-size:.93rem;color:var(--ink)}
.inquiry input:focus,.inquiry select:focus{outline:2px solid var(--indigo);outline-offset:1px;background:#fff}
/* .hero p sets 1.3rem/var(--tint) for hero copy and outranked these on specificity,
   which rendered the form's note as huge pale text on a white card. */
.hero .inquiry__note,.inquiry__note{font-size:.75rem;color:var(--muted);margin:0 0 14px;line-height:1.4;max-width:none}
.hero .inquiry p{font-size:.75rem;color:var(--muted);max-width:none;margin:0 0 14px}
.hero .inquiry .fld:last-of-type{margin-bottom:6px}
.inquiry .btn{width:100%;padding:13px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* Hero ghost button: no outline, just the white pill. `.btn` sets a 2px indigo
   border for every button, which read as a purple box around "Private Rentals". */
.hero .btn--ghost{border-color:transparent}
.hero .btn--ghost:hover{border-color:transparent}

/* Review cards in the hero. Desktop: one 6-column grid, two rows, twelve cards -
   the slide wrappers are display:contents so they do not form a box. Narrow
   screens: the same wrappers become 2x2 scroll-snap slides, three of them, and
   the track shows a sliver of the next slide so it reads as swipeable. */
.hrev{margin-top:26px;max-width:100%}
/* The rating line sits directly on the photo, so it carries its own chip.
   Without it the whole hero veil has to be dark enough to protect 12px text,
   which buries the boat. */
.hrev__bar{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:.82rem;
  margin-bottom:12px;background:rgba(10,20,50,.58);padding:6px 12px;border-radius:20px}
.hrev__score{font-family:var(--font-head);font-weight:800;letter-spacing:1.4px;
  text-transform:uppercase;color:#fff;font-size:.78rem}
.hrev__stars{color:var(--gold);letter-spacing:1px;font-size:.9rem}
.hrev__count{color:#d6def7;font-size:.78rem}

.hrev__quotes{display:grid;grid-template-columns:repeat(6,1fr);gap:8px}
.hrev__slide{display:contents}
.hrev__q{margin:0;background:rgba(10,20,50,.5);border:1px solid rgba(255,255,255,.15);
  border-radius:6px;padding:9px 10px;backdrop-filter:blur(3px);min-width:0}
.hrev__top{display:flex;align-items:center;gap:6px;margin-bottom:5px;min-width:0}
.hrev__pic{width:26px;height:26px;border-radius:50%;flex:0 0 26px;object-fit:cover;display:block}
.hrev__pic--ltr{background:var(--indigo);color:#fff;display:inline-flex;align-items:center;
  justify-content:center;font-family:var(--font-head);font-weight:700;font-size:.7rem}
.hrev__who{display:flex;flex-direction:column;min-width:0;font-size:.68rem;font-weight:700;
  color:#fff;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hrev__tag{font-weight:500;font-size:.6rem;color:#ccd6f4;letter-spacing:.2px}
.hrev__s{color:var(--gold);font-size:.7rem;letter-spacing:.5px;margin-bottom:4px}
.hrev__q blockquote{margin:0;font-size:.68rem;line-height:1.4;color:#e8eefc;
  display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
/* .hero p sets 1.3rem/var(--tint) and would otherwise win on specificity here. */
.hero .hrev__q blockquote{font-size:.68rem;max-width:none;margin:0}

@media(max-width:1180px){
  .hrev__quotes{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
    gap:10px;padding-bottom:8px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .hrev__quotes::-webkit-scrollbar{display:none}
  .hrev__quotes:focus-visible{outline:2px solid #fff;outline-offset:3px}
  .hrev__slide{display:grid;grid-template-columns:1fr 1fr;gap:10px;
    flex:0 0 calc(100% - 26px);scroll-snap-align:start}
  /* Without a trailing spacer the track runs out of scroll 26px early and the
     third slide can never snap flush to the left edge. */
  .hrev__quotes::after{content:"";flex:0 0 16px}
  .hrev__q blockquote,.hero .hrev__q blockquote{-webkit-line-clamp:4}
}
@media(prefers-reduced-motion:no-preference){.hrev__quotes{scroll-behavior:smooth}}

/* Top bar. On a phone it collapses to one line of three emoji: call, email, and
   a tap-to-open social menu. Previously the full phone number, email address and
   icon row wrapped onto three rows and made the header 168px tall before the
   page even started. */
.topbar .tb__i{font-size:1rem;line-height:1}
.tb__soc{display:none;position:relative}
.tb__soc>summary{list-style:none;cursor:pointer;font-size:1rem;line-height:1;padding:2px}
.tb__soc>summary::-webkit-details-marker{display:none}
.tb__soc>summary::marker{content:""}
.tb__soc>summary:focus-visible{outline:2px solid #fff;outline-offset:2px;border-radius:3px}
.tb__menu{position:absolute;top:calc(100% + 8px);right:0;z-index:90;margin:0;padding:6px;
  list-style:none;background:#fff;border-radius:8px;min-width:172px;
  box-shadow:0 12px 30px rgba(0,0,20,.35)}
.tb__menu li{margin:0}
.tb__menu a{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:5px;
  color:var(--navy);font-size:.9rem;font-weight:600}
.tb__menu a:hover{background:var(--bg-alt);text-decoration:none;color:var(--indigo)}
.tb__menu svg{flex:0 0 16px;color:var(--indigo)}

@media(max-width:700px){
  .topbar .container{gap:26px;padding:7px 22px;flex-wrap:nowrap;justify-content:center}
  .topbar .tb__t{display:none}        /* number and address collapse to the icon */
  .topbar .social{display:none}       /* the inline icon row becomes the menu */
  .tb__soc{display:block}
  .nav{padding:10px 22px}
  .nav__logo img{height:40px}
}

/* Mobile nav close control. The open panel is fixed to the right edge and covers
   the ☰ button, so it carries its own ×. The scrim is a separate element rather
   than a pseudo-element on the ×: the button needs to sit ABOVE the panel, and a
   scrim inside its stacking context inherits that and swallows every nav link. */
.nav__close,.nav__scrim{display:none}
.nav__close{background:none;border:0;font-size:2rem;line-height:1;
  color:var(--navy);cursor:pointer;padding:4px 10px}
@media(max-width:900px){
  .nav__menu.open ~ .nav__scrim{display:block;position:fixed;inset:0;z-index:1;
    background:rgba(16,25,60,.45)}
  .nav__menu{z-index:2}
  .nav__menu.open ~ .nav__close{display:block;position:fixed;top:12px;right:14px;z-index:3}
  .nav__close:focus-visible{outline:2px solid var(--indigo);outline-offset:2px;border-radius:4px}
}

/* Phone hero. The desktop photo is landscape; cropping it to a tall phone slot
   pushes the boat off-frame, so the homepage ships a portrait crop composed
   around it (--hero-img-m). --hero-veil-m darkens it enough for the headline to
   clear WCAG AA over a very pale sky. */
@media(max-width:700px){
  /* Three layers: veil, phone crop, desktop photo. A background layer whose URL
     404s renders as nothing and the layer beneath shows through, so if the phone
     crop is ever missing the hero falls back to the desktop image instead of
     going blank. */
  .hero{background-image:var(--hero-veil-m,var(--hero-veil,linear-gradient(rgba(20,30,70,.5),rgba(20,30,70,.6)))),
    var(--hero-img-m,var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)))),
    var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)));
    background-position:center center;background-size:cover;background-repeat:no-repeat}
}

/* Late overrides. This sheet is concatenated after base.css (see CSS_FILES in
   build/build.mjs), so it wins on equal specificity. Narrow, page-level tweaks
   live here rather than at the end of a 26KB base.css. */

/* Homepage hero: one primary action.
   A second equally-weighted button next to "Get Tickets" split the page between
   two businesses at two price points. The private-charter path stays one click
   away as a text link instead of a competing pill. A hero with a single sublink
   renders it as that link; the event pages, which carry three, keep the white
   sublink bar they share with the live site. */
.hero__sublinks:has(a:only-child){background:none;border-radius:0;overflow:visible;
  margin-top:16px;gap:0}
.hero__sublinks:has(a:only-child) a{flex:0 0 auto;min-width:0;padding:0;text-align:left;
  color:#dfe6ff;font-family:var(--font-head);font-weight:600;font-size:.98rem;
  text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.hero__sublinks:has(a:only-child) a:hover{background:none;color:#fff}
.hero__sublinks:has(a:only-child) a::after{content:" →"}

/* Review strip: one row of four, the rest a swipe away.
   A sliver of the fifth card stays visible so the row reads as scrollable. */
.review-grid{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:14px;-webkit-overflow-scrolling:touch}
.review-grid > .review-card{flex:0 0 calc((100% - 78px)/4.3);scroll-snap-align:start;min-width:0}
.review-grid::after{content:"";flex:0 0 2px}
.review-grid:focus-visible{outline:2px solid var(--indigo);outline-offset:4px;border-radius:var(--radius)}
@media(prefers-reduced-motion:no-preference){.review-grid{scroll-behavior:smooth}}
@media(max-width:900px){.review-grid > .review-card{flex-basis:calc((100% - 30px)/2.2)}}
/* Phones show two and a half cards, so the row is unmistakably a row and the
   cut-off third card is the affordance. At ~130px of card width the internals
   have to come down with it or the quote becomes a one-word-per-line column. */
@media(max-width:600px){
  .review-grid{gap:10px}
  .review-grid > .review-card{flex-basis:calc((100% - 25px)/2.5);padding:12px 11px}
  .review-card__top{gap:7px;margin-bottom:4px}
  .review-card .avatar{width:24px;height:24px;font-size:.72rem}
  .review-card .avatar--photo{flex:0 0 24px}
  .review-card .who{font-size:.78rem;line-height:1.25}
  .review-card .when{font-size:.68rem}
  /* The platform badge is redundant at this width — the strip header already
     names the source — and it was stealing 14px from a 128px card. */
  .review-card .src{display:none}
  .review-card .stars{font-size:.92rem;letter-spacing:1px}
  .review-card p{font-size:.76rem;line-height:1.5;-webkit-line-clamp:7}
}

/* Real profile photo where the reviewer has one; the initial chip otherwise. */
.review-card .avatar--photo{object-fit:cover;background:none;padding:0;flex:0 0 32px}
.review-card .src{font-size:.8rem;letter-spacing:.2px}
.review-card .src--yelp{color:#c41200}
.review-card .src--tripadvisor{color:#00857a}
.review-card .src--getyourguide{color:#ff5533}

/* Cards in a row stretch to the tallest, so a 60-word review left the short
   ones half empty. Clamp the quote; the full text lives on the review site. */
.review-card p{display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
.review-card .who{font-size:.95rem}

/* Video / 3D-tour hero.
   The flythrough sits behind the copy as a muted looping layer; the veil that
   normally rides on the background image becomes a real overlay so the text
   keeps its contrast over moving footage.
   The photo stays as the layer under the video: it paints first, and it is
   what a reduced-motion visitor sees when the video is suppressed. The veil
   moves to ::before so it is not applied twice. */
.hero--video{background-image:var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)))}
@media(max-width:700px){
  .hero--video{background-image:var(--hero-img-m,var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy))))}
}
.hero__video,.hero__frame{position:absolute;inset:0;width:100%;height:100%;border:0;
  object-fit:cover;z-index:0}
.hero--video::before{content:"";position:absolute;inset:0;z-index:1;
  background:var(--hero-veil,linear-gradient(rgba(20,30,70,.5),rgba(20,30,70,.6)))}
.hero--video .hero__inner{position:relative;z-index:2}
/* On the tour page the tour is what the visitor came for, so it leads and the
   booking button sits beside it as the white pill. */
.hero__tour{cursor:pointer;font:inherit;font-family:var(--font-head);font-weight:700}
/* Once the live tour is in, it owns the whole hero — no veil, no copy over it. */
.hero--live::before{display:none}
.hero--live .hero__inner{display:none}
.hero--live{min-height:86vh}
@media(prefers-reduced-motion:reduce){.hero__video{display:none}}

/* Two feature cards across on a phone rather than one.
   The auto-fit grid's 280px minimum forces a single column below ~340px of
   usable width, so phones get an explicit two-column track and the card
   internals tighten to match the narrower column. */
@media(max-width:700px){
  .grid--3{grid-template-columns:1fr 1fr;gap:14px}
  .feature{padding:14px}
  .feature--photo{padding:10px}
  .feature__img{height:104px}
  .feature--photo .feature__body{padding:12px 2px 2px}
  .feature h3{font-size:.94rem;line-height:1.25}
  .feature p{font-size:.82rem;line-height:1.55}
  .feature__more a{font-size:.8rem}
}

/* A four-card feature row should be a row, not three plus an orphan.
   The auto-fit track fits three 280px columns in a 1136px grid and wraps the
   fourth, so a grid whose fourth child is its last gets four explicit columns.
   Six-card grids keep auto-fit and their clean 3x2. */
@media(min-width:701px){
  .grid--3:has(> :nth-child(4):last-child){grid-template-columns:repeat(4,1fr)}
}
/* Four across on a tablet leaves ~175px a card, so the row's internals tighten
   there the way the two-up phone layout does. */
@media(min-width:701px) and (max-width:1000px){
  .grid--3:has(> :nth-child(4):last-child){gap:16px}
  .grid--3:has(> :nth-child(4):last-child) .feature--photo{padding:12px}
  .grid--3:has(> :nth-child(4):last-child) .feature__img{height:120px}
  .grid--3:has(> :nth-child(4):last-child) .feature h3{font-size:.98rem;line-height:1.25}
  .grid--3:has(> :nth-child(4):last-child) .feature p{font-size:.86rem;line-height:1.6}
}

/* The 3D tour is the widest, tallest thing on the page and it already reads as
   its own block, so it does not need a full 70px band above and below it. */
.section:has(> .container > .embed){padding:34px 0}
.section:has(> .container > .embed) h2{margin-bottom:.5em}
@media(max-width:700px){.section:has(> .container > .embed){padding:24px 0}}

/* Instagram strip. Square tiles in one scrolling row, same swipe grammar as the
   review strip: five and a bit on desktop, two and a half on a phone. */
.ig__head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;
  flex-wrap:wrap;margin-bottom:18px}
.ig__head h2{margin-bottom:2px}
.ig__handle{font-family:var(--font-head);font-weight:600;color:var(--muted);font-size:.95rem}
.ig__handle:hover{color:var(--indigo)}
.ig__row{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:10px;-webkit-overflow-scrolling:touch}
.ig__row::after{content:"";flex:0 0 2px}
.ig__row:focus-visible{outline:2px solid var(--indigo);outline-offset:4px;border-radius:var(--radius)}
@media(prefers-reduced-motion:no-preference){.ig__row{scroll-behavior:smooth}}
.ig__cell{flex:0 0 calc((100% - 60px)/5.3);scroll-snap-align:start;aspect-ratio:1;
  border-radius:var(--radius);overflow:hidden;background:#e9eefb;display:block}
.ig__cell img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .35s ease}
a.ig__cell:hover img{transform:scale(1.05)}
@media(prefers-reduced-motion:reduce){.ig__cell img{transition:none}
  a.ig__cell:hover img{transform:none}}
@media(max-width:900px){.ig__cell{flex-basis:calc((100% - 36px)/3.4)}}
@media(max-width:600px){
  .ig__row{gap:10px}
  .ig__cell{flex-basis:calc((100% - 25px)/2.5)}
  .ig__head{margin-bottom:14px}
  .ig__follow{padding:10px 16px;font-size:.88rem}
}

/* "What you can expect": photo beside the copy, heading left-aligned with it
   rather than centred over a half-width column. */
.media__body h2{text-align:left}
.media__body .btn{margin-top:6px}

/* Spec sheet. What's included is ticked; the paid add-ons are pills, so the two
   lists read as different kinds of thing instead of one long bullet dump. */
.spec{display:grid;grid-template-columns:1.5fr 1fr;gap:40px;align-items:start}
.spec__group h3{color:var(--navy);font-size:1.05rem;margin-bottom:.7em}
.spec__note{color:var(--muted);font-size:.86rem;margin:-.4em 0 1em}
.spec__list{list-style:none;padding:0;margin:0;display:grid;
  grid-template-columns:1fr 1fr;gap:11px 22px}
.spec__list li{display:flex;gap:10px;align-items:flex-start;
  font-size:.95rem;line-height:1.5;color:var(--ink-soft)}
.spec__tick{flex:0 0 19px;height:19px;margin-top:3px;border-radius:50%;
  background:var(--indigo);color:#fff;display:grid;place-items:center;
  font-size:.65rem;line-height:1}
.spec__chips{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:8px}
.spec__chips li{border:1px solid var(--line);border-radius:999px;background:#fff;
  padding:8px 14px;font-size:.88rem;color:var(--navy);
  font-family:var(--font-head);font-weight:600}
.spec__group--chips{background:var(--tint-2);border-radius:var(--radius);padding:22px}
@media(max-width:900px){
  .spec{grid-template-columns:1fr;gap:26px}
}
@media(max-width:600px){
  .spec__list{grid-template-columns:1fr;gap:9px}
  .spec__list li{font-size:.9rem}
  .spec__group--chips{padding:16px}
  .spec__chips li{padding:7px 12px;font-size:.82rem}
}

/* Fleet: five boats, one row.
   The auto-fit track fits four 230px columns in a 1136px grid and wraps the
   fifth, which reads as an afterthought rather than part of the fleet. Five
   explicit columns leave ~214px a card, so the card internals come down with
   the width. Below 980px the auto-fit track takes over again (3, then 2, then
   1), since five across a tablet would be unreadable.
   Descriptions run from six words to twenty-six, and grid items stretch to the
   tallest, so the body is a flex column with the paragraph absorbing the slack
   — that keeps the capacity line and the button on a common baseline instead of
   floating wherever the copy happens to end.
   The five boat photos are all 640x430. A fixed tile height crops them to
   whatever ratio the column happens to be — at 214x124 that cut the masts off
   Malarky and Athena and sliced Triton's sail — so the tile takes the photos'
   own ratio instead and every boat sits in its frame whole at any width. */
.boat{display:flex;flex-direction:column}
.boat__img{height:auto;aspect-ratio:640/430}
.boat__body{display:flex;flex-direction:column;flex:1}
.boat__body p{flex:1}
@media(min-width:981px){
  .fleet{grid-template-columns:repeat(5,1fr);gap:16px}
  .boat__body{padding:14px}
  .boat__body h3{font-size:1.02rem;margin-bottom:.25em}
  .boat__body p{font-size:.82rem;line-height:1.45}
  .boat__cap{font-size:.78rem;margin-bottom:10px}
  .boat .btn{padding:9px 14px;font-size:.82rem}
}

/* Topbar contact glyphs are now inline SVG rather than emoji, so they need a
   box and a baseline. The anchors become flex so the mark and the text sit on
   a common centre line with real space between them; on a phone .tb__t is
   hidden and the mark alone is the tap target, so it keeps its size. */
.topbar .container > a{display:inline-flex;align-items:center;gap:8px}
.topbar .tb__i{display:inline-flex;align-items:center}
.topbar .tb__i svg{display:block;width:15px;height:15px}
.tb__soc>summary{display:inline-flex;align-items:center}
.tb__soc>summary svg{display:block;width:16px;height:16px}

/* "What's On Board" on brand ground.
   Every other band on the page is a white or pale-blue card on a light field,
   so the spec sheet had nothing to distinguish it from the three card rows
   above it. Inverting it — solid brand indigo, each included item its own
   white card — makes the one section that is pure fact read as pure fact.
   The ticked <li> is already the right unit, so it becomes the card and the
   markup does not change. */
.section:has(> .container > .spec){background:var(--indigo);color:#fff}
.section:has(> .container > .spec) h2{color:#fff}
.section:has(> .container > .spec) .spec__group h3{color:#fff}
.section:has(> .container > .spec) .spec__note{color:rgba(255,255,255,.72)}
.section:has(> .container > .spec) .spec__list{gap:12px}
.section:has(> .container > .spec) .spec__list li{background:#fff;border-radius:var(--radius);
  padding:14px 16px;align-items:center;color:var(--ink-soft);font-size:.92rem;
  box-shadow:0 6px 18px rgba(12,18,52,.20)}
.section:has(> .container > .spec) .spec__tick{margin-top:0;background:var(--indigo)}
/* The add-ons panel was a pale-blue card; on the indigo ground it becomes a
   translucent well so the white pills inside stay the brightest thing. */
.section:has(> .container > .spec) .spec__group--chips{background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.20)}
.section:has(> .container > .spec) .spec__chips li{background:#fff;border-color:transparent;
  color:var(--indigo)}
@media(max-width:600px){
  .section:has(> .container > .spec) .spec__list li{padding:11px 12px;font-size:.86rem}
}

/* Article strip. Third row on the page to use the scroll-snap grammar, after
   reviews and Instagram, so the counts are tuned to the same rhythm: three and
   a bit across on desktop, then 2.3, then 1.5 on a phone where a headline plus
   three lines of excerpt needs the width. The whole card is the link. */
.art__row{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:14px;-webkit-overflow-scrolling:touch}
.art__row::after{content:"";flex:0 0 2px}
.art__row:focus-visible{outline:2px solid var(--indigo);outline-offset:4px;border-radius:var(--radius)}
@media(prefers-reduced-motion:no-preference){.art__row{scroll-behavior:smooth}}
.art__card{flex:0 0 calc((100% - 72px)/3.4);scroll-snap-align:start;min-width:0;
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  box-shadow:var(--shadow);display:flex;flex-direction:column;
  transition:transform .2s ease,box-shadow .2s ease}
.art__card:hover{transform:translateY(-3px);box-shadow:0 14px 34px rgba(31,42,94,.16)}
@media(prefers-reduced-motion:reduce){
  .art__card{transition:none}
  .art__card:hover{transform:none}
}
.art__img{width:100%;aspect-ratio:16/10;object-fit:cover;display:block}
.art__body{padding:15px 17px 17px;display:flex;flex-direction:column;gap:7px;flex:1}
.art__t{font-family:var(--font-head);font-weight:700;color:var(--navy);
  font-size:1.02rem;line-height:1.3}
/* Cards stretch to the tallest, so the excerpt is clamped and "Read more" is
   pushed to the floor - otherwise a short summary leaves a hole under it. */
.art__x{color:var(--ink-soft);font-size:.86rem;line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.art__more{margin-top:auto;padding-top:4px;color:var(--indigo);
  font-family:var(--font-head);font-weight:600;font-size:.85rem}
.art__card:hover .art__more{text-decoration:underline;text-underline-offset:3px}
@media(max-width:900px){.art__card{flex-basis:calc((100% - 36px)/2.3)}}
@media(max-width:600px){
  .art__row{gap:12px}
  .art__card{flex-basis:calc((100% - 26px)/1.5)}
  .art__body{padding:12px 13px 14px;gap:5px}
  .art__t{font-size:.94rem}
  .art__x{font-size:.8rem}
  .art__more{font-size:.8rem}
}

/* Article hero breadcrumbs.
   base.css lightens .hero .crumbs--hero but never .post__hero .crumbs--hero,
   so on the article template the trail fell back to .crumbs{color:var(--muted)}
   - dark grey over a photo, effectively invisible. Same treatment as the main
   hero: pale ink plus a shadow that survives a bright patch of sky. */
.post__hero .crumbs--hero{color:var(--tint);padding:0;
  text-shadow:0 1px 8px rgba(0,0,0,.55)}
.post__hero .crumbs--hero a{color:var(--tint)}
.post__hero .crumbs--hero a:hover{color:#fff}

/* Article hero height.
   Almost every article's lead photo is an 800px WordPress original - there is
   no larger version in the media library, confirmed against the export. At 46vh
   those upscale roughly 1.8x and go soft. 36vh keeps the banner substantial
   while halving the upscale, and a slightly deeper scrim lets the photo read as
   atmosphere rather than detail. */
.post__hero{min-height:36vh}
.post__hero{background-image:linear-gradient(rgba(18,26,62,.42),rgba(18,26,62,.84)),
  var(--hero-img,linear-gradient(160deg,#3a5bb0,var(--navy)))}
.post__hero-inner{padding:44px 22px}
@media(max-width:700px){
  .post__hero{min-height:30vh}
  .post__hero-inner{padding:32px 20px}
}

/* ==========================================================================
   ARTICLE TEMPLATE
   Loaded last, so everything here wins over base.css. Kept in its own file so
   the long-form pages can be tuned without re-pushing a 27KB base.css.

   Nothing here introduces a colour or a typeface. Every value resolves to a
   token from tokens.css; the only new custom properties are two shape values
   scoped to this template, declared immediately below.

   The problem this file solves: the article pages inherited a layout that was
   never designed, only assembled. Photos arrived at whatever shape WordPress
   stored them in - 500x500 next to 720x480 next to 1200x800 - so the prose
   column lurched. Headings sat one line below a photo and one line above a
   paragraph, so nothing read as a section. The contents box was a list of
   bullets in a tinted rectangle. This gives the template a single spacing
   scale, one photo shape, and card treatments that match the homepage.
   ========================================================================== */

.post{
  --radius-media:10px;   /* photos and the cards built around them. --radius
                            (6px) is right on a small UI chip and reads as an
                            unintentional near-square on a 700px-wide photo. */
  --gap-block:2.2em;     /* one vertical step: figure to text, section to
                            section. Every margin below is this or a multiple. */
}

/* --- Hero ---------------------------------------------------------------
   The band was tall enough to push the first sentence off the fold while the
   H1 ran to 22ch and broke across three lines on a laptop. Shorter measure,
   tighter leading, and the body starts sooner underneath. */
.post__hero h1{
  font-size:clamp(2rem,3.5vw,3rem);
  line-height:1.12;
  max-width:19ch;
  letter-spacing:-.01em;
}
.post__hero .crumbs--hero{
  font-size:.86rem;
  letter-spacing:.02em;
  margin-bottom:16px;
}

/* --- Prose column -------------------------------------------------------
   720px at 1.115rem is about 68 characters, inside the 45-75 that keeps a
   reader's eye from losing the line on the return sweep. */
.post__body{
  max-width:720px;
  padding:48px 22px 8px;
  font-size:1.115rem;
  line-height:1.72;
}
.post__body p{margin:0 0 1.25em}

/* --- Buttons inside the prose column -----------------------------------
   `.post__body a` above sets every link in the column to indigo with an
   underline, at specificity 0,1,1 — which beats `.btn` at 0,1,0. A `cta`
   button inside an article therefore rendered as indigo text on an indigo
   ground: a solid navy rectangle with no readable label.

   That is worse than a cosmetic bug. `fh:book` is only resolved when it is a
   section's `cta.href`, never inside a `paragraphs` HTML string, and raw
   fareharbor.com URLs are banned from page data — so while this stood, the
   article template had no way to carry a booking link mid-article at all.

   Scoped to `a.btn` (0,2,1) so it wins over `.post__body a` without touching
   any ordinary link in the column: prose links keep their indigo underline. */
.post__body a.btn,
.post__body a.btn:hover{text-decoration:none}
.post__body a.btn{color:#fff}
.post__body a.btn:hover{color:#fff}
.post__body a.btn--ghost{color:var(--indigo)}
.post__body a.btn--ghost:hover{color:var(--indigo-dark)}
/* A button is a block-level action, not a phrase in a sentence. The paragraph
   the renderer wraps it in gets the column's normal vertical step. */
.post__body p:has(> a.btn:only-child){margin:var(--gap-block) 0}

/* The opening paragraph carries the page. It gets its own size and colour so
   the reader lands on something that is clearly the start of the piece. */
.post__lead{
  font-size:1.32rem;
  line-height:1.6;
  margin:0 0 var(--gap-block);
}
/* The lead is a <div> wrapping the paragraph's own <p>, so the inner element
   would otherwise stack its body margin on top of the block margin above. */
.post__lead>p{margin:0}

/* Headings. The old scale put an H2 barely above body size, so in a listicle
   - where nearly every heading is "#4 Something" - the numbered items read as
   a run-on rather than as sections. Bigger, tighter, and with real space above
   so the gap itself says "new section". */
.post__body h2{
  font-size:clamp(1.62rem,2.3vw,2.02rem);
  line-height:1.2;
  letter-spacing:-.012em;
  font-weight:800;
  margin:calc(var(--gap-block) * 1.35) 0 .55em;
}
.post__body h2:first-child{margin-top:0}
.post__body h3{
  font-size:1.28rem;
  line-height:1.3;
  margin:calc(var(--gap-block) * .9) 0 .45em;
}

/* Inline links: present without shouting. The underline sits away from the
   descenders and only reaches full strength on hover. */
.post__body p a,
.post__body li a{
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  text-decoration-color:rgba(46,59,147,.38);
  transition:text-decoration-color .15s ease;
}
.post__body p a:hover,
.post__body li a:hover{text-decoration-color:currentColor}

/* Body lists */
.post__list{padding-left:1.25em;margin:0 0 var(--gap-block)}
.post__list li{margin-bottom:.55em;padding-left:.15em}
.post__list li::marker{color:var(--indigo)}

/* --- Photos -------------------------------------------------------------
   One shape for every in-article photo. The sources range from 500x500 to
   1200x800; rendering each at its own ratio is most of why these pages looked
   ragged. 3:2 is the shape the majority already are, so it crops the fewest
   of them, and object-fit keeps the centre of the frame. */
.post__figs{margin:var(--gap-block) 0}
.post__figure{margin:var(--gap-block) 0}
.post__figure img,
.post__figs--multi .post__figure img{
  width:100%;
  aspect-ratio:3/2;
  object-fit:cover;
  border-radius:var(--radius-media);
  box-shadow:0 10px 30px rgba(31,42,94,.13);
  display:block;
}
.post__figs--multi{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.post__figs--multi .post__figure{margin:0}

/* Not everything in an imported article is a photograph. The build measures
   each file and tags the small ones, because a 100px emoji used as a list
   marker rendered as a 676px-wide banner under the uniform rule above. These
   two keep their own size and sit centred in the column. */
.post__figs .post__figure--small img,
.post__figs .post__figure--icon img,
.post__figure--small img,
.post__figure--icon img{
  height:auto;          /* with the width/height attributes the build writes,
                           height:auto lets the browser reserve the right box
                           before the file arrives - no layout shift */
  aspect-ratio:auto;
  margin-inline:auto;
}
.post__figs .post__figure--small img,
.post__figure--small img{width:min(320px,100%)}
.post__figs .post__figure--icon img,
.post__figure--icon img{
  width:min(88px,100%);
  border-radius:0;
  box-shadow:none;
}
.post__figure--icon{margin:1em 0}

/* A banner, a collage or a panorama - anything past about 2.5:1. The uniform
   3:2 card keeps the middle third of one of these and throws both ends away,
   which is what happened to the 1600x500 strips on /what-to-wear-on-a-boat-party/.
   The build tags these from the file's own dimensions; here they simply keep
   their own shape at the full width of the column. */
.post__figure--wide img,
.post__figs .post__figure--wide img{
  aspect-ratio:auto;
  height:auto;
  object-fit:contain;
}
/* In a two-up row a banner would be squeezed into half a column, so it takes
   the whole row instead. */
.post__figs--multi .post__figure--wide{grid-column:1/-1}

/* --- Embedded video and maps -------------------------------------------
   An article may carry a Vimeo film or a map. It gets the same 16:9 frame and
   the same media radius as the photos around it, and the same vertical step,
   so it reads as one more block in the column rather than a pasted-in widget. */
.post__embed{margin:var(--gap-block) 0}
.post .embed{max-width:none;border-radius:var(--radius-media);box-shadow:0 10px 30px rgba(31,42,94,.13)}
.post__embed-cap{font-size:.92rem;color:var(--muted);margin:.7em 0 0;text-align:center}
.post__body h2 + .post__embed{margin-top:.9em}

/* A photo directly under its own heading belongs to that heading - close the
   gap so they read as one unit rather than two stray blocks. */
.post__body h2 + .post__figs,
.post__body h2 + .post__figure,
.post__body h3 + .post__figs,
.post__body h3 + .post__figure{margin-top:.9em}

/* Galleries share the photo shape so a gallery row lines up with the single
   figures above and below it. Scoped to .post: the gallery component also
   renders on service pages, which are a later pass. */
.post .gallery{gap:16px}
.post .gallery__cell{border-radius:var(--radius-media)}
.post .gallery__cell img{aspect-ratio:3/2}

/* Same guard as the figures above: a gallery holding one 100px emoji must not
   stretch it across the column. */
.post .gallery__cell--icon,
.post .gallery__cell--small{box-shadow:none;background:none}
.post .gallery__cell--icon img,
.post .gallery__cell--small img{
  height:auto;
  aspect-ratio:auto;
  object-fit:contain;
  margin-inline:auto;
}
.post .gallery__cell--small img{width:min(320px,100%)}
.post .gallery__cell--icon img{width:min(88px,100%)}

/* --- Contents -----------------------------------------------------------
   Was a tinted box of bullets. Now a white card in the same language as the
   homepage cards: hairline border, soft shadow, an uppercase label rather
   than a heading, and two columns so a ten-item list stops being a wall.

   It is a <details> so that the script in the article template can collapse
   it on a phone, where the old version filled an entire screen before the
   reader reached a single sentence. It ships open, so with no JavaScript at
   all the behaviour is exactly what it was before. */
.post__toc{
  background:#fff;
  border:1px solid var(--line);
  border-radius:var(--radius-media);
  box-shadow:0 6px 22px rgba(31,42,94,.07);
  padding:20px 26px 22px;
  margin:0 0 calc(var(--gap-block) * 1.2);
}
.post__toc>summary{
  list-style:none;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  font-family:var(--font-head);
  font-weight:800;
  color:var(--navy);
  text-transform:uppercase;
  letter-spacing:.09em;
  font-size:.76rem;
}
.post__toc>summary::-webkit-details-marker{display:none}
/* Chevron: down when the card is closed, up when it is open. It is the only
   thing telling the reader the card is a control, so it shows at every width -
   the summary is clickable on desktop too. */
.post__toc>summary::after{
  content:"";
  width:8px;height:8px;
  border-right:2px solid var(--indigo);
  border-bottom:2px solid var(--indigo);
  transform:translateY(-2px) rotate(45deg);
  transition:transform .2s ease;
  flex:none;
}
.post__toc[open]>summary::after{transform:translateY(2px) rotate(-135deg)}
.post__toc[open]>summary{margin-bottom:.9em}
.post__toc ul{
  list-style:none;
  margin:0;padding:0;
  columns:250px 2;
  column-gap:34px;
}
.post__toc li{
  break-inside:avoid;
  margin:0 0 .5em;
  font-size:.97rem;
  line-height:1.4;
}
.post__toc a{
  color:var(--ink-prose);
  text-decoration:none;
  border-bottom:1px solid transparent;
}
.post__toc a:hover{color:var(--indigo);border-bottom-color:currentColor}

/* --- In-article FAQ ----------------------------------------------------- */
.post__faq-item{border-radius:var(--radius-media);padding:0 20px}
.post__faq-item summary{padding:15px 0}
.post__faq-item .post__faq-a{padding-bottom:4px}
.post__faq-item .post__faq-a p{color:var(--ink-prose);padding-bottom:14px}

/* --- Keep Reading -------------------------------------------------------
   Text-only cards of uneven height, because each one printed a whole meta
   description. Every article now has a hero image, so these can carry the
   same photo-over-text card the homepage uses, and the excerpt is clamped so
   three cards in a row end level. */
.post__related{padding:64px 0}
.post__related h2{margin-bottom:1.1em}
.artgrid{grid-template-columns:repeat(auto-fit,minmax(272px,1fr));gap:22px}
/* The padding moves to __body so the photo can reach the card edge. Guarded by
   :has so a card rendered WITHOUT a body - the articles-grid component in
   sections.mjs still emits that shape - keeps its own padding from base.css
   instead of collapsing to an unpadded block. */
.artcard{border-radius:var(--radius-media);overflow:hidden}
.artcard:has(.artcard__body){padding:0}
.artcard__img{
  width:100%;
  aspect-ratio:3/2;
  object-fit:cover;
  display:block;
  background:var(--bg-alt);
}
.artcard__body{
  display:flex;
  flex-direction:column;
  flex:1;
  padding:16px 18px 18px;
}
.artcard h3{font-size:1.06rem;line-height:1.3;margin:0 0 .45em}

/* --- The articles index -------------------------------------------------
   Same card, used as a full catalogue rather than a three-up footer. Denser
   columns because there are 35 of them, and the title is the last thing in the
   card so it needs no bottom margin. */
.artgrid--index{grid-template-columns:repeat(auto-fill,minmax(248px,1fr));gap:20px}
.artgrid--index .artcard h3{margin:0;font-size:1.02rem}
.artgrid--index .artcard__body{padding:14px 16px 16px;justify-content:center}
@media(max-width:560px){
  .artgrid--index{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px}
  .artgrid--index .artcard h3{font-size:.94rem}
}
.artcard p{
  color:var(--muted);
  font-size:.9rem;
  line-height:1.55;
  margin:0 0 14px;
  display:-webkit-box;
  -webkit-line-clamp:3;
  -webkit-box-orient:vertical;
  overflow:hidden;
}

/* A masthead sets 20px of bottom padding and the section after it opens with
   70px of its own, so every page without a hero photo - the articles index
   among them - shows a ~90px void between the H1 and the first line of copy.
   Not article-specific; it belongs in base.css and moves there with the
   service-page pass, but it is one rule and the void is on a page this pass
   rebuilt. */
.masthead + .section{padding-top:30px}
/* …and the section's own first heading then adds 1.6em of its own on top of
   that padding. A first child never needs a top margin inside a padded box. */
.section > .container > h2:first-child,
.section > .container > .prose > h2:first-child,
.prose > h2:first-child{margin-top:0}

/* --- Narrow ------------------------------------------------------------- */
@media(max-width:820px){
  .post__body{padding-top:34px;font-size:1.06rem}
  .post__lead{font-size:1.2rem}
  .post{--gap-block:1.8em}
}
@media(max-width:700px){
  .post__toc{padding:16px 18px}
  .post__toc>summary{font-size:.74rem}
  .post__toc ul{columns:1}
  .post__toc li{margin-bottom:.62em}
  .post__figs--multi{grid-template-columns:1fr}
  .post__related{padding:44px 0}
}

/* ==========================================================================
   SERVICE AND LANDING PAGES
   Everything that is not an article: the money pages, the event pages, the
   utility pages. Loaded after article.css, so it wins over base.css.

   As with article.css, no new colour and no new typeface - every value here
   resolves to a token, and the section components are the ones that already
   exist. What changes is measure, rhythm and where the eye is asked to go.

   The three faults this fixes, all visible on /yacht-rental-san-diego/:

   1. MEASURE. A section marked align:"left" renders .prose--wide, capped at
      1080px. At the body size that is about 120 characters a line - roughly
      double the width at which a reader reliably finds the start of the next
      line. Long-form copy on a landing page is still long-form copy.

   2. RHYTHM. Every section paid 70px top and 70px bottom, so two sections in
      a row put 140px of nothing between two related thoughts, and a page of
      twelve sections became a scroll through a series of voids. The gap
      between sections should be smaller than the gap between the page's
      movements, and right now they are the same.

   3. WIDTH MISMATCH. The FAQ was capped at 820px and then split into two
      columns, giving each answer a 380px measure inside a 1180px page, with
      the right half of the band empty.
   ========================================================================== */

/* --- Measure ------------------------------------------------------------
   68ch at the body size, which is the same measure the article template uses.
   The container stays wide - it still holds the cards and the grids - but a
   run of prose inside it does not stretch to fill it. */
.prose--wide{max-width:none}
.prose--wide > p,
.prose--wide > ul,
.prose--wide > ol{max-width:68ch}
.prose--wide > h2.left{max-width:26ch}
/* Centred prose keeps its own narrower cap and stays centred. */
.prose > p{margin:0 0 1.15em}

/* --- Rhythm -------------------------------------------------------------
   One section's bottom padding and the next one's top padding are both doing
   the same job, so halve each and let the pair add up to a single step. A
   section that changes the background is a real break in the page and keeps
   the full measure, because there the padding is what stops the colour band
   from crowding its own contents. */
.section{padding:44px 0}
.section--alt,
.section--navy{padding:66px 0}
/* The first section under the hero opens the page and gets a little more. */
.hero + .section,
.masthead + .section{padding-top:38px}

/* A section heading already carries space above it in its own margin; the
   section padding does not need to repeat it. */
.section > .container > h2:first-child,
.section > .container > .prose > h2:first-child{margin-top:0}
.section > .container > .prose--wide > h2:first-child{margin-top:0}

/* --- Lists --------------------------------------------------------------
   A two-column checklist whose items differ wildly in length left one column
   running far below the other with no visual tie between them. Aligning to
   the top and giving the rows a real gap makes the pairing legible, and the
   tick keeps its own column so wrapped lines stay indented under the text
   rather than under the tick. */
.checklist{gap:16px 40px;align-items:start}
.checklist li{padding-left:28px;line-height:1.6}
.checklist li strong{color:var(--navy)}
.checklist--stack li{padding-left:28px}

/* --- FAQ ----------------------------------------------------------------
   Wider band, and the columns collapse before the answers get too narrow to
   read rather than at an arbitrary breakpoint. */
.faq{max-width:1000px}
.faq-cols{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:4px 40px}
.faq-cols h3{margin-top:1.2em;font-size:1.05rem;color:var(--navy)}
.faq-col:first-child h3:first-child,
.faq-cols h3:first-child{margin-top:0}
.faq details{margin-bottom:10px}

/* --- Side-by-side blocks ------------------------------------------------
   The media component is the page's one two-column layout. Give the photo the
   same shape and card treatment the rest of the site now uses, and keep the
   two halves aligned at the top so a short body does not float against a tall
   photo. */
.media__img img{
  width:100%;
  aspect-ratio:3/2;
  object-fit:cover;
  border-radius:10px;
  box-shadow:0 10px 30px rgba(31,42,94,.13);
  display:block;
}
.media__body > p{max-width:60ch}
.media__body h2{margin-top:0}

/* --- Cards --------------------------------------------------------------
   Equal heights and a consistent radius across the card components, so a row
   of three ends level whatever the copy does. */
.grid--3{align-items:stretch}
.feature,
.usecase,
.price-card{border-radius:10px}

/* --- Quick details panel -----------------------------------------------
   The scannable strip a service page carries just under the hero: six fixed
   facts, six fixed labels, one row. It is a <dl>, so it adds nothing to the
   page's heading outline, and it is deliberately NOT a card grid - a visitor
   reads it across, not down, and it must not compete with the benefit cards
   further down the page.

   The hairline dividers are a 1px grid gap over a --line ground rather than
   per-cell borders: with auto-fit columns the number of cells per row changes
   with the viewport, and borders leave a double line wherever a row wraps. */
.qd{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(168px,1fr));
  gap:1px;
  margin:0;
  background:var(--line);
  border:1px solid var(--line);
  border-radius:10px;
  overflow:hidden;
  box-shadow:var(--shadow);
}
.qd__item{background:var(--white);padding:20px 22px}
.qd__label{
  font-family:var(--font-head);
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:1.4px;
  font-size:.72rem;
  color:var(--muted);
  margin:0 0 6px;
}
.qd__value{
  margin:0;
  font-family:var(--font-head);
  font-weight:700;
  color:var(--navy);
  font-size:1.02rem;
  line-height:1.35;
}
/* Small print belongs under the panel, not inside a cell - a taxes-and-fees
   line in one cell makes that cell look like a seventh fact. */
.qd__note{max-width:68ch;margin:14px auto 0;font-size:.9rem;color:var(--muted);text-align:center}
.qd__cta{margin:20px 0 0;text-align:center}

/* --- Reviews on a money page -------------------------------------------
   The strip was designed for the homepage, directly under a dark hero. On a
   service page it sits on the pale ground, so it needs its own edge. */
.section > .container > .reviews{margin-inline:auto}

@media(max-width:820px){
  .section{padding:34px 0}
  .section--alt,
  .section--navy{padding:48px 0}
  .checklist{gap:14px 0}
  /* Two facts a row on a phone rather than one: six stacked cells push the
     first paragraph of the page a screen and a half down. */
  .qd{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
  .qd__item{padding:16px 16px}
}

/* --- Header drawer (global, not landing-page specific) ------------------
   The mobile nav is a fixed panel parked off-screen with translateX(100%).
   Being off-screen is not the same as being out of the layout: it still
   counts toward the viewport's scrollable overflow, so on a page with
   nothing else clipping it the document measured 614px wide at a 390px
   viewport and the whole page scrolled sideways. /on-the-web/ was the one
   page where that showed.

   overflow-x:clip on the root is what actually stops it: visibility:hidden
   does NOT take a fixed element out of Chrome's scrollable overflow region,
   and display:none would kill the slide-in transition. `clip` rather than
   `hidden` because `hidden` makes the root a scroll container and would
   break the sticky header.

   visibility is still worth setting: the closed drawer should not be in the
   tab order or read aloud, and right now every link in it is both. */
html{overflow-x:clip}
@media(max-width:900px){
  .nav__menu{visibility:hidden}
  .nav__menu.open{visibility:visible}
}

/* --- Left-aligned sections actually starting at the left ----------------
   Two components centre their own inner box inside the container: a checklist
   is wrapped in .prose (820px, auto margins) and a section intro is .lead
   (760px, auto margins). On a section marked align:"left" that put the
   heading and intro ~150px to the right of every other heading on the page,
   so a page alternating features and checklists had two different left edges.
   Only the centred variants should be centred. */
.section > .container > .prose:has(.checklist){max-width:none}
.section > .container > .lead:not(.center){margin-left:0}

/* ==========================================================================
   HOMEPAGE BOOKING JOURNEY  (Sept 2026)
   The homepage was twelve modules that each wrapped their content in a card:
   twelve review cards, four benefit cards, six occasion cards, five boat cards,
   eight article cards, nineteen FAQ rows. Everything had the same weight, so
   nothing led, and pricing sat below all of it.
   These rules serve one rule: cards are for CHOOSING BETWEEN ALTERNATIVES.
   Two sections qualify — the two booking paths, and the other boats. Every
   other block here is editorial: no shell, no border, no shadow.
   Nothing below redefines a token. Colours, fonts and radii come from
   tokens.css unchanged.
   ========================================================================== */

/* --- Section rhythm ------------------------------------------------------
   Major sections breathe; supporting ones (fleet, guides) are visibly lighter
   so the eye can tell a flagship experience from a footnote. Scoped to the
   homepage body class so the other 92 pages keep their existing spacing. */
body:has(#cruise-options) .section{padding:84px 0}
body:has(#cruise-options) #other-boats,
body:has(#cruise-options) #planning-guides{padding:52px 0}
body:has(#cruise-options) #other-boats h2,
body:has(#cruise-options) #planning-guides h2{font-size:clamp(1.45rem,2.1vw,1.7rem)}

/* --- Hero trust line -----------------------------------------------------
   One line, not twelve cards. */
.hero__trust{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 26px;font-size:1rem;color:#fff;
  text-shadow:0 1px 10px rgba(0,0,0,.5)}
.hero__trust-stars{color:var(--gold);letter-spacing:2px;font-size:1.05rem}
.hero__trust-text{font-family:var(--font-head);font-weight:600}
.hero__trust-link{color:rgba(255,255,255,.92);border-bottom:1px solid rgba(255,255,255,.45);
  font-size:.92rem;padding-bottom:1px}
.hero__trust-link::before{content:"";display:inline-block;width:4px;height:4px;border-radius:50%;
  background:rgba(255,255,255,.55);vertical-align:middle;margin:0 10px 3px -14px}
.hero__trust-link:hover{color:#fff;border-bottom-color:#fff;text-decoration:none}

/* --- Editorial split: one photo, unboxed proof points --------------------- */
.media--wide{grid-template-columns:1.15fr .85fr}
.media--wide.media--imgleft{grid-template-columns:1.15fr .85fr}
.proof{list-style:none;margin:26px 0 0;padding:0;display:grid;
  grid-template-columns:1fr 1fr;gap:22px 30px}
.proof__item{margin:0}
.proof__t{font-size:1.02rem;color:var(--navy);margin:0 0 .3em}
.proof__x{margin:0;color:var(--ink-soft);font-size:.95rem;line-height:1.55}
.proof__x a{color:var(--indigo)}

/* --- Occasion link rows --------------------------------------------------
   Six destinations, three rows. Previously six cards with six photos, six
   descriptions and six identical buttons — on a phone that was six full
   screens of scrolling to reach a list of six links. */
.linkrows{list-style:none;margin:24px 0 0;padding:0;border-top:1px solid var(--line)}
.linkrow{display:flex;align-items:center;flex-wrap:wrap;gap:0 10px;
  padding:16px 2px;border-bottom:1px solid var(--line);
  font-family:var(--font-head);font-weight:700;font-size:1.05rem}
.linkrow a{color:var(--navy);display:inline-block;padding:4px 0}
.linkrow a:hover{color:var(--indigo)}
.linkrow__sep{color:var(--line);font-weight:400}

/* --- Tour facade ---------------------------------------------------------
   The Matterport frame is built on click, never on load. */
.embed--facade{cursor:pointer;display:grid;place-items:center}
.embed__poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.embed__play{position:relative;z-index:1;box-shadow:0 10px 34px rgba(0,0,0,.35)}
.embed__fallback{text-align:center;margin:12px 0 0;font-size:.92rem}
.embed__fallback a{color:var(--indigo);display:inline-block;padding:12px 8px}
.section:has(> .container > .embed) .spec{margin-top:44px}

/* --- Guest proof: one quote, four photos --------------------------------- */
.gp{display:grid;grid-template-columns:.95fr 1.05fr;gap:44px;align-items:center}
.gp__stars{color:var(--gold);letter-spacing:3px;font-size:1.15rem}
.gp__quote blockquote{margin:14px 0 0;padding:0;border:0;
  font-family:var(--font-head);font-weight:600;font-size:1.3rem;line-height:1.5;
  color:var(--navy)}
.gp__quote blockquote::before{content:"\201C"}
.gp__quote blockquote::after{content:"\201D"}
.gp__by{margin:16px 0 0;color:var(--muted);font-size:.95rem}
.gp__src{display:inline-block;margin-top:10px;padding:10px 0;color:var(--indigo);font-weight:600;font-size:.95rem}
.gp__photos{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.gp__cell{margin:0;border-radius:var(--radius);overflow:hidden;aspect-ratio:1}
.gp__cell img{width:100%;height:100%;object-fit:cover;display:block}
.gp__followrow{margin:28px 0 0;text-align:center}
.gp__followrow a{color:var(--indigo);font-family:var(--font-head);font-weight:700;display:inline-block;padding:12px 10px}

/* --- Planning guides: editorial rows ------------------------------------- */
.guides{display:grid;gap:0;max-width:860px;margin:0 auto;border-top:1px solid var(--line)}
.guide{display:grid;grid-template-columns:104px 1fr auto;gap:20px;align-items:center;
  padding:18px 4px;border-bottom:1px solid var(--line);color:inherit}
.guide:hover{text-decoration:none;background:var(--tint-2)}
.guide__img{width:104px;height:72px;object-fit:cover;border-radius:4px;display:block}
.guide__body{display:block;min-width:0}
.guide__t{display:block;font-family:var(--font-head);font-weight:700;color:var(--navy);
  font-size:1.05rem;line-height:1.35}
.guide__x{display:block;margin-top:4px;color:var(--muted);font-size:.92rem;line-height:1.45}
.guide__go{color:var(--indigo);font-size:1.2rem}

/* --- FAQ tail + final band ----------------------------------------------- */
.faq__more{margin:26px 0 0;text-align:center}
.band__ctas{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-top:22px}
.band__ctas .btn{margin-top:0}
.band .btn--onnavy{background:transparent;color:#fff;border-color:rgba(255,255,255,.75)}
.band .btn--onnavy:hover{background:rgba(255,255,255,.14);color:#fff;border-color:#fff}

/* --- Focus: keyboard parity with hover ----------------------------------- */
.choice__cta:focus-visible,.embed__play:focus-visible,
.guide:focus-visible,.linkrow a:focus-visible,.hero__trust-link:focus-visible,
.band__ctas .btn:focus-visible{outline:3px solid var(--gold);outline-offset:3px}

/* --- Responsive ----------------------------------------------------------
   Content-driven. Nothing here hides content behind a horizontal carousel. */
@media(max-width:1023px){
  .gp{grid-template-columns:1fr;gap:30px}
  .media--wide,.media--wide.media--imgleft{grid-template-columns:1fr}
}
@media(max-width:820px){
  body:has(#cruise-options) .section{padding:52px 0}
  body:has(#cruise-options) #other-boats,
  body:has(#cruise-options) #planning-guides{padding:36px 0}
  .proof{grid-template-columns:1fr;gap:18px}
  .gp__quote blockquote{font-size:1.15rem}
}
@media(max-width:600px){
  .hero__trust{font-size:.93rem;gap:8px;margin-bottom:22px}
  .linkrow{font-size:1rem;padding:14px 2px}
  .linkrow a{padding:6px 0}
  .band__ctas .btn{width:100%;text-align:center}
  .band__ctas{flex-direction:column;align-items:stretch}
  .guide{grid-template-columns:76px 1fr;gap:14px;padding:16px 2px}
  .guide__img{width:76px;height:58px}
  .guide__go{display:none}
  .gp__photos{gap:10px}
  .embed__play{padding:14px 24px;font-size:1rem}
}

/* The spec sheet's section is inverted to brand indigo (see phone.css). Two
   things inside it were written for a light ground and disappear on that one:
   the section intro (--muted grey, 2.4:1 on indigo) and the tour's fallback
   link (indigo on indigo, invisible). Both are content, not decoration. */
.section:has(> .container > .spec) .lead{color:rgba(255,255,255,.84)}
.section:has(> .container > .spec) .embed__fallback a{color:#fff;text-decoration:underline}

@media(max-width:600px){
  /* The trust line wraps to two lines on a phone, and the separator dot then
     sits alone at the start of the second line looking like a bullet. */
  .hero__trust-link::before{display:none}
  .hero__trust{gap:4px 10px}
  .hero__trust-link{margin-top:2px}
  /* Two booking paths, equal weight, full width — a 40%-wide "Get Tickets"
     beside a 60%-wide "Private Charters" reads as a hierarchy that is not
     there. Scoped to the homepage: every other hero has a single CTA. */
  body:has(#cruise-options) .hero__cta{flex-direction:column;align-items:stretch}
  body:has(#cruise-options) .hero__cta .btn{width:100%;text-align:center}
}

/* The fleet track is five explicit columns above 981px, because the fleet was
   five boats. The homepage now recommends four — Triton is no longer one of
   its own recommendations — so five columns would leave a visible empty slot.
   Four across here; two up on a phone, because these are alternatives to
   glance at, not four full-screen cards to scroll past. */
@media(min-width:981px){
  body:has(#cruise-options) #other-boats .fleet{grid-template-columns:repeat(4,1fr);gap:22px}
}
@media(max-width:600px){
  body:has(#cruise-options) #other-boats .fleet{grid-template-columns:1fr 1fr;gap:14px}
  body:has(#cruise-options) #other-boats .boat__body{padding:14px}
  body:has(#cruise-options) #other-boats .boat__body h3{font-size:1rem;margin-bottom:.25em}
  body:has(#cruise-options) #other-boats .boat__body p{font-size:.82rem;line-height:1.45}
  body:has(#cruise-options) #other-boats .boat__cap{font-size:.78rem;margin-bottom:10px}
  body:has(#cruise-options) #other-boats .boat .btn{padding:9px 12px;font-size:.8rem}
}

.band__note{margin:18px 0 0;font-size:.95rem;color:rgba(255,255,255,.88)}
.band__note a{color:#fff;text-decoration:underline;display:inline-block;padding:6px 2px}
.band__note a:hover{color:#fff}
.proof__link{display:inline-block;margin-top:7px;font-weight:600}

/* ==========================================================================
   CRUISE OPTIONS & PRICING  — the comparison and the rates, in one section
   The page used to ask the same question twice: a comparison of the two ways
   to book, then a pricing band four screens further down covering the same two
   products. A visitor had to carry the first half in their head to read the
   second. Each option now owns its own price, conditions and action.
   Panels are white on the page's own ground — no dark band, no photographs,
   no badges. The only thing competing for attention inside a panel is its one
   filled button.
   ========================================================================== */
#cruise-options{padding:72px 0}
#cruise-options > .container{max-width:1120px;padding-left:32px;padding-right:32px}
#cruise-options > .container > h2{font-size:clamp(1.9rem,2.9vw,2.4rem);margin:0}
#cruise-options > .container > .lead{margin:14px auto 32px;font-size:1.05rem}

.choices{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:stretch}
.choice{background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:28px;display:flex;flex-direction:column;height:100%;box-shadow:none}
.choice__t{font-size:1.4rem;color:var(--navy);margin:0 0 .5em}
.choice__lead{margin:0 0 22px;color:var(--ink-soft);font-size:1rem;line-height:1.55}

/* Price block. The headline figure, a second figure on the same footing where
   there is one, then the conditions that figure depends on. The conditions are
   full-size body text: shrinking them to tidy the panel is how a "from" price
   becomes a misleading one. */
.choice__price{padding-bottom:20px;border-bottom:1px solid var(--line);margin-bottom:4px}
.choice__amt{font-family:var(--font-head);font-weight:800;font-size:2.15rem;
  color:var(--navy);margin:0;line-height:1.1}
.choice__unit{font-family:var(--font-body);font-size:1rem;font-weight:400;
  color:var(--muted);margin-left:10px}
.choice__alt{margin:8px 0 0;font-family:var(--font-head);font-weight:700;
  font-size:1.15rem;color:var(--navy)}
.choice__cond{margin:10px 0 0;color:var(--ink-soft);font-size:1rem;line-height:1.5}
.choice__rate{margin:8px 0 0;color:var(--muted);font-size:1rem;line-height:1.5}

/* Booking facts: label/value pairs, hairline-separated. No box per fact —
   a border around each one turns four short facts into four objects. */
.choice__facts{margin:0;padding:0}
.choice__fact{display:grid;grid-template-columns:8.5rem 1fr;gap:16px;
  padding:13px 0;border-bottom:1px solid var(--line)}
.choice__fact:last-child{border-bottom:0}
.choice__fact dt{font-family:var(--font-head);font-weight:700;color:var(--navy);
  font-size:.82rem;letter-spacing:.6px;text-transform:uppercase;margin:3px 0 0}
.choice__fact dd{margin:0;color:var(--ink-soft);font-size:1rem;line-height:1.5}
.choice__fact dd a{color:var(--indigo)}

.choice__actions{margin-top:auto;padding-top:24px}
.choice__cta{display:inline-block}
.choices__note{max-width:70ch;margin:32px auto 0;text-align:center;
  color:var(--muted);font-size:1rem;line-height:1.5}
.choices__note a{color:var(--indigo);font-weight:600}

/* The header is sticky, so an anchor that lands at the top of the viewport
   lands underneath it. Nothing on the site set a scroll margin, so every
   in-page link on all 93 pages scrolled its target out of sight. */
section[id],.faq-col[id]{scroll-margin-top:96px}

/* Two panels stay side by side down to 768px, as the spec asks. */
/* Below about 900px an 8.5rem label column leaves too little for the value,
   so the pairs stack rather than being squeezed. */
@media(max-width:899px){
  .choice{padding:22px}
  .choice__fact{grid-template-columns:1fr;gap:2px;padding:12px 0}
}
@media(max-width:767px){
  .choices{grid-template-columns:1fr;gap:20px}
  #cruise-options{padding:48px 0}
  #cruise-options > .container{padding-left:20px;padding-right:20px}
  #cruise-options > .container > h2{font-size:clamp(1.65rem,6vw,2rem)}
  .choice{padding:20px}
  .choice__t{font-size:1.3rem}
  .choice__amt{font-size:2rem}
  .choice__cta{display:block;width:100%;text-align:center;padding-top:14px;padding-bottom:14px}
  section[id],.faq-col[id]{scroll-margin-top:70px}
}

/* --- The ticketed cruise pages: harbor and sunset ------------------------
   Scoped with body:has(#cruise-timeline), the same idiom the homepage uses
   with #cruise-options. #cruise-timeline is the itinerary section's anchor,
   carried by the harbor cruise and sunset cruise pages and no others, so the
   two ticketed-cruise pages get one treatment and the other 91 are untouched.

   Everything here is a size or a weight, not a layout invention: the page's
   job is to get a visitor from "this looks fun" to a date on a calendar, and
   the strip, the fact panel and the spec sheet were all rendering at the size
   they use on pages where they are a footnote rather than the argument. */

/* Reviews. The shared strip is a horizontal scroller showing 4.3 cards, sized
   for a homepage row. Here it is three reviews the reader is meant to finish,
   so it becomes a plain three-up grid and the quotes come up to body size. */
body:has(#cruise-timeline) .review-grid{display:grid;grid-template-columns:repeat(3,1fr);
  gap:20px;overflow:visible;padding-bottom:0}
body:has(#cruise-timeline) .review-grid > .review-card{flex:none;padding:24px}
body:has(#cruise-timeline) .review-card p{font-size:1.02rem;line-height:1.62;-webkit-line-clamp:6}
body:has(#cruise-timeline) .review-card .who{font-size:1rem}
body:has(#cruise-timeline) .review-card .when{font-size:.82rem}
body:has(#cruise-timeline) .reviews__head{justify-content:center;padding:34px 0 20px;gap:14px}
body:has(#cruise-timeline) .reviews__score{font-size:1.45rem;letter-spacing:.5px}
body:has(#cruise-timeline) .reviews__count{font-size:1.05rem}
body:has(#cruise-timeline) .stars--lg{font-size:1.45rem}
@media(max-width:900px){
  body:has(#cruise-timeline) .review-grid{grid-template-columns:1fr;gap:14px}
}

/* Quick Facts. This panel answers how long, where, how much and can kids come
   — the six questions that decide the booking — so it should not be set two
   steps smaller than the prose underneath it. */
body:has(#cruise-timeline) .qd__item{padding:24px 24px}
body:has(#cruise-timeline) .qd__label{font-size:.76rem}
body:has(#cruise-timeline) .qd__value{font-size:1.16rem}
@media(max-width:820px){
  body:has(#cruise-timeline) .qd__item{padding:17px 16px}
  body:has(#cruise-timeline) .qd__value{font-size:1.05rem}
}

/* What's Included. The indigo inversion is right and stays. What goes is the
   white card behind every single tick: eight drop-shadowed boxes turned a
   plain list of facts into eight things to look at. Flat white ticks on the
   indigo ground, two columns, which is what the markup was already shaped for. */
body:has(#cruise-timeline) .section:has(> .container > .spec) .spec__list{gap:14px 34px}
body:has(#cruise-timeline) .section:has(> .container > .spec) .spec__list li{
  background:none;box-shadow:none;border-radius:0;padding:0;color:#fff;
  font-size:1rem;line-height:1.55;align-items:flex-start}
body:has(#cruise-timeline) .section:has(> .container > .spec) .spec__tick{
  background:rgba(255,255,255,.20);margin-top:3px}
@media(max-width:600px){
  body:has(#cruise-timeline) .section:has(> .container > .spec) .spec__list li{
    padding:0;font-size:.93rem}
}

/* Aboard. Three blocks replaced six cards, which is right on desktop and
   wrong in the site's two-up phone grid: three children there is a pair plus
   an orphan. These are long blocks with a photo each, so on a phone they
   stack. */
@media(max-width:700px){
  body:has(#cruise-timeline) #benefits .grid--3{grid-template-columns:1fr;gap:16px}
  body:has(#cruise-timeline) #benefits .feature__img{height:150px}
  body:has(#cruise-timeline) #benefits .feature h3{font-size:1.05rem}
  body:has(#cruise-timeline) #benefits .feature p{font-size:.9rem}
}

/* Landmarks. The photography is doing the selling here, so the cards get
   height and the labels come up off the floor. */
body:has(#cruise-timeline) .usecase{min-height:300px}
body:has(#cruise-timeline) .usecase h3{font-size:1.22rem}
body:has(#cruise-timeline) .usecase p{font-size:.95rem}
@media(max-width:700px){
  body:has(#cruise-timeline) .usecase{min-height:200px}
  body:has(#cruise-timeline) .usecase h3{font-size:1rem}
  body:has(#cruise-timeline) .usecase p{font-size:.84rem}
}

/* The tickets block can now carry two buttons, one per boat. They need the gap
   the closing band's pair already has. Unscoped on purpose: only a pricing
   block that sets "ctas" renders this element, which today is two pages. */
.price-ctas{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
.price-ctas .btn{margin-top:0}

/* --- Homepage: Cruise Options & Pricing, inverted -------------------------
   The two panels were white on the page's own near-white ground, which made
   the section that decides how someone books the quietest thing on the page.
   They are now indigo with white type: the same cards, the other way round.

   Scoped to #cruise-options, which exists on the homepage and nowhere else.
   The card's structure is carried by three separate --line borders - the card
   edge, the rule under the price, and the rule under each fact row - so all
   three lift off the dark ground or the panel loses its divisions. */
#cruise-options .choice{background:var(--indigo);border-color:var(--indigo);color:#fff}
#cruise-options .choice__t{color:#fff}
#cruise-options .choice__lead{color:rgba(255,255,255,.86)}
#cruise-options .choice__price{border-bottom-color:rgba(255,255,255,.24)}
#cruise-options .choice__amt{color:#fff}
#cruise-options .choice__unit{color:rgba(255,255,255,.74)}
#cruise-options .choice__alt{color:#fff}
#cruise-options .choice__cond{color:rgba(255,255,255,.84)}
#cruise-options .choice__fact{border-bottom-color:rgba(255,255,255,.20)}
#cruise-options .choice__fact dt{color:rgba(255,255,255,.74)}
#cruise-options .choice__fact dd{color:rgba(255,255,255,.93)}
#cruise-options .choice__fact dd a{color:#fff;text-decoration:underline}
/* The button was indigo-on-white inside a white card. On an indigo card that
   is a button you cannot see, so it inverts too - the same swap .band .btn
   already makes. The 2px border comes with it or the white face sits inside
   an indigo outline. */
#cruise-options .choice__cta{background:#fff;color:var(--indigo);border-color:#fff}
#cruise-options .choice__cta:hover{background:#eef1ff;color:var(--indigo-dark);border-color:#eef1ff}

/* Pricing with 5+ tiers: centred rows of four on desktop, three on tablet,
   two on phones, so an odd last row sits in the middle. */
.pricing--rows{display:flex;flex-wrap:wrap;justify-content:center;gap:16px}
.pricing--rows .price-card{flex:0 0 calc((100% - 48px) / 4);min-width:0;box-sizing:border-box}
@media(max-width:900px){.pricing--rows .price-card{flex-basis:calc((100% - 32px) / 3)}}
@media(max-width:600px){.pricing--rows .price-card{flex-basis:calc((100% - 16px) / 2);padding:16px}.pricing--rows .price-card .amt{font-size:1.5rem}}

/* ==========================================================================
   PAGE-SPECIFIC OVERRIDES — loaded last (see theme/css.json).
   Small, named exceptions to the shared rules. Pages have no body class, so a
   page is targeted through its canonical link.
   ========================================================================== */

/* /yacht-rental-san-diego/ — "Our San Diego Yacht Rental" runs the full width
   of the container instead of the 68ch reading measure that .prose--wide
   applies to paragraphs everywhere else. Owner's call, this section only. */
html:has(link[rel="canonical"][href$="/yacht-rental-san-diego/"]) section[data-edit-id="intro"] .prose--wide > *{max-width:none}

/* Chat widget vs. the charter builder's fixed checkout bar. On a phone both
   sit in the bottom-right corner, and the chat bubble landed squarely on the
   "Send Proposal" button. While the builder is on screen (body.pb-onscreen,
   set by proposal-builder.mjs) the chat steps aside; it returns as soon as the
   visitor scrolls past the builder. Desktop has no checkout bar, so no clash. */
@media(max-width:820px){
  body.pb-onscreen chat-widget{display:none}
}

.masthead{padding-top:40px;padding-bottom:20px}.masthead h1{color:var(--navy);font-size:clamp(2rem,4vw,3.2rem)}
