/**
 * @file S/Y Celestine: the inner pages' stylesheet (itineraries.html, usvi.html, bvi.html, style-guide.html).
 *
 * The markup it styles is written by tools/chart-pages.py; the behaviour it responds to comes from
 * assets/pages.js. The homepage does not load this file. index.html carries its own styles inline, and
 * the two share one set of tokens: the :root block below mirrors index.html's exactly, and the two must
 * be kept in step (tools/build-docs.py reports any token whose value differs between them).
 *
 * How the file is organised: tokens, font fallbacks and base rules first, then the shared voice and
 * components (buttons, nav, reveal, charts), then one block per page section in page order, then the
 * footer and floating bar, and last the two global switches (reduced motion, ?static).
 *
 * Conventions:
 *   - Colour, type size, measure and section spacing come from tokens. A raw hex or a hand-picked width
 *     in a rule is a bug (DESIGN.md: The Three Pins Rule, The Column Span Rule, The One Margin Rule).
 *   - A section is navy (text in Sea Glass) or Canvas (text in navy or Chart Ink). A component used on
 *     both grounds follows its Canvas rules and re-inks them in Sea Glass steps (The Two Worlds Rule).
 *     Nothing does today: .between and .close are navy throughout, and the plans are Canvas.
 *   - State is carried by classes and data attributes that pages.js sets (.is-in, .active, .split-on,
 *     .bg-on, data-open, data-shown, data-active). Script never writes a colour or a transition.
 *   - A single-column grid track is minmax(0, 1fr), never a bare 1fr (The Shrinkable Track Rule).
 *   - Every animation has a counterpart in the reduced-motion block at the foot of the file.
 *
 * Doc comments: a block like this one documents what follows it. Tags, modelled on JSDoc:
 *   @section Name         opens a section of the reference; prose after it describes the section
 *   @token --name         a global custom property set on :root
 *   @var --name           a custom property scoped to a component, set inline by the generator or by script
 *   @rule selector        what a selector, or a group of them, is for
 *   @modifier selector    a variant of the rule above it
 *   @state selector       a state of the rule above it, and what puts it there
 *   @hook selector        a class or attribute that script sets or reads
 *   @breakpoint width     what changes at a width
 *   @see                  where the reasoning lives, usually a named rule in DESIGN.md
 * tools/build-docs.py reads these into docs/css.html and into the style guide's token table. Plain
 * comments beside a declaration are left as they are: they explain one value, in place.
 */

/**
 * @section Tokens
 * Every colour, type size, measure and spacing step on the inner pages. The palette is three pinned
 * colours (Celestine Navy, Chart Ink, Sea Glass) plus Harbor Coral; every other colour is a lightness
 * step inside one of those families, computed to hit a contrast target. The -rgb tokens are channel
 * triplets for translucent steps: rgb(var(--seaglass-rgb) / 0.72).
 * @see DESIGN.md, Colors; The Three Pins Rule
 *
 * @token --navy-core         Celestine Navy. The pinned anchor: every navy field, the chart field, photo wells, the theme colour.
 * @token --navy-shade        Night Watch. The darker navy step: one of the two stripes of the homepage's virtual tour field.
 * @token --navy-deep         Midnight Hull. Text on frost, dark buttons, badges, overlays and the footer.
 * @token --navy-core-rgb     Celestine Navy as channels, for navy washes and legibility halos.
 * @token --navy-deep-rgb     Midnight Hull as channels, for overlays (0.72 to 0.96) and muted calendar days (0.62).
 * @token --steel-ink         Chart Ink. The pinned charcoal: body and secondary text on frost, fine linework.
 * @token --steel-shade       Harbor Steel. Supporting text and the base link colour. A Canvas-surface colour: never on a photograph or on navy.
 * @token --steel-blue        Steel Blue. The focus ring, chosen to clear 3:1 against navy, Canvas and Sea Glass at once; small accents.
 * @token --slate-muted       Slate Muted. Muted small print. A Canvas-surface colour.
 * @token --sky-tint          Shallow Water. Highlights on navy: chart pins, key numerals, the weather reading; open days in the calendar.
 * @token --harbor-sky        Harbor Sky. Secondary action fill (with Midnight Hull text), gauge fills, the on-hold stripe, text selection.
 * @token --harbor-sky-rgb    Harbor Sky as channels.
 * @token --pale-sky          Pale Sky. Quiet panels, and the base of the calendar's on-hold stripe.
 * @token --seaglass          Sea Glass. The pinned pale: the text colour on every navy field, small chrome on navy, the hover fill of dark buttons.
 * @token --seaglass-rgb      Sea Glass as channels: borders, ghost outlines and secondary text on navy (0.12 to 0.95).
 * @token --canvas            Canvas. The one light section surface. A background only, never a text colour.
 * @token --canvas-rgb        Canvas as channels: the wash over the homepage's photographic light sections. Homepage only.
 * @token --seaglass-light    Sea Glass Light. The polaroid mat around plates and chart insets, and caption panels.
 * @token --seaglass-deep     Sea Glass Deep. What shows behind a photograph while it loads.
 * @token --seaglass-deep-rgb Sea Glass Deep as channels.
 * @token --seaglass-mist       Sea Glass Mist. The slow-drifting haze inside the rate table. Homepage only.
 * @token --seaglass-mist-clear The same colour at zero alpha, so the haze's gradients fade without greying. Homepage only.
 * @token --chart-rule        Chart Rule. Hairlines between log entries, facts and notes. Quiet on purpose: it marks an edge, not a boundary anyone reads.
 * @token --chart-label       Chart Label. Tracked uppercase annotations on Canvas: places, days, captions. A Canvas-surface colour.
 * @token --harbor-coral      Harbor Coral. The one warm colour. The primary booking action and nothing else, always with Midnight Hull text.
 * @token --nav-glass         Nav Glass. Once the translucent nav bar over the homepage hero; unused now that the bar has no background.
 * @token --nav-glass-rgb     Nav Glass as channels. The plate behind the homepage's hero headline on a phone.
 * @token --blueprint-gain-1  Multiply gain that rescales the blueprint1 plate so its field lands on Celestine Navy. Asset-bound: re-measure if the plate is redrawn.
 * @token --blueprint-gain-2  The same for the blueprint2 plate, behind the closing section.
 * @token --font-display      Cormorant Garamond, then its metric-matched fallback. The voice: headings, ledes, names.
 * @token --font-body         Jost, then its metric-matched fallback. Everything you read or count: paragraphs, figures, links in prose.
 * @token --font-label        Jost again, under its own name. The tracked uppercase label voice: navigation, buttons, captions, chart furniture.
 * @token --type-display      Display: the homepage hero headline only.
 * @token --type-headline     Headline: section titles.
 * @token --type-subhead      Subhead: a second heading inside a section.
 * @token --type-title-lg     Title L: closing index headings, the homepage's wide plate names and menu links.
 * @token --type-title        Title: every card and entry heading.
 * @token --type-title-sm     Title S: small titles, and every tile title on a phone.
 * @token --type-lead         Lead: the one serif paragraph that introduces a section.
 * @token --type-serif        Serif text: serif running text inside a component.
 * @token --type-body         Body: Jost 300 paragraphs.
 * @token --type-body-navy    Body on navy: one step up, because light text on a dark field reads smaller. The closing paragraph; the homepage's destination blurbs.
 * @token --type-small        Small: secondary facts and credits.
 * @token --type-label        Label: the floor for tracked uppercase annotations.
 * @token --leading-serif     Line height for serif running text.
 * @token --leading-body      Line height for body copy.
 * @token --leading-title     Line height for titles.
 * @token --ease-reveal       The one easing curve for entrances: soft, decelerating.
 * @token --grid-cols         Columns in the page grid. Informational; the spans below are what rules use. Homepage only.
 * @token --grid-max          Full width of the nine-column page grid.
 * @token --gutter            Gutter between columns.
 * @token --col               One column, derived from the two above.
 * @token --span-3            Three columns and their two gutters. Spans 4 to 8 follow the same pattern.
 * @token --span-4            Four columns.
 * @token --span-5            Five columns: the measure for a lede.
 * @token --span-6            Six columns.
 * @token --span-7            Seven columns.
 * @token --span-8            Eight columns.
 * @token --measure-read      Reading container (span 6).
 * @token --measure-mid       Mid container (span 7).
 * @token --measure-wide      Wide container (span 8).
 * @token --measure-full      The whole grid (span 9).
 * @token --section-x         Horizontal page margin. The only source of it: anything that breaks the margin computes from this.
 * @token --section-y         Default vertical section padding.
 * @token --section-y-lg      Emphasis step: the homepage's availability section, and the main sections of these pages.
 * @token --section-y-xl      Emphasis step for the closing booking section.
 * @token --nav-h             Height of the fixed nav bar: hero top padding, sticky offsets and scroll margins clear it. These pages only.
 *
 * @breakpoint 768px Margins, vertical rhythm, gutter and nav height step down together. Vertical rhythm goes lower on a phone, not higher.
 */
:root {
  --navy-core: #061e45; --navy-shade: #041530; --navy-deep: #020c1d;
  --navy-core-rgb: 6 30 69; --navy-deep-rgb: 2 12 29;
  --steel-ink: #36454f; --steel-shade: #4a5f6d; --steel-blue: #5b7d90; --slate-muted: #566771;
  --sky-tint: #9dc4d2; --harbor-sky: #7fa8b8; --harbor-sky-rgb: 127 168 184; --pale-sky: #d6ecf1;
  --seaglass: #c3e3eb; --seaglass-rgb: 195 227 235;
  --canvas: #eaf3f6; --seaglass-light: #f4fafc; --seaglass-deep: #cfdfe5; --seaglass-deep-rgb: 207 223 229;
  --chart-rule: #a9cbd6; --chart-label: #3d6b7d;
  --harbor-coral: #ff5a5f;
  --nav-glass: rgb(205 224 231 / 0.72); --nav-glass-rgb: 205 224 231;
  --blueprint-gain-1: #4096ae; --blueprint-gain-2: #3d90ac;
  color-scheme: light;
  --font-display: 'Cormorant Garamond', 'Cormorant Fallback', Georgia, serif;
  --font-body: 'Jost', 'Jost Fallback', system-ui, sans-serif;
  --font-label: 'Jost', 'Jost Fallback', system-ui, sans-serif;
  /* Type roles. Cormorant's x-height is 0.386em to Jost's 0.460em, so serif running text is
     set about 1.19x the sans beside it: --type-serif (20px) sits level with --type-body (17px). */
  --type-display: clamp(48px, 8vw, 92px);
  --type-headline: clamp(38px, 9vw, 58px);
  --type-subhead: clamp(30px, 7vw, 44px);
  --type-title-lg: 34px; --type-title: 28px; --type-title-sm: 24px;
  --type-lead: 22px; --type-serif: 20px; --type-body: 17px; --type-body-navy: 18px; --type-small: 14px; --type-label: 12px;
  --leading-serif: 1.5; --leading-body: 1.65; --leading-title: 1.15;
  --ease-reveal: cubic-bezier(0.22, 0.61, 0.36, 1);

  --grid-max: 1040px; --gutter: 32px;
  --col: calc((var(--grid-max) - 8 * var(--gutter)) / 9);
  --span-3: calc(3 * var(--col) + 2 * var(--gutter));
  --span-4: calc(4 * var(--col) + 3 * var(--gutter));
  --span-5: calc(5 * var(--col) + 4 * var(--gutter));
  --span-6: calc(6 * var(--col) + 5 * var(--gutter));
  --span-7: calc(7 * var(--col) + 6 * var(--gutter));
  --span-8: calc(8 * var(--col) + 7 * var(--gutter));
  --measure-read: var(--span-6); --measure-mid: var(--span-7); --measure-wide: var(--span-8); --measure-full: var(--grid-max);

  --section-x: 56px; --section-y: 56px; --section-y-lg: 96px; --section-y-xl: 128px;
  --nav-h: 89px;
}
@media (max-width: 768px) {
  :root { --section-x: 24px; --section-y: 64px; --section-y-lg: 64px; --section-y-xl: 80px; --gutter: 24px; --nav-h: 70px; }
}

/**
 * @section Font fallbacks
 * Metric-matched stand-ins, measured against the webfonts, so the swap does not re-wrap the page. The
 * webfonts load asynchronously with display=swap; until they arrive Georgia and Arial stand in, scaled
 * and with their ascent and descent overridden so every line break stays where it was.
 *
 * @rule @font-face 'Cormorant Fallback'  Georgia at 88.4%.
 * @rule @font-face 'Jost Fallback'       Arial at 92.8%. Body copy and the label voice.
 * @see DESIGN.md, Typography: Roles are tokens
 */
@font-face { font-family: 'Cormorant Fallback'; src: local('Georgia'); size-adjust: 88.4%; ascent-override: 104.7%; descent-override: 32.3%; line-gap-override: 0%; }
@font-face { font-family: 'Jost Fallback'; src: local('Arial'); size-adjust: 92.8%; ascent-override: 115.3%; descent-override: 40.4%; line-gap-override: 0%; }

/**
 * @section Base
 * The reset, the page defaults and the accessibility helpers.
 *
 * @rule *                  Border-box sizing and no default margins: every gap on the page is set on purpose.
 * @rule html               Smooth in-page scrolling (made instant under reduced motion) and a scrollbar in the palette.
 * @rule body               Canvas ground, Midnight Hull text, Jost 300 at Body size. lining-nums site-wide, because
 *                          figures here are data and Cormorant's old-style 1 and 0 read as letters (The Plain Figures Rule).
 * @rule ::selection        Harbor Sky with Midnight Hull text.
 * @rule a                  Harbor Steel, Celestine Navy on hover. Right for Canvas only: a navy surface names its own link colour.
 * @rule :focus-visible     The site-wide focus ring: 3px Steel Blue, 3px offset. Sea Glass on the navy surfaces, where Steel Blue is too quiet.
 * @rule p, li, dd          text-wrap: pretty, so no paragraph ends on a lone word.
 * @rule h1, h2, h3         Cormorant 400. Bold is not part of the system (The Light Hand Rule).
 * @rule .vh                Visually hidden, still read aloud.
 * @rule .skip-link         "Skip to content", off screen until it takes focus.
 */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; scrollbar-color: var(--steel-blue) var(--canvas); }
body { background: var(--canvas); color: var(--navy-deep); font-family: var(--font-body); font-weight: 300; font-size: var(--type-body); line-height: var(--leading-body); font-variant-numeric: lining-nums; overflow-x: hidden; }
::selection { background: var(--harbor-sky); color: var(--navy-deep); }
a { color: var(--steel-shade); }
a:hover { color: var(--navy-core); }
:focus-visible { outline: 3px solid var(--steel-blue); outline-offset: 3px; border-radius: 2px; }
footer :focus-visible, .site-nav :focus-visible, #mobile-menu :focus-visible { outline-color: var(--seaglass); }
img { max-width: 100%; }
i, em { font-style: italic; }
p, li, dd { text-wrap: pretty; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 400; }
.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: 12px; top: -60px; z-index: 200; background: var(--navy-deep); color: var(--seaglass); font-size: 14px; letter-spacing: 2px; text-transform: uppercase; padding: 12px 20px; text-decoration: none; transition: top 0.2s; }
.skip-link:focus { top: 12px; color: var(--seaglass); }
.skip-link:hover { color: var(--seaglass); }

/**
 * @section Voice
 * Serif for things you would say, tracked uppercase Jost for things you would annotate, light Jost for everything you read or count.
 * @see DESIGN.md, The Logbook Voice Rule; The One Weight Per Voice Rule
 *
 * @rule .label   The annotation voice: Jost 400, 12px, uppercase, 3px tracking.
 * @rule .lede    The introducing paragraph: Cormorant 400 at Lead size.
 * @rule (the two weight groups)  One weight per voice. body is Jost 300, so every label and every serif fragment
 *                that is not a heading is named here and set to 400, and the label group is also where labels take
 *                --font-label. A new label or serif class joins the matching group.
 * @rule .between a:not(.btn), .close a:not(.btn)  Prose links on navy inherit the field's Sea Glass.
 * @rule section[id]   Anchored sections stop clear of the fixed nav.
 */
.label { font-family: var(--font-label); font-weight: 400; font-size: 12px; letter-spacing: 3px; text-transform: uppercase; }
.lede { font-family: var(--font-display); font-weight: 400; font-size: var(--type-lead); line-height: var(--leading-serif); }
/* One weight per voice, and one face per voice. Cormorant ships at 400 only, and the label voice is Jost 400
   as on the homepage; without these, both inherit body's 300 (a weight the serif does not have). Labels name --font-label
   so the label voice can change face without touching body copy. */
.plan-facts li, .notes dt, .between dt, .key .name, .more a .t, #mobile-menu a, .mapbox-fail { font-weight: 400; }
.skip-link, .nav-links a, .chart-hint, .chart-key, .plan-facts small, .chart-cap, .leg-when, .leg-sail, .tags, .gauge,
.key .where, .entry .where, .inset figcaption, .inset .scalebar, .mapbox-where, .mapbox-foot, .band figcaption, footer .wx-place { font-family: var(--font-label); font-weight: 400; }
/* Prose links on the navy fields take the field's Sea Glass, as #destinations and #book do on index.html; left to the
   base rule they were Harbor Steel on navy (2.5:1) and navy on navy on hover. Buttons keep their own colors. */
.between a:not(.btn), .close a:not(.btn) { color: inherit; }
section[id] { scroll-margin-top: var(--nav-h); }

/**
 * @section Buttons
 * Square, tracked, quiet colour swaps. Corners have no radius; pills are for icon-only controls. Every
 * button is a link: there are no forms on the site, and every action leaves for a phone call, an
 * email or the Charter Smarter booking form.
 * @see DESIGN.md, Buttons; The One Coral Rule
 *
 * @rule .btn               The base: label voice at 12px with 4px tracking, 18px by 26px padding, 132px minimum width, 0.25s colour swaps.
 * @modifier .btn-primary   Harbor Coral with Midnight Hull text. One per view, and only for booking.
 * @modifier .btn-dark      Midnight Hull at 92% with Sea Glass text: Call and Email in the floating bar.
 * @modifier .btn-sky       Harbor Sky with Midnight Hull text, in the larger 14px size: secondary actions on navy.
 * @modifier .btn-ghost     A 1px Sea Glass outline at 50% with Sea Glass text, 14px: navy fields only.
 * @state :hover            Every filled button swaps to a Sea Glass fill with Midnight Hull text; the ghost firms its outline and takes a 10% fill.
 */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; font-family: var(--font-label); font-weight: 400; font-size: 12px; letter-spacing: 4px; text-transform: uppercase; text-decoration: none; padding: 18px 26px; min-width: 132px; transition: background 0.25s, color 0.25s, border-color 0.25s; }
.btn-primary { background: var(--harbor-coral); color: var(--navy-deep); }
.btn-primary:hover { background: var(--seaglass); color: var(--navy-deep); }
.btn-dark { background: rgb(var(--navy-deep-rgb) / 0.92); color: var(--seaglass); }
.btn-dark:hover { background: var(--seaglass); color: var(--navy-deep); }
.btn-sky { background: var(--harbor-sky); color: var(--navy-deep); font-size: 14px; letter-spacing: 2px; padding: 18px 40px; }
.btn-sky:hover { background: var(--seaglass); color: var(--navy-deep); }
.btn-ghost { border: 1px solid rgb(var(--seaglass-rgb) / 0.5); color: var(--seaglass); font-size: 14px; letter-spacing: 2px; padding: 18px 40px; }
.btn-ghost:hover { border-color: var(--seaglass); background: rgb(var(--seaglass-rgb) / 0.1); color: var(--seaglass); }

/**
 * @section Navigation
 * Inner pages open in the scrolled navy state; there is no light hero to sit over. A fixed navy bar
 * with the logo and six uppercase links back to the homepage's sections. At 920px and below the links
 * give way to the burger, which opens #mobile-menu: a navy drawer from the right, marked up as a modal
 * dialog, with a second group linking the three inner pages.
 * @see DESIGN.md, Navigation; Inner Page Chrome
 *
 * @rule .site-nav                   The fixed bar. Its height is --nav-h, which other rules clear.
 * @rule .site-nav img               The logo in Sea Glass. Its file is used as a mask over a --seaglass fill, not tinted by filter.
 * @rule img.mark-seaglass           The same recolour for the mark anywhere else on navy (the style guide uses it).
 * @rule .nav-links a                13px label voice at 85%, full strength on hover.
 * @state .nav-links a[aria-current]  Where you are: full strength, with a 1px hairline drawn 8px below the label.
 *                                   Drawn as a pseudo-element because text-decoration would run on under the trailing tracking.
 * @rule .nav-burger                 A 44px target holding three wave-shaped bars (an SVG mask over a Sea Glass fill).
 * @state .nav-burger.active         The bars cross into an X. Set by pages.js while the drawer is open.
 * @rule #mobile-menu                The drawer: full width up to 20rem, 30px Cormorant links in Sea Glass.
 * @hook #mobile-menu[data-open="yes"]  Displays the drawer. Written by pages.js.
 * @rule #mobile-menu .menu-group    A group of links. The second group sits under a hairline and a .label heading.
 * @rule #mobile-menu a.btn          The drawer's Book button. It restates its ink because the id rule above outranks .btn-primary.
 * @breakpoint 920px  Links hide, the burger shows.
 * @breakpoint 768px  The bar and the drawer tighten their padding.
 */
.site-nav { position: fixed; top: 0; left: 0; right: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 32px; padding: 21px var(--section-x); background: var(--navy-core); border-bottom: 1px solid rgb(var(--seaglass-rgb) / 0.18); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); }
.site-nav > a:first-child { display: flex; align-items: center; flex-shrink: 0; margin-right: 24px; }
/* The mark in Sea Glass, as in index.html: the file is only the stencil, a mask over a token fill (the way the burger
   is drawn), and the img's own pixels are pushed out of its box. Not a filter chain: one lands on its colour only where
   every step is clamped, and iOS Safari does not clamp (it drew the nav's mark cyan and the footer's old ivory chain yellow). */
.site-nav img, footer .marks img.logo, img.mark-seaglass { background: var(--seaglass); -webkit-mask: url("Celestine-Logo.svg") center / contain no-repeat; mask: url("Celestine-Logo.svg") center / contain no-repeat; object-position: -999px 0; }
.site-nav img { height: 46px; width: auto; }
.nav-links { display: flex; gap: 40px; align-items: center; }
.nav-links a { color: var(--seaglass); opacity: 0.85; text-decoration: none; font-size: 13px; letter-spacing: 2px; text-transform: uppercase; transition: opacity 0.2s; }
.nav-links a:hover, .nav-links a[aria-current] { opacity: 1; }
/* Where you are: the same drawn hairline as index.html's nav, stopping at the last letter rather than under its trailing tracking. */
.nav-links a { position: relative; }
.nav-links a[aria-current]::after { content: ""; position: absolute; left: 0; right: 2px; bottom: -8px; height: 1px; background: currentColor; }
.nav-burger { display: none; position: relative; width: 44px; height: 44px; cursor: pointer; background: none; border: none; padding: 0; flex: none; z-index: 41; }
.nav-burger span { position: absolute; left: 9px; width: 26px; height: 8px; background: var(--seaglass); transition: top 0.3s, transform 0.3s, opacity 0.3s; -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 8'><path d='M0 4 Q6.5 0.5 13 4 T26 4' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'/></svg>") center / 26px 8px no-repeat; mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 8'><path d='M0 4 Q6.5 0.5 13 4 T26 4' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'/></svg>") center / 26px 8px no-repeat; }
.nav-burger span:nth-child(1) { top: 7px; }
.nav-burger span:nth-child(2) { top: 18px; }
.nav-burger span:nth-child(3) { top: 29px; }
.nav-burger.active span:nth-child(1) { top: 18px; transform: rotate(45deg); }
.nav-burger.active span:nth-child(2) { opacity: 0; }
.nav-burger.active span:nth-child(3) { top: 18px; transform: rotate(-45deg); }
#mobile-menu { position: fixed; top: 0; right: 0; bottom: 0; width: 100%; max-width: 20rem; z-index: 30; background: var(--navy-core); display: none; flex-direction: column; align-items: flex-start; justify-content: center; gap: 22px; padding: 56px; box-shadow: -8px 0 32px rgba(0,0,0,0.2); }
#mobile-menu[data-open="yes"] { display: flex; }
#mobile-menu a { color: var(--seaglass); text-decoration: none; font-family: var(--font-display); font-size: 30px; line-height: 1.1; }
#mobile-menu a[aria-current] { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 8px; text-decoration-color: rgb(var(--seaglass-rgb) / 0.6); }
#mobile-menu .menu-group { display: flex; flex-direction: column; gap: 10px; }
#mobile-menu .menu-group + .menu-group { margin-top: 6px; padding-top: 18px; border-top: 1px solid rgb(var(--seaglass-rgb) / 0.18); width: 100%; }
#mobile-menu .menu-group .label { color: rgb(var(--seaglass-rgb) / 0.72); }
/* The id rule above outranks .btn-primary, which left Book in Sea Glass on coral (2.3:1) and Sea Glass on Sea Glass on hover. */
#mobile-menu a.btn { font-family: var(--font-label); font-size: 12px; margin-top: 12px; color: var(--navy-deep); }
@media (max-width: 920px) {
  .nav-burger { display: block; }
  .nav-links { display: none; }
}
@media (max-width: 768px) {
  .site-nav { padding: 12px var(--section-x); }
  #mobile-menu { padding: 40px 32px; }
}

/**
 * @section Reveal
 * Same grammar as the homepage: slow, soft, once. A block starts 36px low and transparent, and rises
 * over 0.8s when pages.js marks it as entered. Without script it stays hidden.
 *
 * @rule .reveal                  The resting state.
 * @hook .reveal.reveal-visible   Entered. Added once by pages.js, never removed.
 */
.reveal { opacity: 0; transform: translateY(36px); transition: opacity 0.8s ease, transform 0.8s ease; }
.reveal.reveal-visible { opacity: 1; transform: translate(0, 0); }

/**
 * @section Charts
 * Every chart is a viewBox crop of one drawing, assets/chart/vi-land.svg, on a Celestine Navy field.
 * The SVG carries the geography and the furniture (graticule, compass rose, scale bar, title block);
 * pins and place labels are HTML laid over it, positioned in percent, so they stay legible at any
 * chart scale and can take focus. Chart type is set in SVG user units, so it scales with the drawing.
 * @see DESIGN.md, Charts; The Chart Truth Rule
 *
 * @rule .chart               The positioning context for everything laid over the drawing.
 * @rule .chart .shoal        The coastline once as a wide, faint halo: Sea Glass at 7%, 11px.
 * @rule .chart .land         The coastline again as land: Sea Glass fill at 16% under a 1px Sea Glass line.
 * @rule .chart .grat         Graticule lines every tenth of a degree. Non-scaling, so always 1px.
 * @rule .chart .grat-label   Graticule edge labels in the label voice at chart scale.
 * @rule .chart .rose, .rose-fill, .rose-text   The four-point compass rose and its N.
 * @rule .chart .scale, .scale-text   The nautical-mile scale bar.
 * @rule .chart .chart-title  The title block: a caps line, and with .serif the chart's name in Cormorant.
 * @rule .chart .route        One leg of a passage: a dashed Sea Glass line.
 * @rule .chart .draw         The mask that draws the routes on. One unbroken path with pathLength 1, so a
 *                            dash offset of 1 hides the whole passage and 0 shows it.
 * @hook .chart.is-in         Entered (pages.js): the mask's offset eases to 0 over 2.6s, then pins and labels fade in,
 *                            staggered by --i.
 * @var --i                   A pin's place in the entrance order. Set inline by the generator.
 */
.chart { position: relative; --unit: 1px; }
.chart > svg { display: block; width: 100%; height: auto; }
.chart .land { fill: rgb(var(--seaglass-rgb) / 0.16); stroke: var(--seaglass); stroke-width: 1; stroke-opacity: 0.85; stroke-linejoin: round; }
.chart .shoal { fill: none; stroke: var(--seaglass); stroke-width: 11; stroke-opacity: 0.07; stroke-linejoin: round; }
.chart .grat { fill: none; stroke: rgb(var(--seaglass-rgb) / 0.13); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart .grat-label { font-family: var(--font-label); font-weight: 400; font-size: 8px; letter-spacing: 0.6px; fill: rgb(var(--seaglass-rgb) / 0.62); }
.chart .rose { fill: none; stroke: rgb(var(--seaglass-rgb) / 0.7); stroke-width: 0.8; }
.chart .rose-fill { fill: rgb(var(--seaglass-rgb) / 0.85); stroke: none; }
.chart .rose-text { font-family: var(--font-display); font-size: 9px; fill: var(--seaglass); }
.chart .scale { stroke: rgb(var(--seaglass-rgb) / 0.8); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart .scale-text { font-family: var(--font-label); font-size: 7.5px; letter-spacing: 0.8px; fill: rgb(var(--seaglass-rgb) / 0.8); }
.chart .route { fill: none; stroke: var(--seaglass); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 4.5 3.5; opacity: 0.95; transition: opacity 0.35s ease, stroke-width 0.35s ease; } /* impeccable-disable-line layout-transition: stroke-width is SVG paint, not layout */
.chart .draw { fill: none; stroke: #fff; stroke-width: 6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.chart.is-in .draw { stroke-dashoffset: 0; transition: stroke-dashoffset 2.6s var(--ease-reveal); }
.chart .chart-title { font-family: var(--font-label); font-size: 8px; letter-spacing: 1.6px; fill: rgb(var(--seaglass-rgb) / 0.72); }
.chart .chart-title.serif { font-family: var(--font-display); font-size: 13px; letter-spacing: 0; fill: var(--seaglass); }

/**
 * @section Chart pins and linking
 * Pins are real HTML so they stay legible at any chart scale and can be focused. Pointing at, or
 * focusing, a log entry or key row lights its leg and pin, and the rest of the chart steps back.
 *
 * @rule .pin                  A 24px Shallow Water disc with a Midnight Hull numeral and a navy ring.
 * @state .pin:hover, .pin:focus-visible, .pin.active   Sea Glass, 1.25 times the size, with a wider ring and the Control shadow.
 * @rule .pin-label            The place name beside a pin, in the label voice, with a navy halo so it holds over
 *                             coastline and satellite imagery. Hidden from assistive technology: the pin is named.
 * @modifier .pin-label.left, .above, .below, .belowr   Which side of the pin the label sits on. The one thing on a chart chosen by hand.
 * @rule .chart .mark          A small ring for a place a leg passes through without stopping.
 * @hook .chart[data-active]   A key is lit (pages.js): routes other than .active fall to 28%, and pins other than
 *                             .active fall to 55%.
 * @modifier .pin-hold         A pin that keeps full strength while another is lit. Available to the generator (hold=True); unused today.
 * @breakpoint 768px  Pins and labels step down a size; graticule labels and the title block are dropped.
 */
.pin { position: absolute; transform: translate(-50%, -50%); width: 24px; height: 24px; border-radius: 50%; background: var(--sky-tint); color: var(--navy-deep); border: 1.5px solid var(--navy-core); box-shadow: 0 0 0 3px rgb(var(--seaglass-rgb) / 0.18); font-family: var(--font-label); font-weight: 500; font-size: 12px; line-height: 1; display: flex; align-items: center; justify-content: center; text-decoration: none; transition: transform 0.35s var(--ease-reveal), box-shadow 0.35s ease, background 0.35s ease, opacity 0.6s ease; z-index: 2; }
.pin:hover, .pin:focus-visible, .pin.active { background: var(--seaglass); color: var(--navy-deep); transform: translate(-50%, -50%) scale(1.25); box-shadow: 0 0 0 6px rgb(var(--seaglass-rgb) / 0.22), 0 6px 18px rgba(0,0,0,0.35); z-index: 3; }
.pin-label { position: absolute; transform: translate(0, -50%); white-space: nowrap; font-family: var(--font-label); font-weight: 400; font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--seaglass); text-shadow: 0 0 6px rgb(var(--navy-core-rgb) / 0.95), 0 0 2px rgb(var(--navy-core-rgb) / 1); pointer-events: none; z-index: 2; transition: opacity 0.6s ease; }
.pin-label.left { transform: translate(-100%, -50%); }
.pin-label.above { transform: translate(-50%, -100%); }
.pin-label.below { transform: translate(-50%, 0); }
.pin-label.belowr { transform: translate(-11px, 0); }
.chart .mark { position: absolute; transform: translate(-50%, -50%); width: 8px; height: 8px; border-radius: 50%; background: var(--navy-core); border: 1.5px solid var(--seaglass); z-index: 2; }
.chart[data-active] .route:not(.active) { opacity: 0.28; }
.chart[data-active] .route.active { stroke-width: 2.4; opacity: 1; }
.chart[data-active] .pin:not(.active):not(.pin-hold) { opacity: 0.55; }
.chart .pin, .chart .pin-label, .chart .mark { opacity: 0; }
.chart.is-in .pin, .chart.is-in .pin-label, .chart.is-in .mark { opacity: 1; }
.chart.is-in .pin { transition-delay: calc(0.9s + var(--i, 0) * 0.14s); }
.chart.is-in .pin-label { transition-delay: calc(1.1s + var(--i, 0) * 0.14s); }
.chart.is-in[data-active] .pin { transition-delay: 0s; }
/**
 * @section Chart / satellite split
 * Every chart but the itineraries hero carries a satellite plate of the same window, in register with
 * the drawing (tools/fetch-satellite.py). Chart to the left of the divider, satellite to its right.
 * The plate lies over the drawing and under the routes, pins and furniture (.chart-over), so the
 * passage stays plotted on both. Nothing shows until pages.js marks the chart .split-on; without
 * script it is simply the chart.
 * @see DESIGN.md, The chart / satellite split
 *
 * @var --split        The divider's position in percent from the left. Written by pages.js, which measures where it
 *                     rests against what is on screen; defaults to 100% (chart only).
 * @var --knob-y       How high the knob rides on the divider, chosen per chart to clear its pins. Set inline by the generator.
 * @var --split-delay  How long the entrance waits, so the route has drawn first. Set inline by the generator.
 * @rule .chart > .chart-over   A second SVG above the plate for whatever must stay visible on both views: the routes,
 *                     and on the index charts the rose, scale bar, title block and graticule labels.
 * @rule .chart .sat   The plate, clipped from the left by --split.
 * @rule .chart .sat img   color: transparent keeps the alt text (still read aloud) from being drawn across the chart while a plate loads.
 * @rule .split-line   A 22px-wide grab strip drawing a 1px Sea Glass line. touch-action: pan-y, so the page still scrolls past it.
 * @rule .split-knob   A 40px round control in the Button Dark vocabulary, with the Control shadow since it sits on imagery.
 *                     Its ::after grows the hit area by 5px all round. Clamped 26px inside either edge.
 * @state .split-knob:hover, .chart.is-dragging .split-knob   Solid Sea Glass with Midnight Hull chevrons.
 * @hook .chart.split-on     Script is running: the plate, line and knob are displayed.
 * @hook .chart.split-live   The line and knob are visible.
 * @hook .chart.split-intro  The entrance is in flight: --split changes ease over 1.5s, after --split-delay.
 * @hook .chart.is-dragging  A pointer holds the divider: the resize cursor everywhere, and pins stop taking the pointer.
 */
.chart > .chart-over { position: absolute; inset: 0; height: 100%; pointer-events: none; }
.chart .sat, .chart .split-line, .chart .split-knob { display: none; }
.chart.split-on .sat { display: block; position: absolute; inset: 0; clip-path: inset(0 0 0 var(--split, 100%)); }
/* color: transparent keeps the alt text (still read aloud) from being drawn across the chart while a plate is loading. */
.chart .sat img { display: block; width: 100%; height: 100%; max-width: none; color: transparent; pointer-events: none; user-select: none; -webkit-user-drag: none; }
.chart.split-on .split-line { display: block; position: absolute; top: 0; bottom: 0; left: var(--split, 100%); width: 22px; margin-left: -11px; cursor: ew-resize; touch-action: pan-y; opacity: 0; }
.chart .split-line::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; margin-left: -0.5px; background: var(--seaglass); box-shadow: 0 0 0 1px rgb(var(--navy-deep-rgb) / 0.28); }
.chart.split-on .split-knob { display: flex; position: absolute; z-index: 4; left: clamp(26px, var(--split, 100%), calc(100% - 26px)); top: var(--knob-y, 50%); width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%; align-items: center; justify-content: center; background: rgb(var(--navy-deep-rgb) / 0.92); color: var(--seaglass); border: 1px solid rgb(var(--seaglass-rgb) / 0.75); box-shadow: 0 4px 18px rgba(0,0,0,0.35); cursor: ew-resize; touch-action: pan-y; user-select: none; -webkit-user-select: none; opacity: 0; transition: background 0.25s, color 0.25s, border-color 0.25s, opacity 0.6s ease; }
.chart .split-knob::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; }
.chart .split-knob svg { width: 22px; height: 22px; display: block; pointer-events: none; }
.chart .split-knob:hover, .chart.is-dragging .split-knob { background: var(--seaglass); color: var(--navy-deep); border-color: var(--seaglass); }
.chart .split-knob:focus-visible { outline-color: var(--seaglass); outline-offset: 3px; border-radius: 50%; }
.chart.split-live .split-line, .chart.split-live .split-knob { opacity: 1; }
.chart.split-on .split-line { transition: opacity 0.6s ease; }
/* The one authored moment: after the route has drawn, the satellite wipes in from the east and settles. */
.chart.split-intro .sat { transition: clip-path 1.5s var(--ease-reveal) var(--split-delay, 0.9s); }
.chart.split-intro .split-line { transition: left 1.5s var(--ease-reveal) var(--split-delay, 0.9s), opacity 0.6s ease var(--split-delay, 0.9s); }
.chart.split-intro .split-knob { transition: left 1.5s var(--ease-reveal) var(--split-delay, 0.9s), opacity 0.6s ease var(--split-delay, 0.9s), background 0.25s, color 0.25s, border-color 0.25s; }
.chart.is-dragging { cursor: ew-resize; }
.chart.is-dragging .pin, .chart.is-dragging .pin-label { pointer-events: none; }
/**
 * @section Chart panning and key
 * On a phone a chart keeps a minimum width and pans sideways inside its scroller, opening on its
 * subject (pages.js, data-focus-x) with its divider resting in the middle of what that leaves on screen.
 *
 * @rule .chart-scroll   The scroller. Clipped on desktop, horizontally scrollable at 768px and below.
 * @var --chart-min      The width a chart keeps on a phone. Set inline by the generator, per chart.
 * @rule .chart-hint     "Drag the chart to pan": phone only.
 * @rule .chart-key      The key under the hero chart: a dashed sample line, and .fine for the "Not for navigation" line.
 */
.chart-scroll { overflow: hidden; }
.chart-scroll > .chart { min-width: 0; }
.chart-hint { display: none; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.72); padding: 10px 0 0; }
@media (max-width: 768px) {
  .chart-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .chart-scroll > .chart { min-width: var(--chart-min, 0px); }
  .chart-hint { display: block; }
  .chart .grat-label, .chart .chart-title { display: none; }
  .pin { width: 22px; height: 22px; font-size: 11px; }
  .pin-label { font-size: 11px; letter-spacing: 1.2px; }
}
.chart-key { display: flex; flex-wrap: wrap; gap: 8px 28px; align-items: center; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.8); }
.chart-key span { display: inline-flex; align-items: center; gap: 10px; }
.chart-key i { display: inline-block; width: 34px; height: 0; border-top: 2px dashed var(--seaglass); }
.chart-key .fine { font-family: var(--font-body); letter-spacing: 1px; opacity: 0.7; text-transform: none; font-size: 13px; }

/**
 * @section Itineraries: hero
 * The itineraries page opens on a full-width chart of the seven-night passage, with the headline set
 * over its open sea. This is the one chart with no satellite plate, because type sits on it.
 *
 * @rule .hero-chart             The navy field. Its top padding clears the fixed nav.
 * @rule .hero-chart .hero-copy  The headline block, laid over the chart's empty north-west with a navy halo on its type.
 * @rule .hero-chart .hero-actions   Two ghost buttons to the plans.
 * @rule .hero-chart .chart      On a phone, cropped by the scroller to a band: 230 of the chart's 560 viewBox units
 *                               come off the top, because the copy has left the open sea the chart keeps for it and
 *                               a screen of empty water was all that stood between the buttons and the islands. The
 *                               cut takes Anegada, the compass rose and the passage north, which runs off the top
 *                               edge; nothing comes off the foot, where land reaches to within 5 units of the edge.
 * @breakpoint 768px   The chart is 870px wide whatever the window is, so the cut is flat pixels.
 * @breakpoint 1100px  The copy leaves the chart and sits above it, without the halo.
 */
.hero-chart { position: relative; background: var(--navy-core); color: var(--seaglass); padding-top: var(--nav-h); overflow: hidden; }
.hero-chart .hero-copy { position: absolute; z-index: 4; left: var(--section-x); top: calc(var(--nav-h) + 48px); max-width: var(--span-4); }
.hero-chart h1 { font-size: clamp(40px, 5.2vw, 72px); line-height: 0.98; text-wrap: balance; color: var(--seaglass); text-shadow: 0 0 24px rgb(var(--navy-core-rgb) / 0.9); }
.hero-chart .lede { margin-top: 22px; max-width: 42ch; text-shadow: 0 0 12px rgb(var(--navy-core-rgb) / 0.9); }
.hero-chart .hero-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 30px; }
.hero-chart .hero-actions .btn { padding: 16px 28px; }
.hero-chart .chart-key { justify-content: flex-end; padding: 18px var(--section-x) 26px; }
.hero-chart .chart-scroll { position: relative; z-index: 1; }
@media (min-width: 769px) { .hero-chart .chart-hint { display: none; } }
@media (max-width: 1100px) {
  .hero-chart .hero-copy { position: static; padding: 40px var(--section-x) 8px; max-width: var(--measure-read); }
  .hero-chart h1 { text-shadow: none; }
  .hero-chart .lede { text-shadow: none; }
  .hero-chart .chart-key { justify-content: flex-start; }
}
@media (max-width: 768px) {
  .hero-chart .hero-copy { padding-top: 32px; }
  .hero-chart .chart { margin-top: -230px; }
  .hero-chart .chart-hint { padding: 10px var(--section-x) 0; }
}

/**
 * @section Itineraries: passage plans
 * One section per sample passage: a head (title, lede, four facts), then a sticky chart beside the
 * day-by-day log, then "how the week leans". Both plans are Canvas today; the navy variant is kept
 * working beside every rule.
 *
 * @rule .plan                   The section.
 * @modifier .plan.frost         Canvas ground.
 * @rule .plan-inner             The full nine-column measure, centred.
 * @rule .plan-head              Five columns of title and lede against the facts.
 * @rule .plan-facts             Four figures in Cormorant, each over a label-voice caption, above a Chart Rule hairline.
 * @rule .plan-body              Four columns of chart against five of log, with a derived alley, so both sit on column lines.
 * @rule .plan-chart             The chart column. Sticky below the nav while the log scrolls past.
 * @rule .plan-chart .mat        The chart's frame. A navy plate inside a Canvas plan: it names its own ink, as .hero-chart and
 *                               .index do, so nothing in it inherits the plan's Midnight Hull.
 * @rule .plan-chart .chart-cap  The caption under the mat: "Numbered by leg" and "Not for navigation".
 * @breakpoint 1151px  Below the full grid the two columns go fluid: 5fr to 6fr with an 8% alley.
 * @breakpoint 900px   One column; the chart stops being sticky.
 * @breakpoint 768px   Section padding drops to --section-y; facts and titles step down a size.
 */
.plan { padding: var(--section-y-lg) var(--section-x); position: relative; }
.plan.frost { background: var(--canvas); }
.plan-inner { max-width: var(--measure-full); margin: 0 auto; }
.plan-head { display: grid; grid-template-columns: minmax(0, var(--span-5)) minmax(0, 1fr); column-gap: var(--gutter); row-gap: 28px; align-items: end; margin-bottom: 56px; }
.plan-head h2 { font-size: clamp(38px, 6vw, 58px); line-height: 1.02; text-wrap: balance; }
.plan-head .lede { margin-top: 18px; max-width: var(--measure-read); }
.plan.frost .plan-head .lede { color: var(--steel-ink); }
.plan-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 28px; border-top: 1px solid var(--chart-rule); padding-top: 22px; }
.plan-facts { list-style: none; }
.plan-facts li { font-family: var(--font-display); font-size: var(--type-title); line-height: 1; }
.plan-facts small { display: block; margin-top: 8px; font-family: var(--font-label); font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--chart-label); }
.plan-body { display: grid; grid-template-columns: var(--span-4) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-4) - var(--span-5)); align-items: start; }
.plan-chart { position: sticky; top: calc(var(--nav-h) + 24px); }
/* A navy plate inside a Canvas plan: it names its own ink, as .hero-chart and .index do, so nothing in it inherits the plan's Midnight Hull. */
.plan-chart .mat { background: var(--navy-core); color: var(--seaglass); border-radius: 2px; padding: 0; box-shadow: 0 8px 24px rgba(0,0,0,0.15); overflow: hidden; }
.plan-chart .grat-label, .plan-chart .chart-title { display: none; }
.plan-chart .chart-cap { display: flex; justify-content: space-between; gap: 12px; padding: 12px 2px 0; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--chart-label); }
/* The phone-only pan hint sits under the mat on the plan's Canvas, so it takes the caption's ink, not the chart's Sea Glass (1.2:1 there). */
.plan-chart .chart-hint { color: var(--chart-label); }

/**
 * @section Itineraries: the log
 * One entry per leg: a numbered day beside a title ("from, arrow, to"), the time under sail, a
 * paragraph, and the day's planning tags.
 *
 * @rule .leg           An entry: a 96px day column and the text, between Chart Rule hairlines.
 * @hook .leg.active    Its leg is lit on the chart (pages.js): a Sea Glass wash from the left, and the numeral grows.
 * @rule .leg-num       The leg's number in a 30px navy disc, matching its pin on the chart.
 * @rule .leg-when      "Day 3, Monday" in the label voice.
 * @rule .leg-title     Title size. .to is the arrow between the two places; a visually hidden " to " is read in its place.
 * @rule .leg-sail      Time under sail, with the sail glyph.
 * @rule .tags          Planning tags: the crew's own pictograms from assets/icons/tags.svg at 24px, filled with
 *                      currentColor (Chart Label on Canvas, Shallow Water on navy). Each is named by its title and an accessible label.
 * @modifier .tags.legend   The key to the set, where each pictogram carries a visible label.
 */
.legs { list-style: none; }
.leg { display: grid; grid-template-columns: 96px minmax(0, 1fr); column-gap: 24px; padding: 26px 0 30px; border-top: 1px solid var(--chart-rule); position: relative; transition: background 0.3s ease; }
.leg:last-child { border-bottom: 1px solid var(--chart-rule); }
.leg-day { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.leg-num { font-family: var(--font-label); width: 30px; height: 30px; border-radius: 50%; background: var(--navy-core); color: var(--seaglass); font-weight: 500; font-size: 12px; display: flex; align-items: center; justify-content: center; transition: transform 0.35s var(--ease-reveal), background 0.35s ease; }
.leg.active .leg-num { transform: scale(1.18); }
.leg-when { font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--chart-label); line-height: 1.5; }
.leg-title { font-family: var(--font-display); font-weight: 400; font-size: var(--type-title); line-height: var(--leading-title); display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.leg-title .to { display: inline-flex; align-items: center; color: var(--steel-blue); }
.leg-title .to svg { width: 22px; height: 12px; display: block; }
.leg-sail { margin-top: 10px; font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--chart-label); display: flex; align-items: center; gap: 10px; }
.leg-sail svg { width: 16px; height: 16px; flex: none; }
.leg p { margin-top: 14px; max-width: 60ch; color: var(--steel-ink); font-size: var(--type-body); line-height: var(--leading-body); }
/* Planning tags: the itinerary legend's own pictograms, set beside their labels. */
.tags { list-style: none; display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 18px; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--steel-shade); }
.tags li { display: inline-flex; align-items: center; gap: 8px; }
.tags li svg { width: 24px; height: 24px; flex: none; color: var(--chart-label); }
.tags.legend { gap: 10px 20px; }
.tags.legend li svg { width: 22px; height: 22px; }
.leg.active { background: linear-gradient(to right, rgb(var(--seaglass-rgb) / 0.35), rgb(var(--seaglass-rgb) / 0)); }

/**
 * @section Itineraries: how the week leans
 * The mix: relative emphasis, from the charter's own planning sheet. Five gauges on a scale ruled in quarters.
 *
 * @rule .mix           The block: a title and lede against the gauges.
 * @rule .gauge         One row: a label and its track.
 * @rule .gauge-track   The ruled scale: a tick every 25%.
 * @rule .gauge-fill    The reading. Scales in from the left over 1.2s, each row 0.1s after the one above.
 * @var --v             The reading in percent. Set inline by the generator.
 * @hook .gauges.is-in  Entered (pages.js): the fills run.
 */
.mix { margin-top: 56px; padding-top: 30px; border-top: 1px solid var(--chart-rule); display: grid; grid-template-columns: var(--span-4) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-4) - var(--span-5)); }
.mix h3 { font-size: var(--type-title); line-height: var(--leading-title); }
.mix .lede { font-size: var(--type-serif); margin-top: 10px; max-width: 34ch; color: var(--steel-ink); }
.gauges { list-style: none; display: grid; gap: 16px; }
.gauge { display: grid; grid-template-columns: 200px minmax(0, 1fr); align-items: center; gap: 18px; font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--chart-label); }
.gauge-track { position: relative; height: 12px; background-image: repeating-linear-gradient(to right, var(--chart-rule) 0 1px, transparent 1px 25%); background-size: 100% 100%; border-right: 1px solid var(--chart-rule); }
.gauge-fill { position: absolute; left: 0; top: 3px; height: 6px; width: var(--v); background: var(--harbor-sky); transform-origin: left; transform: scaleX(0); transition: transform 1.2s var(--ease-reveal); }
.gauges.is-in .gauge-fill { transform: scaleX(1); }
.gauge:nth-child(2) .gauge-fill { transition-delay: 0.1s; } .gauge:nth-child(3) .gauge-fill { transition-delay: 0.2s; } .gauge:nth-child(4) .gauge-fill { transition-delay: 0.3s; } .gauge:nth-child(5) .gauge-fill { transition-delay: 0.4s; }

@media (max-width: 1151px) {
  .plan-body, .mix { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: 8%; }
  .gauge { grid-template-columns: 150px minmax(0, 1fr); }
}
@media (max-width: 900px) {
  .plan-head { grid-template-columns: 1fr; }
  .plan-facts { max-width: 520px; }
  .plan-body { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .plan-chart { position: static; }
  .mix { grid-template-columns: 1fr; row-gap: 24px; }
}
@media (max-width: 768px) {
  .plan { padding: var(--section-y) var(--section-x); }
  .plan-head { margin-bottom: 36px; }
  .plan-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
  .plan-facts li { font-size: var(--type-title-sm); }
  .leg { grid-template-columns: 1fr; row-gap: 12px; padding: 22px 0 26px; }
  .leg-day { flex-direction: row; align-items: center; gap: 14px; }
  .leg-title { font-size: var(--type-title-sm); }
  .gauge { grid-template-columns: 1fr; gap: 8px; }
}

/**
 * @section Itineraries: reading the plan
 * The notes block under the two plans. Both plans are Canvas now, so a Chart Rule hairline marks the
 * seam, as it does above .more.
 *
 * @rule .notes         The section: a heading and lede against a definition list.
 * @rule .notes dt, dd  A term in Cormorant at Title S, and its explanation at 50ch.
 * @rule .notes .tags   The full legend of pictograms in three columns, two at 480px, one at 360px.
 */
.notes { background: var(--canvas); padding: var(--section-y-lg) var(--section-x); border-top: 1px solid var(--chart-rule); }
.notes-inner { max-width: var(--measure-full); margin: 0 auto; display: grid; grid-template-columns: var(--span-4) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-4) - var(--span-5)); row-gap: 40px; }
.notes h2 { font-size: clamp(34px, 5vw, 48px); line-height: 1.05; text-wrap: balance; }
.notes .lede { margin-top: 16px; color: var(--steel-ink); max-width: 36ch; }
.notes dl { display: grid; gap: 26px; }
.notes dt { font-family: var(--font-display); font-size: var(--type-title-sm); line-height: var(--leading-title); }
.notes dd { margin-top: 8px; color: var(--steel-ink); max-width: 50ch; }
.notes .tags { margin-top: 18px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 16px; }
@media (max-width: 480px) { .notes .tags { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Two columns leave 128px a cell at 320px; "Paddleboarding" with its pictogram needs about 166 and cannot break. */
@media (max-width: 360px) { .notes .tags { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 1151px) { .notes-inner { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: 8%; } }
@media (max-width: 900px) { .notes-inner { grid-template-columns: 1fr; } }
@media (max-width: 768px) { .notes { padding: var(--section-y) var(--section-x); } }

/**
 * @section Destinations: photo hero
 * The two destination pages open on a photograph under a navy scrim that deepens toward the foot,
 * where the headline sits.
 *
 * @rule .hero-photo            The field: at least 72vh (capped at 820px), its copy at the bottom left.
 * @rule .hero-photo::after     The scrim: navy at 92% at the foot, 10% at the top.
 * @rule .hero-photo .hero-copy  The headline, lede and two ghost buttons, on the mid measure.
 */
.hero-photo { position: relative; min-height: min(72vh, 820px); display: flex; align-items: flex-end; padding: calc(var(--nav-h) + 80px) var(--section-x) 64px; color: var(--seaglass); background: var(--navy-core); overflow: hidden; }
.hero-photo picture, .hero-photo picture img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-photo::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgb(var(--navy-core-rgb) / 0.92) 0%, rgb(var(--navy-core-rgb) / 0.55) 42%, rgb(var(--navy-core-rgb) / 0.1) 100%); }
.hero-photo .hero-copy { position: relative; z-index: 2; max-width: var(--measure-mid); }
.hero-photo h1 { font-size: clamp(44px, 7vw, 88px); line-height: 0.98; text-wrap: balance; color: var(--seaglass); }
.hero-photo .lede { margin-top: 20px; max-width: var(--span-5); }
.hero-photo .hero-actions { margin-top: 28px; display: flex; gap: 12px; flex-wrap: wrap; }
@media (max-width: 768px) { .hero-photo { min-height: min(66vh, 700px); padding-top: calc(var(--nav-h) + 56px); padding-bottom: 48px; } .hero-photo .lede { font-size: var(--type-serif); } }

/**
 * @section Destinations: chart index
 * A navy section holding the country's chart with every featured anchorage numbered, and a key beside
 * it. Key rows and pins light each other (pages.js).
 *
 * @rule .index             The navy section.
 * @rule .index-head        Five columns of heading against the lede.
 * @rule .index-body        Six columns of chart against three of key.
 * @modifier .index-body.wide   A chart too wide to share a row (the USVI): the chart takes the full measure and the key runs in three columns under it.
 * @rule .index .mat        The chart's frame: a 1px Sea Glass line at 20%.
 * @rule .key               The numbered list of anchorages. Each row is one link to its entry.
 * @rule .key .k            The numeral, in the pin's colours.
 * @rule .key .name, .where  The anchorage in Cormorant, and its island in the label voice.
 * @hook .key a.active      Its pin is lit on the chart.
 */
.index { background: var(--navy-core); color: var(--seaglass); padding: var(--section-y-lg) var(--section-x); position: relative; overflow: hidden; }
.index-inner { max-width: var(--measure-full); margin: 0 auto; }
.index-head { display: grid; grid-template-columns: minmax(0, var(--span-5)) minmax(0, 1fr); column-gap: var(--gutter); align-items: end; margin-bottom: 44px; }
.index-head h2 { font-size: clamp(38px, 6vw, 58px); line-height: 1.02; text-wrap: balance; }
.index-head .lede { max-width: 40ch; }
.index-body { display: grid; grid-template-columns: var(--span-6) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-6) - var(--span-3)); align-items: start; }
.index-body.wide { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
.index .mat { border: 1px solid rgb(var(--seaglass-rgb) / 0.2); border-radius: 2px; overflow: hidden; background: var(--navy-core); }
.index .chart-cap { display: flex; justify-content: space-between; gap: 12px; padding: 12px 2px 0; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.72); }
.key { list-style: none; counter-reset: k; display: grid; gap: 0; }
.index-body.wide .key { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--gutter); }
.key li { border-top: 1px solid rgb(var(--seaglass-rgb) / 0.2); }
.key a { display: grid; grid-template-columns: 30px minmax(0, 1fr); column-gap: 14px; align-items: baseline; padding: 13px 4px; text-decoration: none; color: var(--seaglass); transition: background 0.25s ease; }
.key a:hover, .key a:focus-visible { background: rgb(var(--seaglass-rgb) / 0.08); }
.key a.active { background: rgb(var(--seaglass-rgb) / 0.12); }
.key .k { font-family: var(--font-label); font-size: 12px; font-weight: 500; color: var(--navy-deep); background: var(--sky-tint); border-radius: 50%; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; align-self: center; }
.key .name { font-family: var(--font-display); font-size: var(--type-serif); line-height: var(--leading-title); }
.key .where { display: block; font-family: var(--font-label); font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.7); margin-top: 3px; }
@media (max-width: 1151px) { .index-body { grid-template-columns: minmax(0, 6fr) minmax(0, 4fr); column-gap: 6%; } }
@media (max-width: 900px) { .index-body, .index-head { grid-template-columns: minmax(0, 1fr); row-gap: 32px; } .index-body.wide .key { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px) { .index { padding: var(--section-y) var(--section-x); } .index-body.wide .key { grid-template-columns: 1fr; } }

/**
 * @section Destinations: pilot entries
 * One entry per anchorage, written like a pilot book: a chart inset beside a number, a name, a place
 * line, a paragraph or two, and what the anchorage is good for. Entries alternate sides.
 *
 * @rule .entries                The Canvas section.
 * @rule .entry                  Four columns of inset against five of text, with a derived alley.
 * @rule .entry:nth-child(even)  The mirror image: text first, inset second.
 * @rule .entry-num              The anchorage's number, matching its pin on the index chart.
 * @rule .entry .where           The place line, in the label voice.
 * @rule .entries-credit         The imagery credit, composed per page from the sources its plates came from.
 * @breakpoint 1151px  The columns go fluid.
 * @breakpoint 800px   One column, inset first.
 */
.entries { background: var(--canvas); padding: var(--section-y-lg) var(--section-x); }
.entries-inner { max-width: var(--measure-full); margin: 0 auto; display: grid; row-gap: 72px; }
.entry { display: grid; grid-template-columns: var(--span-4) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-4) - var(--span-5)); align-items: start; scroll-margin-top: calc(var(--nav-h) + 24px); }
.entry:nth-child(even) { grid-template-columns: minmax(0, 1fr) var(--span-4); }
.entry:nth-child(even) .inset { order: 2; }
.entry-text { padding-top: 6px; }
.entry-num { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; background: var(--navy-core); color: var(--seaglass); font-family: var(--font-label); font-weight: 500; font-size: 12px; margin-bottom: 18px; }
.entry h3 { font-size: clamp(30px, 3.4vw, 40px); line-height: 1.08; text-wrap: balance; }
.entry .where { margin-top: 8px; font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--chart-label); }
.entry p { margin-top: 18px; color: var(--steel-ink); max-width: 50ch; }
.entry p + p { margin-top: 12px; }
.entry .tags { margin-top: 20px; }
/**
 * @section Chart insets
 * The inset: the yacht section's frost mat, carrying a chart plate instead of a photograph. A 4:3
 * crop of the one drawing at anchorage scale, with the pin where the yacht lies, a north arrow, a
 * one-mile bar, and a caption lip giving the coordinates. It can be swapped for a photograph in the
 * same mat without changing the page.
 *
 * @rule .inset               The Sea Glass Light mat, with the Float shadow. It wraps the plate on three sides.
 * @var --mat                 The mat's width: 16px, 14px at 800px and below.
 * @rule .inset figcaption    The lip: "Chart inset" and the coordinates, in the label voice.
 * @rule .inset .north        The north arrow, with a soft navy cast so it holds over reef and sand.
 * @rule .inset .scalebar     The one-mile bar.
 * @var --nm                  One nautical mile as a fraction of the inset's width. Set inline by the generator.
 */
.inset { --mat: 16px; margin: 0; padding: var(--mat) var(--mat) 0; background: var(--seaglass-light); border-radius: 2px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); }
.inset .chart { background: var(--navy-core); overflow: hidden; }
.inset .chart > svg { aspect-ratio: 4 / 3; }
.inset .chart .pin { cursor: default; }
.inset figcaption { padding: 14px 0 16px; display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--chart-label); }
.inset figcaption span:last-child { color: var(--slate-muted); letter-spacing: 1px; }
/* The arrow and the bar can sit over satellite imagery now, so they carry a soft navy cast to hold up on reef and sand. */
.inset .north { position: absolute; right: 12px; top: 10px; width: 22px; height: 30px; opacity: 0.9; filter: drop-shadow(0 1px 2px rgb(var(--navy-deep-rgb) / 0.75)); }
.inset .scalebar { position: absolute; left: 12px; right: 12px; bottom: 10px; display: flex; align-items: flex-end; gap: 8px; font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.9); filter: drop-shadow(0 1px 2px rgb(var(--navy-deep-rgb) / 0.75)); pointer-events: none; }
.inset .scalebar i { display: block; width: calc((100% + 24px) * var(--nm)); flex: none; height: 5px; border: 1px solid rgb(var(--seaglass-rgb) / 0.8); border-top: none; }
.entries-credit { max-width: var(--span-4); padding-top: 22px; border-top: 1px solid var(--chart-rule); font-size: 14px; line-height: 1.6; color: var(--steel-shade); }
/**
 * @section Anchorage map opener
 * The inset opens Apple's satellite map at its pin: the whole plate is the target, and this round
 * control is its keyboard and screen-reader handle, in the divider knob's vocabulary. A link until a
 * MapKit token is set.
 *
 * @rule .inset .chart   The zoom-in cursor over the whole plate.
 * @rule .inset-open     A 34px round control at the plate's top left. Its ::after grows the hit area by 6px all round.
 */
.inset .chart { cursor: zoom-in; }
.inset-open { position: absolute; left: 10px; top: 10px; z-index: 4; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: rgb(var(--navy-deep-rgb) / 0.92); color: var(--seaglass); border: 1px solid rgb(var(--seaglass-rgb) / 0.75); box-shadow: 0 4px 18px rgba(0,0,0,0.35); cursor: pointer; transition: background 0.25s, color 0.25s, border-color 0.25s; }
.inset-open::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; }
.inset-open svg { width: 16px; height: 16px; display: block; }
.inset-open:hover { background: var(--seaglass); color: var(--navy-deep); border-color: var(--seaglass); }
.inset-open:focus-visible { outline-color: var(--seaglass); border-radius: 50%; }

/**
 * @section Map dialog
 * The homepage lightbox's field and close button, holding a live map instead of a photograph. Emitted
 * only when a MapKit token is set, so dormant today.
 *
 * @rule .mapbox                 The Midnight Hull field at 96%. Hidden with visibility as well as opacity, so nothing
 *                               inside it can take focus while it is closed.
 * @hook .mapbox[data-open="yes"]   Open. Written by pages.js.
 * @rule .mapbox-frame           Three rows: heading, map, foot.
 * @rule .mapbox-num             The anchorage's number, in the pin's colours.
 * @rule .mapbox-map             The box MapKit draws into.
 * @rule .mapbox-fail            The fallback line laid over the map when MapKit has not initialised.
 * @rule .mapbox-foot            "Open in Apple Maps", always present, beside "Not for navigation".
 * @rule .mapbox-close           A 48px solid Sea Glass close button with the Control shadow, fixed to the corner.
 */
.mapbox { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 40px; background: rgb(var(--navy-deep-rgb) / 0.96); color: var(--seaglass); visibility: hidden; opacity: 0; transition: opacity 0.3s ease, visibility 0s linear 0.3s; }
.mapbox[data-open="yes"] { visibility: visible; opacity: 1; transition: opacity 0.3s ease; }
.mapbox :focus-visible { outline-color: var(--seaglass); }
.mapbox-frame { width: min(1100px, 100%); height: min(780px, 100%); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; row-gap: 18px; }
.mapbox-head { display: flex; align-items: center; gap: 16px; padding-right: 64px; }
.mapbox-num { flex: none; width: 30px; height: 30px; border-radius: 50%; background: var(--sky-tint); color: var(--navy-deep); font-weight: 500; font-size: 12px; display: flex; align-items: center; justify-content: center; }
.mapbox h2 { font-size: clamp(28px, 4vw, 40px); line-height: 1.08; text-wrap: balance; }
.mapbox-where { margin-top: 6px; font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.75); }
.mapbox-map { position: relative; min-height: 0; background: var(--navy-core); border: 1px solid rgb(var(--seaglass-rgb) / 0.2); border-radius: 2px; overflow: hidden; }
.mapbox-fail { position: absolute; inset: 0; z-index: 2; background: var(--navy-core); display: flex; align-items: center; justify-content: center; text-align: center; padding: 32px; font-family: var(--font-display); font-size: 22px; line-height: 1.4; color: rgb(var(--seaglass-rgb) / 0.86); }
.mapbox-fail[hidden] { display: none; }
.mapbox-foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.72); }
.mapbox-foot .btn { padding: 14px 26px; font-size: 12px; letter-spacing: 3px; }
.mapbox-close { position: fixed; top: 24px; right: 24px; z-index: 1; width: 48px; height: 48px; border-radius: 50%; border: none; background: var(--seaglass); color: var(--navy-deep); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 18px rgba(0,0,0,0.35); transition: background 0.25s; }
.mapbox-close:hover { background: var(--sky-tint); }
.mapbox-close svg { width: 22px; height: 22px; display: block; }
@media (max-width: 768px) { .mapbox { padding: 84px 16px 20px; } .mapbox-close { top: 18px; right: 16px; } .mapbox-head { padding-right: 0; } .mapbox-frame { height: 100%; } }
@media (max-width: 1151px) { .entry, .entry:nth-child(even) { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: 8%; } .entry:nth-child(even) { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); } }
@media (max-width: 800px) { .entry, .entry:nth-child(even) { grid-template-columns: 1fr; row-gap: 26px; } .entry:nth-child(even) .inset { order: 0; } .entries-inner { row-gap: 56px; } .inset { --mat: 14px; } }
@media (max-width: 768px) { .entries { padding: var(--section-y) var(--section-x); } }

/**
 * @section Photo band
 * A quiet full-bleed plate between the entries and the notes.
 *
 * @rule .band             The plate: between 320px and 640px tall, the photograph covering it.
 * @rule .band figcaption  A square Midnight Hull caption plate at the bottom left: the badge vocabulary.
 */
.band { position: relative; height: clamp(320px, 52vw, 640px); overflow: hidden; background: var(--navy-core); }
.band picture, .band img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.band figcaption { position: absolute; left: var(--section-x); bottom: 24px; z-index: 2; background: var(--navy-deep); color: var(--seaglass); font-size: 12px; letter-spacing: 3px; text-transform: uppercase; padding: 12px 18px; }

/**
 * @section Between the anchorages
 * Practical notes on a navy field: the blueprint plate, multiplied by its gain so it lands on
 * Celestine Navy, under a navy wash at 78%.
 * @see DESIGN.md, The Multiply Gain Rule
 *
 * @rule .between          The field.
 * @rule .between::before  The wash that quiets the blueprint under the type.
 * @rule .between-inner    A heading and lede against a definition list, as in .notes.
 */
.between { background: var(--navy-core); color: var(--seaglass); padding: var(--section-y-lg) var(--section-x); background-image: linear-gradient(var(--blueprint-gain-1), var(--blueprint-gain-1)), url('opt/blueprint1-1280.webp'); background-blend-mode: multiply, normal; background-size: cover; background-position: center; position: relative; }
.between::before { content: ""; position: absolute; inset: 0; background: rgb(var(--navy-core-rgb) / 0.78); }
.between-inner { position: relative; z-index: 1; max-width: var(--measure-full); margin: 0 auto; display: grid; grid-template-columns: var(--span-4) minmax(0, 1fr); column-gap: calc(var(--measure-full) - var(--span-4) - var(--span-5)); row-gap: 40px; }
.between h2 { font-size: clamp(34px, 5vw, 48px); line-height: 1.05; text-wrap: balance; }
.between .lede { margin-top: 16px; max-width: 36ch; }
.between dl { display: grid; gap: 26px; }
.between dt { font-family: var(--font-display); font-size: var(--type-title-sm); line-height: var(--leading-title); }
.between dd { margin-top: 8px; color: rgb(var(--seaglass-rgb) / 0.86); max-width: 50ch; }
@media (max-width: 1151px) { .between-inner { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: 8%; } }
@media (max-width: 900px) { .between-inner { grid-template-columns: 1fr; } }
@media (max-width: 768px) { .between { padding: var(--section-y) var(--section-x); } }

/**
 * @section Also on the chart
 * Cross links between the three inner pages: the other two, each a serif title with an arrow over a
 * one-line description.
 *
 * @rule .more         The Canvas section, under a Chart Rule hairline.
 * @rule .more a       One link. .t is the title and arrow, .d the description.
 */
.more { background: var(--canvas); padding: var(--section-y) var(--section-x); border-top: 1px solid var(--chart-rule); }
.more-inner { max-width: var(--measure-full); margin: 0 auto; display: grid; grid-template-columns: var(--span-3) minmax(0, 1fr); column-gap: var(--gutter); align-items: start; }
.more h2 { font-size: var(--type-title-lg); line-height: 1.1; }
.more ul { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }
.more a { display: block; text-decoration: none; color: var(--navy-deep); padding: 22px 0; border-top: 1px solid var(--chart-rule); transition: color 0.25s ease; }
.more a:hover { color: var(--steel-blue); }
.more a .t { font-family: var(--font-display); font-size: var(--type-title); line-height: 1.1; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.more a .t svg { width: 22px; height: 12px; flex: none; align-self: center; color: var(--steel-blue); }
.more a .d { margin-top: 8px; font-size: var(--type-small); color: var(--steel-ink); }
@media (max-width: 800px) { .more-inner { grid-template-columns: 1fr; row-gap: 20px; } .more ul { grid-template-columns: 1fr; gap: 0; } }

/**
 * @section Closing
 * Same field as the homepage's booking section: the second blueprint plate under a navy wash at 85%,
 * centred type, and the page's one coral button above a row of secondary actions.
 *
 * @rule .close         The field, on the emphasis step --section-y-xl.
 * @rule .close h2      The page's last word, and the one place the headline scale steps up (to 68px).
 * @rule .close .lede   Set in the body sans here, not Cormorant: a closing paragraph, not an introduction.
 * @rule .close .row    A centred row of buttons.
 */
.close { position: relative; color: var(--seaglass); padding: var(--section-y-xl) var(--section-x); text-align: center; background-color: var(--navy-core); background-image: linear-gradient(var(--blueprint-gain-2), var(--blueprint-gain-2)), url('opt/blueprint2-1280.webp'); background-blend-mode: multiply, normal; background-size: cover; background-position: center; overflow: hidden; }
.close::before { content: ""; position: absolute; inset: 0; background: rgb(var(--navy-core-rgb) / 0.85); }
.close-inner { position: relative; z-index: 2; }
.close h2 { font-size: clamp(38px, 9vw, 68px); line-height: 1.02; max-width: var(--measure-mid); margin: 0 auto; text-wrap: balance; }
.close .lede { font-family: var(--font-body); font-weight: 300; line-height: var(--leading-body); text-wrap: balance; margin: 26px auto 40px; max-width: var(--span-4); font-size: var(--type-body-navy); opacity: 0.85; }
.close .row { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
.close .row + .row { margin-top: 16px; }

/**
 * @section Deferred plates
 * The two blueprint plates lie at the foot of every inner page and weigh 370KB together, and CSS has no
 * lazy loading for a background image. Each is withheld until pages.js marks its section as within reach
 * (two screens or so); until then the section shows its navy field, which is the colour the plate is toned
 * to. Only where script runs: (scripting: enabled) is false with script off, and a browser that does not
 * know the feature skips the block, so both still fetch the plates with the page, as they always did.
 * Screen only, so a printed page has them.
 *
 * @state .between.bg-on, .close.bg-on   The plate may load. Set once by pages.js, and at once under ?static.
 */
@media screen and (scripting: enabled) {
  .between:not(.bg-on), .close:not(.bg-on) { background-image: none; }
}

/**
 * @section Footer
 * Mirrors index.html: the two marks, the social links, the weather instrument, the booking address
 * and the credit, on Midnight Hull.
 * @see DESIGN.md, Weather Widget; The Hit Area Rule
 *
 * @rule footer .marks        The Celestine logo (Sea Glass by the nav's mask, at 90%) and the Paradise Yacht Management mark.
 * @rule footer .social a     24px marks with an invisible 44px hit area (::after with a negative inset), so nothing moves.
 * @rule footer .weather      The instrument: a fixed 308px block against the right margin, so the reading does not shift
 *                            as place names change.
 * @hook footer .weather[data-faded="yes"]   Faded out between two readings. Written by pages.js.
 * @rule footer .wx-temp, .wx-place, .wx-desc   The reading in Shallow Water, and its two label lines.
 * @rule footer .mail         The booking address, with its own 44px hit area.
 * @rule footer .copyright    The credit line.
 * @rule footer (weight)      400, not body's 300: every line here is 14px or smaller on Midnight Hull (The Dark Field Rule).
 * @breakpoint 768px  Everything centres in one column; the weather takes a hairline above and below.
 * @breakpoint 380px  The address steps down so it is not clipped at 320px.
 */
footer { background: var(--navy-deep); color: rgb(var(--seaglass-rgb) / 0.6); font-weight: 400; padding: 40px var(--section-x); display: flex; align-items: center; flex-wrap: wrap; gap: 24px; }
footer .marks { display: flex; align-items: center; gap: 12px; }
footer .marks a { display: inline-flex; }
footer .marks img.logo { height: 46px; width: auto; opacity: 0.9; }
footer .marks img.pym { height: 46px; width: auto; opacity: 0.9; }
footer .rule { width: 1px; height: 32px; background: rgb(var(--seaglass-rgb) / 0.3); }
footer .social { display: flex; gap: 20px; align-items: center; }
footer .social a { position: relative; display: flex; align-items: center; justify-content: center; color: rgb(var(--seaglass-rgb) / 0.6); text-decoration: none; transition: color 0.2s; width: 24px; height: 24px; }
/* 44px hit areas for the small targets, drawn outside the box so nothing moves. */
footer .social a::after { content: ""; position: absolute; inset: -10px; }
footer .mail::after { content: ""; position: absolute; inset: -13px 0; }
footer .social a:hover { color: var(--seaglass); }
footer .social svg { width: 100%; height: 100%; }
footer .weather { display: flex; align-items: center; gap: 14px; width: 308px; flex: none; white-space: nowrap; transition: opacity 0.5s ease; margin-left: auto; }
footer .weather[data-faded="yes"] { opacity: 0; }
footer .wx-temp { font-size: 24px; line-height: 1.15; color: var(--sky-tint); }
footer .wx-temp span { font-size: 13px; opacity: 0.72; }
footer .wx-meta { display: flex; flex-direction: column; gap: 4px; }
footer .wx-place { font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgb(var(--seaglass-rgb) / 0.72); }
footer .wx-desc { font-size: 12px; letter-spacing: 1px; color: rgb(var(--seaglass-rgb) / 0.7); }
footer .mail { position: relative; flex-basis: 100%; margin-top: 22px; display: flex; align-items: center; gap: 10px; color: rgb(var(--seaglass-rgb) / 0.7); text-decoration: none; font-size: 14px; letter-spacing: 1px; transition: color 0.2s; }
footer .mail:hover { color: var(--seaglass); }
footer .mail svg { width: 17px; height: 17px; flex: none; }
/* At 320px the address ran past the edge and was clipped. */
@media (max-width: 380px) { footer .mail { font-size: 13px; letter-spacing: 0; } }
footer .copyright { width: 100%; margin-top: -14px; color: var(--sky-tint); font-size: 12px; }
footer .copyright a { color: inherit; }
@media (max-width: 768px) {
  footer { justify-content: center; text-align: center; padding: 36px var(--section-x) 96px; flex-direction: column; align-items: center; }
  footer > div { width: 100%; justify-content: center; }
  footer .rule { display: none; }
  footer .weather { border-top: 1px solid rgb(var(--seaglass-rgb) / 0.18); border-bottom: 1px solid rgb(var(--seaglass-rgb) / 0.18); padding: 16px 0; width: 100%; margin-left: 0; justify-content: center; order: 2; }
  footer .mail { justify-content: center; order: 3; margin-top: 0; }
  footer .copyright { margin-top: 24px; order: 4; }
  footer .copyright .br { display: block; }
}

/**
 * @section Floating action bar
 * Call, Email and Book, mirroring index.html: a column on the right edge, a full-width row along
 * the bottom on a phone.
 *
 * @rule .float-cta                  Hidden: transparent, 16px low, and out of the pointer's way.
 * @hook .float-cta[data-shown="yes"]   Shown. Written by pages.js once the hero has passed, and cleared over the closing section.
 * @var --cta-vv                     How far a phone's toolbar or keyboard has pushed the visible bottom edge up. Written by pages.js.
 */
.float-cta { position: fixed; right: 0; bottom: calc(40px + var(--cta-vv, 0px)); z-index: 25; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; opacity: 0; transform: translateY(16px); pointer-events: none; transition: opacity 0.4s ease, transform 0.4s ease; }
.float-cta[data-shown="yes"] { opacity: 1; transform: translateY(0); pointer-events: auto; }
.float-cta .btn svg { width: 15px; height: 15px; flex: none; }
@media (max-width: 768px) {
  .float-cta { flex-direction: row; left: 0; right: 0; bottom: var(--cta-vv, 0px); gap: 0; }
  .float-cta > a { flex: 1; min-width: 0; padding: 20px 12px; letter-spacing: 3px; }
}

/**
 * @section Reduced motion
 * Every animation's counterpart. Nothing slides, draws or fills: reveals become a short fade, routes
 * and pins are simply there, gauges are full, the split and the dialog change at once. A new
 * animation anywhere in this file needs a line here.
 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { transform: none; transition: opacity 0.4s ease; }
  .chart .draw, .chart.is-in .draw { stroke-dashoffset: 0; transition: none; }
  .chart .pin, .chart .pin-label, .chart .mark { opacity: 1; transition: none; }
  .gauge-fill { transform: scaleX(1); transition: none; }
  .pin, .leg-num { transition: none; }
  .chart.split-on .sat, .chart.split-on .split-line, .chart.split-on .split-knob { transition: none; }
  .mapbox, .mapbox[data-open="yes"] { transition: none; }
  .float-cta { transition: opacity 0.2s ease; }
}

/**
 * @section Static capture
 * Static capture switch (?static in the URL): every entrance resolved, for screenshots and print.
 * pages.js sets the class before anything else runs.
 *
 * @hook html.static   Every entrance is forced to its end state, with !important, and no transition.
 */
html.static .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
html.static .chart .pin, html.static .chart .pin-label, html.static .chart .mark { opacity: 1 !important; transition: none !important; }
html.static .chart .draw { stroke-dashoffset: 0 !important; transition: none !important; }
html.static .gauge-fill { transform: scaleX(1) !important; transition: none !important; }
html.static .chart.split-on .sat, html.static .chart.split-on .split-line, html.static .chart.split-on .split-knob { transition: none !important; }
html.static .float-cta { transition: none !important; }
