/* SafeBoat website, in the Regatta design system of the app it sells.
   ------------------------------------------------------------------
   Values are the app's own tokens (sb-app-regatta/src/index.css): cool
   fog page, white borderless surfaces on soft shadows, deep cool ink,
   azure as the one signal, tinted feature accents. Outfit for everything
   people read, Space Grotesk for readouts and labels. No paper, no grain,
   no grid, no orange: the brand mark keeps its own colours and that is
   the only place they appear.                                          */

:root {
  --page:    #eef1f6;
  --surface: #ffffff;
  --subtle:  #f7f9fc;
  --inset:   #e7ecf3;
  --text:    #0d1b2e;
  --muted:   #48586f;
  /* --soft is the app's token and is too pale for sentences on the fog page (3:1). --quiet is the
     site's own step between it and --muted, 4.6:1, for every small line that is meant to be read. */
  --quiet:   #5d6c83;
  --soft:    #8391a6;
  --azure:   #2563eb;  --azure-up: #1d4ed8;  --azure-tint: rgba(37, 99, 235, .10);  --azure-glow: rgba(37, 99, 235, .32);
  --ok:      #12a150;  --ok-tint:      rgba(18, 161, 80, .11);
  --cyan:    #0891b2;  --cyan-tint:    rgba(8, 145, 178, .10);
  --violet:  #7c3aed;  --violet-tint:  rgba(124, 58, 237, .10);
  --magenta: #d6409f;  --magenta-tint: rgba(214, 64, 159, .10);
  --warn:    #d97706;  --warn-tint:    rgba(217, 119, 6, .11);
  --alarm:   #e5484d;
  --on-accent: #ffffff;
  --line:    rgba(13, 27, 46, .08);
  --card-line: transparent;
  --ink-btn: #0d1b2e;  --ink-btn-text: #ffffff;
  --shadow-sm: 0 1px 2px rgba(23,43,77,.05), 0 4px 16px rgba(23,43,77,.07);
  --shadow-md: 0 2px 6px rgba(23,43,77,.06), 0 12px 32px rgba(23,43,77,.13);
  --shadow-phone: 0 40px 80px -36px rgba(23,43,77,.45), 0 12px 28px -14px rgba(23,43,77,.25);
  --bezel: #0d1b2e;  --bezel-hi: #2a3b59;
  --water: #c4d9ed;                       /* the map's sea, sampled from the captures */
  --glow-a: rgba(37, 99, 235, .12);  --glow-b: rgba(8, 145, 178, .05);
  --sans: "Outfit", system-ui, sans-serif;
  --mono: "Space Grotesk", ui-monospace, monospace;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --page:    #090b12;
    --surface: #12151f;
    --subtle:  #0e1119;
    --inset:   #05070c;
    --text:    #eef1f8;
    --muted:   rgba(238, 241, 248, .72);
    --quiet:   rgba(238, 241, 248, .60);
    --soft:    rgba(238, 241, 248, .46);
    --azure:   #3b82f6;  --azure-up: #5b96f8;  --azure-tint: rgba(122, 168, 255, .13);  --azure-glow: rgba(59, 130, 246, .45);
    --ok:      #3ddc97;  --ok-tint:      rgba(61, 220, 151, .13);
    --cyan:    #45d0e8;  --cyan-tint:    rgba(69, 208, 232, .13);
    --violet:  #a78bfa;  --violet-tint:  rgba(167, 139, 250, .14);
    --magenta: #f477c0;  --magenta-tint: rgba(244, 119, 192, .14);
    --warn:    #fbbf24;  --warn-tint:    rgba(251, 191, 36, .13);
    --alarm:   #ff5f57;
    --on-accent: #0b0e15;
    --line:    rgba(238, 241, 248, .08);
    --card-line: rgba(238, 241, 248, .07);
    --ink-btn: #eef1f8;  --ink-btn-text: #0d1b2e;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.35), 0 4px 16px rgba(0,0,0,.35);
    --shadow-md: 0 2px 6px rgba(0,0,0,.45), 0 14px 36px rgba(0,0,0,.55);
    --shadow-phone: 0 40px 80px -30px rgba(0,0,0,.8);
    --bezel: #1a1f2d;  --bezel-hi: #343d53;
    --water: #0a0b12;
    --glow-a: rgba(59, 130, 246, .17);  --glow-b: rgba(69, 208, 232, .06);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--page); color: var(--text);
  font-family: var(--sans); font-size: 16px; line-height: 1.5;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: clip;                       /* the fanned phones may lean past the frame; they must never add a scrollbar */
}
::selection { background: var(--azure); color: #fff; }
img { max-width: 100%; }
a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible { outline: 2.5px solid var(--azure); outline-offset: 3px; border-radius: 8px; }
.skip { position: absolute; left: -9999px; top: 8px; padding: 8px 12px; background: var(--text); color: var(--page); border-radius: 8px; }
.skip:focus { left: 8px; z-index: 50; }
[id] { scroll-margin-top: 20px; }

.only-dark, .brand .only-dark { display: none; }
@media (prefers-color-scheme: dark) {
  .only-light, .brand .only-light { display: none; }
  .brand .only-dark { display: block; }
}

/* Type voices, as the app names them */
h1, h2, h3 { font-weight: 800; letter-spacing: -.02em; margin: 0; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; margin: 0 0 16px; padding: 6px 12px 6px 10px;
  border-radius: 999px; background: var(--azure-tint); color: var(--azure);
  font-family: var(--mono); font-weight: 700; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; line-height: 1;
}
.eyebrow i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 3px var(--azure-tint); }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Buttons: one height for all three, so the row reads as one object */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-weight: 700; font-size: 15px; padding: 10px 18px; border-radius: 14px;
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.btn-primary {
  color: #fff; background: linear-gradient(135deg, var(--azure), var(--azure-up));
  box-shadow: 0 8px 22px -8px var(--azure-glow), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 28px -8px var(--azure-glow), inset 0 1px 0 rgba(255,255,255,.18); }
.btn-primary:active, .store:active { transform: translateY(0) scale(.985); }
.btn-lg { font-size: 16.5px; height: 50px; padding: 0 24px; border-radius: 16px; }
.stores { display: flex; gap: 10px; flex-wrap: wrap; }
.store {
  display: inline-flex; align-items: center; gap: 10px; height: 50px;
  padding: 0 16px 0 13px; border-radius: 16px;
  background: var(--ink-btn); color: var(--ink-btn-text); box-shadow: var(--shadow-sm);
  transition: transform .15s ease, box-shadow .15s ease;
}
.store:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.store svg { width: 22px; height: 22px; fill: currentColor; flex: none; }
.store span { display: flex; flex-direction: column; font-weight: 700; font-size: 15px; line-height: 1.08; white-space: nowrap; }
.store small { font-weight: 500; font-size: 10px; opacity: .75; }

/* Frame */
.top, .hero, .features, .install, .foot { width: min(1200px, 100% - 40px); margin-inline: auto; }

.top { display: flex; align-items: center; gap: 28px; height: 72px; }
.brand img { display: block; height: 28px; width: auto; }
.nav { display: flex; gap: 4px; margin-left: auto; font-weight: 600; font-size: 15px; color: var(--muted); }
.nav a { padding: 7px 12px; border-radius: 10px; transition: color .15s ease, background .15s ease; }
.nav a:hover { color: var(--text); background: var(--line); }

/* ── Hero ─────────────────────────────────────────────────────────
   --C is the width of the phones' column. Every phone measure is a share of it, so the fan scales
   as one object with the page and its outermost corner stops at the column's edge: it can lean
   over the page margin, never over the words beside it. */
.hero {
  --C: calc((min(1200px, 100vw - 40px) - 24px) * .55);
  display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  align-items: center; gap: 24px;
  padding: 18px 0 8px;
}
h1 { font-size: clamp(38px, 4.5vw, 62px); line-height: 1.0; letter-spacing: -.03em; margin-bottom: 18px; text-wrap: balance; }
.lede { font-size: 18px; line-height: 1.5; color: var(--muted); max-width: 30em; margin: 0 0 26px; text-wrap: pretty; }
.actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 22px; }
.proof { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 18px; color: var(--quiet); font-size: 14px; font-weight: 500; }
.proof li { display: inline-flex; align-items: center; gap: 8px; }
.proof li::before { content: ""; width: 14px; height: 14px; flex: none; border-radius: 50%; background: var(--ok-tint)
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M4 7.3l2 2 4-4.4' fill='none' stroke='%2312a150' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 14px no-repeat; }
@media (prefers-color-scheme: dark) {
  .proof li::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M4 7.3l2 2 4-4.4' fill='none' stroke='%233ddc97' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
}

/* Three real phones, fanned. The centre one is the home screen. */
.hero-phones { position: relative; height: calc(var(--C) * .9); display: flex; align-items: center; justify-content: center; }
/* a breath of the app's azure behind the glass, so the phones sit in light rather than on a flat page */
.hero-phones::before { content: ""; position: absolute; left: 50%; top: 52%; width: calc(var(--C) * 1.02); height: calc(var(--C) * .74);
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, var(--glow-a), var(--glow-b) 62%, transparent); }
.phone {
  --w: calc(var(--C) * .343);
  margin: 0; position: absolute; width: var(--w); aspect-ratio: 390 / 844;
  padding: calc(var(--w) * .036); border-radius: calc(var(--w) * .18);
  background: linear-gradient(152deg, var(--bezel-hi), var(--bezel) 44%);
  box-shadow: var(--shadow-phone), inset 0 0 0 1px rgba(255,255,255,.10), inset 0 0 0 2px rgba(0,0,0,.28);
}
/* No fake notch or island: the captures carry no status bar, and a pill
   drawn over the app's own header would be the one untrue pixel here. */
/* The glass. Everything live is positioned inside it, in percentages of the
   captured 390x844 screen, and sized in cqw so it scales with the phone. */
.screen { position: relative; width: 100%; height: 100%; border-radius: calc(var(--w) * .146); overflow: hidden; container-type: inline-size; background: var(--page); }
.screen picture, .screen img { display: block; width: 100%; height: 100%; }
.screen img { object-fit: cover; }

/* Live anchor watch. Colours are the app's: azure ring, green anchor, teal
   position dot and track (as it draws them itself in anchor-light.webp). */
.amap { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.a-radius { fill: rgba(59, 130, 246, .20); stroke: #3b82f6; stroke-width: 1.6; transition: fill .35s ease, stroke .35s ease; }
.a-pulse  { fill: none; stroke: var(--alarm); stroke-width: 2; opacity: 0; transform-box: fill-box; transform-origin: center; }
.a-track  { fill: none; stroke: #0e9ab8; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
.a-anchor circle { fill: var(--ok); stroke: #fff; stroke-width: 2.6; }
.a-anchor path { fill: none; stroke: #fff; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.a-boat .halo { fill: rgba(8, 145, 178, .22); transition: fill .3s ease; }
.a-boat .dot  { fill: #0891b2; stroke: #fff; stroke-width: 2.4; transition: fill .3s ease; }
@media (prefers-color-scheme: dark) {
  .a-anchor circle, .a-boat .dot { stroke: #0b0e15; }
  .a-anchor path { stroke: #0b0e15; }
  .a-track { stroke: #45d0e8; } .a-boat .dot { fill: #45d0e8; } .a-boat .halo { fill: rgba(69, 208, 232, .22); }
}

/* status + GPS pill over the captured ones: the card's recipe at full-screen geometry */
/* three classes on purpose: the card's `.live.status` has two and would otherwise win */
.live.status.hero-status { left: 10%; width: 80%; top: 79.5%; height: 3.6%; background: var(--surface); font-size: 5.64cqw; }
.live.gps.hero-gps { left: 22%; width: 56%; top: 82.7%; height: 4%; }

/* the alarm: ring, words and a breath of red on the glass */
[data-anchor-demo] .screen::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .3s ease; border-radius: inherit; box-shadow: inset 0 0 0 3px rgba(229, 72, 77, .55), inset 0 0 60px rgba(229, 72, 77, .28); }
[data-anchor-demo].is-alarm .screen::after { opacity: 1; }
[data-anchor-demo].is-alarm .a-radius { fill: rgba(229, 72, 77, .18); stroke: var(--alarm); }
[data-anchor-demo].is-alarm .a-pulse  { animation: a-pulse 1.1s ease-out infinite; }
[data-anchor-demo].is-alarm .a-boat .dot  { fill: var(--alarm); }
[data-anchor-demo].is-alarm .a-boat .halo { fill: rgba(229, 72, 77, .25); }
.live .is-alarm { color: var(--alarm); }
@keyframes a-pulse { from { opacity: .75; transform: scale(1); } to { opacity: 0; transform: scale(8); } }
[data-anchor-demo] .amap { transition: opacity .5s ease; }
[data-anchor-demo] .minimap > * { transition: opacity .5s ease, fill .35s ease, stroke .35s ease; }
[data-anchor-demo].is-reset .amap, [data-anchor-demo].is-reset .minimap > * { opacity: 0; }

/* The anchor card shows the anchored boat, not the footer. The status rides on a strip shaped like
   the top of the app's own sheet, so the words that matter are still there. */
.a-strip { position: absolute; left: 0; right: 0; bottom: 0; height: 27%; display: grid; place-items: center;
  background: var(--surface); border-radius: 5.2cqw 5.2cqw 0 0; box-shadow: 0 -4px 18px rgba(23, 43, 77, .12);
  font-family: var(--sans); font-weight: 800; font-size: 5.5cqw; letter-spacing: -.02em; color: var(--ok); white-space: nowrap; }
.a-strip b { font-weight: inherit; font-variant-numeric: tabular-nums; }
.a-strip .is-alarm { color: var(--alarm); }
.crop[data-anchor-demo].is-alarm::after { box-shadow: inset 0 0 0 2px rgba(229, 72, 77, .6), inset 0 0 44px rgba(229, 72, 77, .26); }
.crop[data-anchor-demo]::after { transition: box-shadow .3s ease; }

/* Live wind, only over the map: the forecast sheet begins at 52% of the screen. */
.wind { position: absolute; left: 0; top: 0; width: 100%; height: 52.6%; pointer-events: none;
  -webkit-mask-image: linear-gradient(#000 86%, transparent); mask-image: linear-gradient(#000 86%, transparent); }
.phone.main { --w: calc(var(--C) * .405); z-index: 3; animation: rise .8s cubic-bezier(.2,.7,.2,1) both .1s; }
.phone.side { z-index: 1; animation: rise .8s cubic-bezier(.2,.7,.2,1) both; }
.phone.left  { transform: translateX(calc(var(--C) * -.315)) translateY(calc(var(--C) * .046)) rotate(-7deg); animation-delay: .25s; }
.phone.right { transform: translateX(calc(var(--C) *  .315)) translateY(calc(var(--C) * .046)) rotate(7deg); animation-delay: .35s; }
@keyframes rise { from { opacity: 0; translate: 0 22px; } to { opacity: 1; translate: 0 0; } }

/* ── Features ───────────────────────────────────────────────────── */
.features { padding: 26px 0 8px; }
.section-head { display: flex; align-items: baseline; gap: 16px; margin: 0 0 16px; }
.section-head h2 { font-size: 28px; }
.section-head p { margin: 0; color: var(--quiet); font-size: 15px; font-weight: 500; }

.grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.span2 { grid-column: span 2; }

.card {
  background: var(--surface); border-radius: 22px; padding: 14px 16px 16px;
  box-shadow: var(--shadow-sm); border: 1px solid var(--card-line);
  display: flex; flex-direction: column; gap: 12px;
  transition: transform .18s ease, box-shadow .18s ease;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.card:target { box-shadow: 0 0 0 2px var(--accent), var(--shadow-md); }
.card p { margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted); text-wrap: pretty; }
.card-head { display: flex; align-items: center; gap: 10px; }
.card-head h3 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.ico {
  width: 36px; height: 36px; border-radius: 11px; flex: none;
  display: inline-grid; place-items: center; background: var(--tint); color: var(--accent);
  transition: background .2s ease, color .2s ease;
}
.ico svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
/* the tile answers the hand: tint becomes the full accent */
.card:hover .ico, .strip li:hover .ico { background: var(--accent); color: var(--on-accent); }

/* A real crop of the feature's own screen */
/* A fixed aspect ratio, not a fixed height: the visible window is then the
   same 390x200 logical-pixel slice of the capture at every card width, so
   anything laid over it in percentages lands on the same pixels. That is
   what lets the live status line and ring below sit exactly on the app's. */
.crop { position: relative; aspect-ratio: 390 / 200; border-radius: 16px; overflow: hidden; background: var(--inset); container-type: inline-size; }
.crop img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); display: block; }
.crop::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--line); pointer-events: none; }

/* Live replicas of the app's own moving parts, in the app's own type and
   tokens, each covering the captured original exactly. Sizes are in cqw so
   they scale with the crop the way the capture does; every geometry number
   below is measured from the 390x844 screens. */
.live { position: absolute; display: grid; place-items: center; white-space: nowrap; font-family: var(--sans); font-weight: 800; color: var(--ok); letter-spacing: -.02em; line-height: 1; }
.live b { font-weight: inherit; font-variant-numeric: tabular-nums; }
/* anchor: window is image rows 644..844 */
.live.status { left: 12%; width: 76%; top: 11%; height: 16%; background: var(--surface); font-size: 5.64cqw; }
.live.gps { left: 22%; width: 56%; top: 27%; height: 17.5%; border-radius: 999px; background: color-mix(in srgb, var(--ok) 12%, var(--surface)); font-family: var(--mono); font-weight: 700; font-size: 3.08cqw; letter-spacing: .06em; text-transform: uppercase; grid-auto-flow: column; gap: .55em; }
.live.gps svg { width: 1.1em; height: 1.1em; fill: currentColor; }
/* I'm OK, fitted: the screen is drawn at 72% of the crop's width, rows 108..386 of it. Its own
   background is the page colour, so the margins left and right are seamless. Every number below is
   the full-size geometry times 0.72 (ring centre (194.75, 188.75), radius 64.75; timer centre y 294.5). */
.crop.fit { background: var(--page); }
.crop.fit img { position: absolute; left: 14%; top: -19.94cqw; width: 72%; height: auto; object-fit: fill; }
.crop.fit .ring { left: 38%; top: 5.76%; width: 23.91%; height: 46.62%; }
.crop.fit .live.timer { left: 35.6%; width: 28.8%; top: 59.9%; height: 14.4%; font-size: 5.54cqw; }

/* I'm OK: window is image rows 120..320. Measured from the capture's pixels:
   button centre (194.75, 188.75), ring centreline radius 64.75, stroke 5.5.
   The app's arc is the time *elapsed*, clockwise from twelve. */
.ring { position: absolute; left: 33.33%; top: 2%; width: 33.2%; height: 64.75%; transform: rotate(-90deg); overflow: visible; }
.ring circle { fill: none; stroke-width: 9; }
.ring .t { stroke: var(--inset); }
.ring .p { stroke: var(--ok); stroke-linecap: round; stroke-dasharray: 406.8; stroke-dashoffset: 306; transition: stroke-dashoffset 1s linear; }
.live.timer { left: 30%; width: 40%; top: 76%; height: 20%; background: var(--page); font-size: 7.7cqw; font-variant-numeric: tabular-nums; }

/* The app's stat wells (trips/TripsPage.tsx `Stat`): a tiny eyebrow over a Space Grotesk figure */
.wells { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 6px; margin: 0; }
.wells div { background: var(--inset); border-radius: 12px; padding: 7px 4px 6px; text-align: center; min-width: 0; }
.wells dt { font-family: var(--mono); font-weight: 700; font-size: 8.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--quiet); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wells dd { margin: 2px 0 0; font-family: var(--mono); font-weight: 700; font-size: 14px; line-height: 1.15; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── BoatGPT: words on the left, the app's conversation on the right ── */
.gpt { display: grid; grid-template-columns: minmax(0, .94fr) minmax(0, 1.06fr); gap: 16px; padding: 14px 14px 14px 16px; }
.gpt-copy { display: flex; flex-direction: column; gap: 10px; padding-top: 2px; }
.gpt-copy .wells { margin-top: auto; padding-top: 4px; }
.gpt-copy .wells dd { font-size: 17px; color: var(--accent); }
.gpt-copy .wells dt { font-size: 9px; }

/* the app's own bubbles (boat-gpt/components/MessageBubble.tsx) */
.chat { border-radius: 16px; background: var(--inset); padding: 12px; display: flex; flex-direction: column; gap: 8px; overflow: hidden; position: relative; min-height: 100%; }
.msg { font-size: 13.5px; line-height: 1.45; transition: opacity .35s ease, transform .35s ease; }
.msg.me { align-self: flex-end; max-width: 86%; padding: 9px 13px; border-radius: 18px 18px 6px 18px; background: var(--azure-tint); color: var(--text); }
.msg.bot { position: relative; align-self: flex-start; max-width: 94%; padding: 10px 13px 11px; border-radius: 18px 18px 18px 6px; background: var(--surface); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 5px; }
.ground { display: flex; align-items: center; gap: 8px; }
.ground em { font-style: normal; display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700; line-height: 1; color: var(--ok); background: var(--ok-tint); padding: 4px 8px 4px 7px; border-radius: 999px; }
.ground em i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ground small { font-family: var(--mono); font-size: 10.5px; font-weight: 500; color: var(--quiet); }
.section-label { font-family: var(--mono); font-weight: 700; font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--ok); margin-top: 3px; }
.msg .text { color: var(--text); }
.msg .pill { font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--azure); background: var(--azure-tint); border-radius: 999px; padding: 1px 6px; margin-left: 4px; vertical-align: super; line-height: 1.2; transition: opacity .3s ease; }
/* the cited page, as the app's Sources drawer lists it: the manual, then the page and the way to it */
.cite { display: flex; align-items: center; gap: 9px; margin-top: 3px; padding-top: 8px; border-top: 1px solid var(--line); color: var(--azure); transition: opacity .4s ease; }
.cite svg { width: 26px; height: 26px; padding: 6px; border-radius: 8px; background: var(--azure-tint); flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cite span { display: flex; flex-direction: column; gap: 1px; min-width: 0; line-height: 1.25; }
.cite b { font-size: 12.5px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cite small { font-family: var(--mono); font-size: 10.5px; font-weight: 700; }
.composer { margin-top: auto; display: flex; align-items: center; gap: 8px; background: var(--surface); border-radius: 999px; padding: 5px 5px 5px 12px; font-size: 13px; color: var(--soft); box-shadow: var(--shadow-sm); }
.composer svg { width: 18px; height: 18px; flex: none; fill: none; stroke: var(--quiet); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.composer span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.composer b { width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(135deg, var(--azure), var(--azure-up)); position: relative; flex: none; }
.composer b::after { content: ""; position: absolute; left: 11px; top: 12px; width: 7px; height: 7px; border-top: 2px solid #fff; border-left: 2px solid #fff; transform: rotate(45deg); }
/* The answer arriving, as it does in the app: "Reading the manuals…", then the words, then the page.
   All of it is opt-in from site.js. Without it the finished answer simply stands there. */
.phase { display: none; position: absolute; left: 13px; top: 11px; align-items: center; gap: 7px; font-family: var(--mono); font-size: 11px; font-weight: 500; color: var(--quiet); white-space: nowrap; }
.phase i { width: 7px; height: 7px; border-radius: 50%; background: var(--cyan); animation: blink .6s ease-in-out infinite alternate; }
.chat.is-armed .msg { opacity: 0; transform: translateY(6px); }
.chat.is-armed.s1 .msg.me, .chat.is-armed.s2 .msg.bot { opacity: 1; transform: none; }
.chat.is-armed.s2:not(.s3) .msg.bot > :not(.phase) { visibility: hidden; }
.chat.is-armed.s2:not(.s3) .phase { display: inline-flex; }
.chat.is-armed:not(.s4) .msg .pill, .chat.is-armed:not(.s4) .cite { opacity: 0; }
.chat [data-rest] { visibility: hidden; }

/* Small in-token widgets for the two screens we cannot show yet */
.widget { height: 160px; border-radius: 16px; background: var(--inset); padding: 12px; display: flex; flex-direction: column; gap: 8px; position: relative; overflow: hidden; }
.widget .wells div { background: var(--surface); box-shadow: var(--shadow-sm); }
.widget .wells dd { font-size: 13px; }

/* Trips: the app's Current Trip card */
.trip-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.trips .pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; line-height: 1; padding: 6px 10px 6px 9px; border-radius: 999px; background: var(--surface); color: var(--violet); box-shadow: var(--shadow-sm); }
.trips .pill i { width: 8px; height: 8px; border-radius: 50%; background: currentColor; animation: blink 1.2s ease-in-out infinite alternate; }
.elapsed { font-family: var(--mono); font-weight: 700; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
@keyframes blink { from { opacity: .3; } to { opacity: 1; } }
.trackbox { position: relative; flex: 1; min-height: 0; margin: 0 2px; }
.track { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.track path { fill: none; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
.track .leg { stroke: var(--violet); stroke-width: 3; }
.track .pause { stroke: var(--soft); stroke-width: 2.2; stroke-dasharray: .1 6; }
.track .dot { stroke-width: 8; stroke: var(--violet); }
.track .start { stroke: var(--ok); stroke-width: 10; }
.track .stop { stroke-width: 7; }
.track .head { stroke-width: 10; }
.track .head-halo { stroke-width: 22; opacity: .22; animation: halo 1.8s ease-in-out infinite; }
@keyframes halo { 0%, 100% { opacity: .08; } 50% { opacity: .3; } }
.paused { position: absolute; left: 55.8%; top: 65%; transform: translate(-50%, 7px); font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--quiet); white-space: nowrap; }

/* Pair: one watch, two phones. Both maps are the hero's anchor story, on the same clock. */
.pair { flex-direction: row; align-items: center; justify-content: center; gap: 0; }
.mini { position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px; flex: none;
  font-family: var(--mono); font-size: 9px; font-weight: 700; color: var(--quiet); text-transform: uppercase; letter-spacing: .07em; line-height: 1; }
.minimap { display: block; width: 64px; height: 112px; border-radius: 15px; background: var(--water); border: 3px solid var(--bezel); box-shadow: var(--shadow-sm); transition: border-color .3s ease, box-shadow .3s ease; }
.minimap .a-radius { stroke-width: 3.2; }
.minimap .a-track { stroke-width: 5; }
.minimap .a-anchor circle { stroke-width: 5; }
.minimap .a-boat .dot { stroke-width: 4.5; }
.link { flex: 1; max-width: 104px; min-width: 40px; height: 2px; margin: 14px 8px 0; position: relative;
  background: repeating-linear-gradient(90deg, var(--magenta) 0 5px, transparent 5px 10px); animation: flow .9s linear infinite; transition: filter .3s ease; }
@keyframes flow { to { background-position: 10px 0; } }
.link i { position: absolute; top: -3px; left: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--magenta); animation: carry 2.4s cubic-bezier(.5,0,.5,1) infinite; }
@keyframes carry { 0% { left: 0; opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { left: calc(100% - 8px); opacity: 0; } }
.code { position: absolute; left: 50%; top: -34px; transform: translateX(-50%); white-space: nowrap; font-family: var(--mono); font-weight: 700; font-size: 12px; letter-spacing: .14em; color: var(--text); background: var(--surface); padding: 5px 7px 5px 10px; border-radius: 9px; box-shadow: var(--shadow-sm); }
.bell { position: absolute; right: -7px; top: 8px; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--magenta); color: #fff; box-shadow: 0 0 0 2.5px var(--inset); transition: background .3s ease; }
.bell svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* the boat drags up in the hero, and the phone ashore rings down here */
.pair.is-alarm .ashore .minimap { border-color: var(--alarm); box-shadow: 0 0 0 3px rgba(229, 72, 77, .22), var(--shadow-sm); }
.pair.is-alarm .bell { background: var(--alarm); animation: ring .5s ease-in-out infinite; }
.pair.is-alarm .bell::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--alarm); animation: ping 1.1s ease-out infinite; }
.pair.is-alarm .link { filter: hue-rotate(40deg) saturate(1.4); }
@keyframes ring { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-14deg); } 75% { transform: rotate(14deg); } }
@keyframes ping { from { transform: scale(1); opacity: .8; } to { transform: scale(2.3); opacity: 0; } }

/* Built-in strip */
.strip {
  list-style: none; margin: 14px 0 0; padding: 6px 8px;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px;
  background: var(--surface); border-radius: 22px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line);
}
.strip li { display: flex; gap: 12px; align-items: flex-start; padding: 12px 10px; }
.strip li + li { border-left: 1px solid var(--line); padding-left: 16px; }
.strip b { display: block; font-size: 14.5px; font-weight: 700; line-height: 1.3; margin: 1px 0 3px; }
/* block, or the 16px/24px strut of the parent sets the leading instead of this line-height */
.strip span:not(.ico) { display: block; font-size: 13px; line-height: 1.45; color: var(--muted); text-wrap: pretty; }

/* Install + footer */
.install {
  margin-top: 28px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 22px;
  padding: 18px 20px; background: var(--surface); border-radius: 22px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line);
}
.install img { display: block; width: 92px; height: 92px; border-radius: 14px; background: #fff; padding: 6px; box-shadow: 0 0 0 1px var(--line); }
.install h2 { font-size: 24px; margin-bottom: 4px; }
.install p { margin: 0; color: var(--muted); max-width: 64ch; font-size: 15px; text-wrap: balance; }
.install p b { color: var(--text); font-weight: 700; }
.no-qr-words { display: none; }
.foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 24px 0 32px; font-size: 14px; color: var(--quiet); flex-wrap: wrap; }
.foot nav { display: flex; gap: 18px; font-weight: 500; flex-wrap: wrap; }
.foot a { transition: color .15s ease; }
.foot a:hover { color: var(--text); }

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .strip li:nth-child(3) { border-left: 0; padding-left: 10px; }
  .strip li:nth-child(n+3) { border-top: 1px solid var(--line); }
}
@media (max-width: 860px) {
  .nav { display: none; }
  .top { height: 64px; justify-content: space-between; }
  /* one column: the fan goes under the words, sized to the page rather than to half of it */
  .hero { --C: min(520px, 100vw - 40px); grid-template-columns: minmax(0, 1fr); gap: 4px; padding-top: 8px; }
  h1 { font-size: clamp(34px, 8vw, 46px); }
  .lede { font-size: 16px; margin-bottom: 22px; }
  .hero-phones { margin-top: 6px; }
  .install { grid-template-columns: auto 1fr; }
  .install .stores { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  .top, .hero, .features, .install, .foot { width: min(1200px, 100% - 28px); }
  .grid { gap: 10px; }
  .card { padding: 12px 12px 14px; gap: 10px; border-radius: 18px; }
  .card p { font-size: 13.5px; }
  .card-head h3 { font-size: 16px; }
  .crop, .chat, .widget { border-radius: 12px; }
  /* BoatGPT stacks like the other cards: the screen first, the words under it */
  .gpt { grid-template-columns: minmax(0, 1fr); padding: 12px 12px 14px; gap: 12px; }
  .gpt .chat { order: -1; min-height: 0; }
  .strip { grid-template-columns: 1fr; padding: 4px 6px; }
  .strip li + li, .strip li:nth-child(3) { border-left: 0; border-top: 1px solid var(--line); padding-left: 10px; }
  .section-head { flex-direction: column; gap: 2px; }
  .install { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .install img, .qr-words { display: none; }
  .no-qr-words { display: inline; }
  .install .stores { grid-column: auto; }
}
@media (max-width: 600px) {
  /* A narrow screen gets one phone, and it is the home screen: every tool in a single view, and its
     content sits in the top two thirds, which is exactly what the fold leaves showing. The live
     anchor watch is the first card underneath, so it is not shown twice. */
  /* 236 px of phone is 511 tall and its last tile (BoatGPT) ends near 382: the fade only ever crosses empty screen */
  .hero-phones { height: 408px; overflow: hidden; align-items: flex-start;
    -webkit-mask-image: linear-gradient(#000 94%, transparent); mask-image: linear-gradient(#000 94%, transparent); }
  .hero-phones::before { top: 40%; width: 120%; height: 90%; }
  .phone.side { display: none; }
  .phone.main { --w: 236px; position: relative; }
}
@media (max-width: 520px) {
  .grid { grid-template-columns: minmax(0, 1fr); }
  .span2 { grid-column: auto; }
  .actions .btn-lg { width: 100%; }
  .stores { width: 100%; }
  .actions .store { flex: 1; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001s !important; animation-iteration-count: 1 !important; transition: none !important; }
}

/* == Fonts, served from here: no request to Google ================== */
@font-face { font-family: "Outfit"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("/fonts/outfit-latin-wght-normal.woff2") format("woff2-variations"), url("/fonts/outfit-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Outfit"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("/fonts/outfit-latin-ext-wght-normal.woff2") format("woff2-variations"), url("/fonts/outfit-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url("/fonts/space-grotesk-latin-wght-normal.woff2") format("woff2-variations"), url("/fonts/space-grotesk-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url("/fonts/space-grotesk-latin-ext-wght-normal.woff2") format("woff2-variations"), url("/fonts/space-grotesk-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* == Inner pages: about, the legal pages, changelog, contact ========== */
.nav a[aria-current="page"] { color: var(--text); }
.page { width: min(720px, 100% - 40px); margin: 0 auto; padding: 22px 0 8px; }
.page-head { padding: 12px 0 24px; border-bottom: 1px solid var(--line); margin-bottom: 28px; }
.page-head h1 { font-size: clamp(34px, 5vw, 50px); line-height: 1.02; letter-spacing: -.03em; margin: 10px 0 12px; text-wrap: balance; }
.page-sub { font-size: 18px; line-height: 1.5; color: var(--muted); margin: 0; max-width: 36em; text-wrap: pretty; }
.page-meta { margin: 16px 0 0; font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--quiet); }

.prose { font-size: 16.5px; line-height: 1.62; }
.prose > * + * { margin-top: 1em; }
.prose p, .prose li, .prose dd { color: var(--muted); text-wrap: pretty; }
.prose strong { color: var(--text); font-weight: 700; }
.prose a { color: var(--azure); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.prose a:hover { color: var(--azure-up); }
.prose h2 { font-size: 22px; letter-spacing: -.02em; margin-top: 2.2em; display: flex; gap: 12px; align-items: baseline; }
.prose h2 > span { font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: .04em; color: var(--azure); flex: none; min-width: 2.4em; }
.prose h3 { font-size: 17px; margin-top: 1.7em; }
.prose h2 + p, .prose h3 + p, .prose h2 + ul, .prose h3 + ul { margin-top: .55em; }
.prose ul, .prose ol { padding-left: 1.25em; }
.prose li + li { margin-top: .45em; }
.prose li::marker { color: var(--azure); }
.prose .short { background: var(--surface); border-radius: 20px; padding: 18px 20px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line); }
.prose .short > h2 { margin-top: 0; font-size: 15px; }
.prose .short > h2 > span { min-width: 0; }
.prose .short ul { margin-top: 10px; }
.prose .short li { color: var(--text); }

/* a data inventory: one card per kind of data */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; margin: 1.1em 0 0; }
.facts > div { background: var(--surface); border-radius: 16px; padding: 14px 16px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line); }
.facts dt { font-weight: 700; color: var(--text); font-size: 15px; margin-bottom: 4px; }
.facts dd { margin: 0; font-size: 14px; line-height: 1.5; }
.facts dd + dd { margin-top: 6px; }
.facts .tag { display: inline-block; font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--quiet); }

.contact-card { display: flex; align-items: center; gap: 16px; padding: 18px 20px; margin-top: 1.4em; background: var(--surface); border-radius: 20px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line); }
.contact-card .ico { width: 44px; height: 44px; border-radius: 14px; }
.contact-card b { display: block; font-size: 14px; color: var(--quiet); font-weight: 600; margin-bottom: 2px; }
.contact-card a { font-size: 19px; font-weight: 700; color: var(--azure); text-decoration: none; letter-spacing: -.01em; }
.contact-card a:hover { text-decoration: underline; }

.release { padding: 18px 20px; background: var(--surface); border-radius: 20px; box-shadow: var(--shadow-sm); border: 1px solid var(--card-line); }
.release + .release { margin-top: 14px; }
.release h2 { margin: 0 0 6px; font-size: 20px; letter-spacing: -.02em; }
.release time { display: block; font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--quiet); margin-bottom: 10px; }
.release ul { margin: 8px 0 0; }
.release h3 { font-size: 15px; margin-top: 1.2em; }

.oops { text-align: center; padding: 60px 0 40px; }
.oops h1 { font-size: clamp(36px, 6vw, 56px); margin: 12px 0; }
.oops p { color: var(--muted); font-size: 17px; margin: 0 0 22px; }

@media (max-width: 640px) {
  .page { width: min(720px, 100% - 28px); }
  .prose { font-size: 16px; }
  .prose h2 { font-size: 20px; }
  .contact-card { flex-direction: column; align-items: flex-start; }
}
