:root{
  --ink:#10263B; --ink-soft:#4A5E71; --paper:#F3F7F9; --card:#FFFFFF;
  --line:#D8E2E8;
  --excellent:#0E8A5F; --go:#2C7FB8; --marginal:#C98A00; --nogo:#B3402F; --off:#8A98A5;
  --prime:#FF5A1F;
  --disp:'Barlow Condensed',Arial Narrow,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;
  --body:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--paper);color:var(--ink);font-family:var(--body);font-size:15px;line-height:1.45;
     padding-bottom:48px}
.wrap{max-width:680px;margin:0 auto;padding:0 14px}

/* masthead */
header{border-bottom:2px solid var(--ink);padding:18px 0 12px;margin-bottom:14px;
  background-image:repeating-linear-gradient(180deg,transparent 0 11px,rgba(16,38,59,.05) 11px 12px)}
.mast{display:flex;justify-content:space-between;align-items:flex-end;gap:10px}
h1{font-family:var(--disp);font-weight:700;font-size:30px;letter-spacing:.04em;text-transform:uppercase;line-height:.95}
h1 span{display:block;font-size:15px;letter-spacing:.28em;color:var(--ink-soft)}
.stamp{text-align:right;font-family:var(--mono);font-size:11px;color:var(--ink-soft);white-space:nowrap}
.stamp b{color:var(--ink)}
/* Freshness, in plain words, always visible. Green is not decoration here —
   the failure being guarded against is a fresh-looking page over stale calls. */
.fresh{margin-top:8px;font-size:13.5px;font-weight:600;padding:6px 10px;border-radius:4px;
  border-left:4px solid var(--excellent);background:#EAF7F0;color:#0B5F42}
.fresh-warn{border-left-color:var(--marginal);background:#FFF8E6;color:#6B4E00}
.fresh-bad{border-left-color:var(--nogo);background:#FDEEEB;color:#7A2617}
.live{margin-top:10px;font-family:var(--mono);font-size:12px;background:var(--ink);color:#DFF0E8;
  padding:7px 10px;border-radius:4px;display:flex;gap:14px;flex-wrap:wrap}
.live em{font-style:normal;color:#8FD8B8}
.live .muted{color:#8FA6B8}
.live .stale{color:#FFC08A}

/* banner for degraded / stale states */
.banner{border:1.5px solid var(--marginal);background:#FFF8E6;border-radius:6px;padding:9px 12px;
  margin-bottom:14px;font-size:13.5px;color:#6B4E00}
.banner.bad{border-color:var(--nogo);background:#FDEEEB;color:#7A2617}
.banner b{font-family:var(--disp);letter-spacing:.08em;text-transform:uppercase}

/* demotion notice — a withdrawn flag has to be as visible as the flag was */
.demote{border:1.5px solid var(--nogo);border-left-width:5px;border-radius:7px;
  background:#FDEEEB;padding:11px 13px;margin-bottom:14px}
.demote-head{font-family:var(--disp);font-weight:700;font-size:14px;letter-spacing:.14em;
  text-transform:uppercase;color:#7A2617;margin-bottom:5px}
.demote-body b{font-family:var(--disp);font-weight:700;font-size:16px;color:var(--ink)}
.demote-body p{font-size:13.5px;line-height:1.5;color:#5C2415;margin-top:5px}

/* best day hero */
.hero{background:var(--card);border:1.5px solid var(--ink);border-radius:8px;overflow:hidden;margin-bottom:16px;
      box-shadow:0 2px 0 rgba(16,38,59,.15)}
.hero-flag{background:var(--prime);color:#fff;font-family:var(--disp);font-weight:700;font-size:14px;
  letter-spacing:.2em;text-transform:uppercase;padding:5px 12px;display:flex;justify-content:space-between;gap:8px}
.hero-main{padding:14px 14px 6px;display:flex;justify-content:space-between;align-items:baseline;flex-wrap:wrap;gap:4px}
.hero-main .day{font-family:var(--disp);font-weight:700;font-size:34px;text-transform:uppercase;line-height:1}
.hero-main .dest{font-family:var(--disp);font-weight:600;font-size:22px;color:var(--excellent);text-transform:uppercase}
.hero-stats{display:flex;gap:8px;padding:8px 14px 4px;flex-wrap:wrap}
.chip{font-family:var(--mono);font-size:11.5px;border:1px solid var(--line);border-radius:4px;padding:3px 8px;background:#F7FAFB}
.chip b{font-weight:600}
.hero-note{padding:8px 14px 12px;font-size:13.5px;color:var(--ink-soft)}
/* The lead story's one sentence — the front page in a single line, so it gets
   body-text weight rather than the muted note colour around it. */
.hero-lede{font-size:16px;line-height:1.5;color:var(--ink);margin-bottom:4px}
.hero-jump{margin-top:10px;font-family:var(--disp);font-weight:600;font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;background:none;color:var(--ink-soft);
  border:1px solid var(--line);border-radius:5px;padding:6px 12px;cursor:pointer}
.hero-jump:hover{color:var(--ink);border-color:var(--ink)}

/* shape-of-day bar */
.shape{padding:10px 14px 4px}
.shape-label{font-family:var(--disp);font-weight:600;font-size:13px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:5px}
.bar{position:relative;height:34px;border-radius:5px;overflow:hidden;display:flex;border:1px solid var(--line)}
.seg{height:100%;display:flex;align-items:center;justify-content:center;font-family:var(--mono);
     font-size:10px;font-weight:600;color:#fff;white-space:nowrap;overflow:hidden}
.ticks{display:flex;justify-content:space-between;font-family:var(--mono);font-size:9.5px;color:var(--ink-soft);margin-top:3px}
.s-glass{background:#0E8A5F}.s-beach{background:#2C7FB8}.s-run{background:#7BA7C9}.s-late{background:#C98A00}.s-off{background:#B9C6D0;color:#41525f}

/* day rail */
.rail-label{font-family:var(--disp);font-weight:700;font-size:16px;letter-spacing:.18em;text-transform:uppercase;margin:4px 0 8px}

/* wind chart */
.chart{background:var(--card);border:1px solid var(--line);border-radius:8px;overflow:hidden;margin-bottom:16px}
.chart-head{display:flex;justify-content:space-between;align-items:center;padding:10px 12px 6px;flex-wrap:wrap;gap:6px}
.chart-head .t{font-family:var(--disp);font-weight:700;font-size:16px;letter-spacing:.18em;text-transform:uppercase}
.times{display:flex;gap:6px}
.tbtn{font-family:var(--mono);font-size:11px;border:1px solid var(--line);background:#F7FAFB;border-radius:4px;
  padding:4px 9px;cursor:pointer;color:var(--ink)}
.tbtn.on{background:var(--ink);color:#fff;border-color:var(--ink)}
.lbtn{font-family:var(--mono);font-size:11px;border:1px solid var(--line);background:#F7FAFB;border-radius:4px;padding:4px 9px;cursor:pointer;color:var(--ink-soft)}
.lbtn.on{background:#0E4D7A;color:#fff;border-color:#0E4D7A}
.legend{display:flex;gap:10px;align-items:center;font-family:var(--mono);font-size:10px;color:var(--ink-soft);padding:0 12px 10px;flex-wrap:wrap}
.sw{width:14px;height:9px;border-radius:2px;display:inline-block;margin-right:4px;vertical-align:-1px}
.stage{position:relative;width:100%;aspect-ratio:600/430;background:linear-gradient(160deg,#BFD9E6,#A9CBDD 60%,#9CC2D6)}
.chart-fallback{position:absolute;inset:0}
.chart-fallback svg,.chart-fallback canvas{position:absolute;inset:0;width:100%;height:100%}
/* real chart */
.chart-map{position:absolute;inset:0;z-index:1;background:#A9CBDD}
.chart-overlay{position:absolute;inset:0;pointer-events:none}
.leaflet-container{font-family:var(--body);background:#A9CBDD}
/* Mute the chart under the overlay. The comfort colours have to be the loudest
   thing on the water — a full-saturation basemap fought them and both lost.
   Land keeps a little more contrast than water so the shoreline still reads. */
.leaflet-tile-pane{filter:saturate(.38) brightness(1.14) contrast(.88)}
.chart-wash{position:absolute;inset:0;background:#EFF3F2;opacity:.34;pointer-events:none}
.leaflet-control-attribution{font-size:9px;background:rgba(255,255,255,.72)}
.chart-tools{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:8px 12px 0}
.chart-src{font-family:var(--mono);font-size:10.5px;color:var(--ink-soft)}
.chart-src b{color:var(--ink)}
.warn-inline{font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--nogo);border:1px solid var(--nogo);border-radius:3px;padding:2px 6px;margin-left:auto}

/* chart pins — divIcons so they inherit the paper styling, no marker images */
.pin-buoy,.pin-dest,.pin-gate{background:none;border:0}
.pin-dot{display:block;width:9px;height:9px;border-radius:50%;background:#10263B;
  box-shadow:0 0 0 3px rgba(16,38,59,.25)}
.pin-label{position:absolute;left:13px;top:-5px;white-space:nowrap;font-family:var(--mono);
  font-size:10px;line-height:1.25;text-shadow:0 1px 2px #fff,0 -1px 2px #fff,1px 0 2px #fff,-1px 0 2px #fff}
.pin-label b{display:block;font-weight:600;color:#10263B;font-size:10.5px}
.pin-label i{display:block;font-style:normal;color:#0E4D7A;font-weight:600}
.pin-label em{display:block;font-style:normal;font-size:8.5px;color:#41525F;opacity:.8}
.pin-dest .pin-mark{display:block;width:7px;height:7px;border-radius:50%;background:#41525F;
  box-shadow:0 0 0 2px rgba(255,255,255,.8);font-size:0}
.pin-dest.lead .pin-mark,.pin-dest.home .pin-mark{background:var(--excellent);font-size:9px;
  width:auto;height:auto;border-radius:0;box-shadow:none;color:var(--excellent);line-height:1}
.pin-dest.home .pin-mark{color:var(--nogo)}
.pin-name{position:absolute;left:10px;top:-4px;white-space:nowrap;font-family:var(--mono);
  font-size:9.5px;color:#2C3E4E;text-shadow:0 1px 2px #fff,0 -1px 2px #fff,1px 0 2px #fff,-1px 0 2px #fff}
.pin-dest.lead .pin-name{font-weight:600;color:#0B5F42;font-size:10.5px}
.pin-gate .gate-arrow{display:block;font-size:17px;line-height:1;color:#0E4D7A;font-weight:700;
  text-shadow:0 1px 2px #fff,0 -1px 2px #fff,1px 0 2px #fff,-1px 0 2px #fff}
.pin-gate.ebb .gate-arrow{color:var(--nogo)}
.gate-label{position:absolute;left:16px;top:-2px;white-space:nowrap;font-family:var(--mono);
  font-size:9.5px;color:#2C3E4E;text-shadow:0 1px 2px #fff,0 -1px 2px #fff,1px 0 2px #fff,-1px 0 2px #fff}
.gate-label i{font-style:normal;color:#0E4D7A}
.leaflet-popup-content{font-size:12.5px;line-height:1.45}
.leaflet-popup-content .mono{font-family:var(--mono);font-size:10.5px;color:var(--ink-soft)}

/* phones: give the chart more height than a 600x430 box allows, and keep the
   pin labels from crowding */
@media (max-width:520px){
  .stage{aspect-ratio:3/4}
  .pin-name{font-size:9px}
  .pin-label{font-size:9.5px}
  .warn-inline{margin-left:0}
}
.chart-foot{display:flex;gap:8px;padding:8px 12px 10px;flex-wrap:wrap}

/* time scrubber */
.scrub{padding:2px 12px 8px;display:flex;align-items:center;gap:10px}
.scrub input[type=range]{flex:1;accent-color:#0E4D7A;height:22px}
.scrub-read{font-family:var(--mono);font-size:11px;color:var(--ink-soft);text-align:right;min-width:132px}
.scrub-read b{display:block;color:var(--ink);font-size:12px}

/* ---------------------------------------------------------- the week
   Day stories, not console rows. Layer 1 is a headline and one sentence; the
   numbers and the doctrine sit behind two progressive disclosures so the front
   page stays readable by someone who has never docked a boat. */
.week{margin:18px 0 6px}
.week-head{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  border-bottom:2px solid var(--ink);padding-bottom:5px;margin-bottom:12px;flex-wrap:wrap}
.week-head h2{font-family:var(--disp);font-weight:700;font-size:23px;letter-spacing:.05em;
  text-transform:uppercase;line-height:1}
.week-head .kicker{font-family:var(--mono);font-size:10.5px;color:var(--ink-soft)}

.story{background:var(--card);border:1px solid var(--line);border-left:5px solid var(--off);
  border-radius:7px;margin-bottom:10px;overflow:hidden}
.story.v-excellent{border-left-color:var(--excellent)}
.story.v-go{border-left-color:var(--go)}
.story.v-marginal{border-left-color:var(--marginal)}
.story.v-nogo{border-left-color:var(--nogo)}
.story.v-off{border-left-color:var(--off)}
.story.open{border-color:var(--ink);box-shadow:0 2px 0 rgba(16,38,59,.15)}

.story-head{display:block;width:100%;text-align:left;background:none;border:0;
  padding:12px 14px 11px;cursor:pointer;font:inherit;color:inherit;position:relative}
.story-top{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.story-day{font-family:var(--disp);font-weight:700;font-size:21px;letter-spacing:.03em;
  text-transform:uppercase;line-height:1}
.story-watch{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--prime);border:1px solid var(--prime);border-radius:3px;padding:1px 5px}
.story-flag{font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--prime);margin-top:5px}
.story-verdict{font-family:var(--disp);font-weight:600;font-size:16px;letter-spacing:.04em;
  text-transform:uppercase;margin-top:3px}
.story-lede{font-size:15px;line-height:1.5;margin-top:5px;color:var(--ink)}
/* Tide-timed destinations state a window, not a leave-by time. */
.tideline{font-family:var(--mono);font-size:11.5px;color:#0E4D7A;background:#EAF3F7;
  border-radius:4px;padding:5px 9px;margin-top:7px;display:inline-block}
/* Layer 1: the other kinds of day this forecast supports. */
.alts{margin-top:8px;display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;
  font-size:13px;color:var(--ink-soft)}
.alts-k{font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-soft)}
.alt b{font-weight:600;color:var(--ink)}
.alt i{font-style:normal;font-family:var(--mono);font-size:10.5px;color:var(--ink-soft)}
/* No separator glyph: when the list wraps on a phone the dot orphans at the
   start of the next line. The gap and the type chip separate them well enough. */
.alt{white-space:nowrap}
/* Layer 2: every option with its reason. */
.options{margin:11px 0 4px}
.options-k{font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);margin-bottom:6px}
.options ul{list-style:none}
.opt{border:1px solid var(--line);border-radius:6px;padding:8px 10px;margin-bottom:6px;background:#F7FAFB}
.opt.lead{border-color:var(--go);background:#F2F8FC}
.opt-head{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.opt-head b{font-family:var(--disp);font-weight:700;font-size:16px;letter-spacing:.02em}
.opt-type{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-soft);border:1px solid var(--line);border-radius:3px;padding:1px 5px;background:#fff}
.opt-lead{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:#fff;background:var(--go);border-radius:3px;padding:2px 6px}
.opt p{font-size:13.5px;color:var(--ink-soft);margin-top:4px}
.opt-gate{font-family:var(--mono);font-size:10.5px;color:#8A6A00;margin-top:4px}

.story-more-cue{display:inline-block;margin-top:8px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft)}
.story-more-cue .caret{margin-left:4px}
.story.open .story-more-cue .caret{display:inline-block;transform:rotate(180deg)}
.story-head:hover .story-more-cue{color:var(--ink)}
.story-head:focus-visible{outline:2px solid var(--go);outline-offset:-3px}

.story-more{padding:0 14px 13px;border-top:1px solid var(--line);margin-top:2px}
.story-more .shape{padding:11px 0 3px}

.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:10px 0}
.cell{border:1px solid var(--line);border-radius:5px;padding:6px 8px;background:#F7FAFB}
.cell .k{font-family:var(--disp);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
.cell .v{font-family:var(--mono);font-size:12.5px;font-weight:600}

/* layer 2 risk: plain sentence up front, trap name in small print beneath */
.risk{border-left:3px solid var(--marginal);background:#FFFBF0;border-radius:0 5px 5px 0;
  padding:9px 11px;margin:10px 0 2px}
.risk-label{font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.14em;
  text-transform:uppercase;color:#8A6A00;margin-bottom:3px}
.risk p{font-size:14px;line-height:1.45;color:var(--ink)}
.risk-trap{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--ink-soft);margin-top:5px}

.full-toggle{margin-top:12px;font-family:var(--disp);font-weight:600;font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;background:none;color:var(--ink-soft);
  border:1px solid var(--line);border-radius:5px;padding:6px 12px;cursor:pointer}
.full-toggle:hover{color:var(--ink);border-color:var(--ink)}
.full{margin-top:11px;padding-top:11px;border-top:1px dashed var(--line)}
.full p{font-size:13px;color:var(--ink-soft);margin-top:8px}
.sources{font-family:var(--mono);font-size:10.5px;line-height:1.6;color:var(--ink-soft);
  border-top:1px dotted var(--line);margin-top:10px;padding-top:8px}

.await{font-family:var(--mono);font-size:11.5px;color:var(--ink-soft);border:1px dashed var(--line);
  border-radius:5px;padding:8px 10px;margin-top:8px;background:#F7FAFB}

@keyframes pulse{50%{opacity:.35}}

/* NWS zone text */
.zone{background:var(--card);border:1px solid var(--line);border-radius:8px;padding:14px;margin-top:16px}
.zone .rail-label{margin-top:0}
.zone-body{font-family:var(--mono);font-size:11.5px;color:var(--ink-soft);line-height:1.5}
.zone-body .hl{color:var(--nogo);font-weight:600;display:block;margin-bottom:6px}
.zone-body .pd{margin-bottom:5px}
.zone-body .pd b{color:var(--ink)}

footer{margin-top:22px;font-family:var(--mono);font-size:10.5px;color:var(--ink-soft);
  border-top:1px solid var(--line);padding-top:10px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:6px}
footer .warn{color:var(--nogo)}
.c-excellent{color:var(--excellent)}.c-go{color:var(--go)}.c-marginal{color:var(--marginal)}.c-nogo{color:var(--nogo)}.c-off{color:var(--off)}

/* required day-shape line, beach-test result, and derived timing facts */
.shapeline{font-family:var(--mono);font-size:12.5px;font-weight:600;color:var(--ink);
  background:#EAF3F7;border-left:3px solid #0E4D7A;border-radius:0 4px 4px 0;
  padding:7px 10px;margin:10px 0 6px}
.beachline{font-family:var(--mono);font-size:11.5px;color:var(--ink-soft);
  padding:0 0 4px}
/* ROUTING.md invariants. The pattern names the day, the gates carry their own
   verdict, and the risk is always one of the eight named traps — so each gets
   its own line rather than being buried in the note. */
.patternline{font-family:var(--mono);font-size:11px;letter-spacing:.02em;
  color:var(--ink-soft);text-transform:uppercase;padding:0 0 6px}
.gateline{font-family:var(--mono);font-size:11.5px;color:var(--ink-soft);
  padding:0 0 4px}
.riskline{font-family:var(--mono);font-size:11.5px;font-weight:600;
  color:#8A3B12;background:#FDF1E7;border-left:3px solid #C2571A;
  border-radius:0 4px 4px 0;padding:6px 9px;margin:2px 0 8px}
.facts{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0 2px}
.facts span{font-family:var(--mono);font-size:10.5px;color:var(--ink-soft);
  border:1px solid var(--line);border-radius:4px;padding:2px 7px;background:#F7FAFB}
.facts b{color:var(--ink);font-weight:600}
.hero-note .shapeline{margin-top:2px}

/* Narrow screens: "Bow Bells Report" is a longer masthead than the space a
   phone gives it alongside the scan stamp, so stack them instead of letting
   the stamp clip. */
@media (max-width: 520px){
  h1{font-size:25px}
  h1 span{font-size:12px;letter-spacing:.16em;margin-top:2px}
  .mast{flex-direction:column;align-items:flex-start;gap:6px}
  .stamp{text-align:left;white-space:normal}
}
