/* Caribbean Guard coastal identity. Safety colors and map geometry are unchanged.
   Layout: one panel on desktop; a scrollable list / detail sheet on mobile. */
:root{--ink:#132f3c;--paper:#fffefa;--muted:#536974;--ocean:#126780;--line:#dce3e3;--sand:#f4f3ec;--panel:390px;--header:80px;--sheet-r:18px}
body{background:var(--ink)}
button,a,summary{touch-action:manipulation}
.topbar{height:var(--header);padding:8px 24px;background:var(--paper);gap:16px;z-index:1300;border-color:var(--line)}
.brand{flex-direction:row;align-items:center;gap:12px;font-size:18px;letter-spacing:-.04em;overflow:visible;max-width:none;white-space:nowrap}
.brand img{object-fit:contain;width:56px;height:56px;flex:none}
.brand-text{display:block}
.brand small{font-size:12px;text-transform:none;letter-spacing:0;margin-top:5px;font-weight:400}
.region-label{font-size:12px;color:var(--muted);border-left:1px solid var(--line);padding-left:20px;margin-left:8px}
.sos{border-radius:6px;box-shadow:none;background:transparent;color:#a72222;border:1px solid #e3bbbb;padding:0 12px;gap:6px;cursor:pointer}
.sos .word{text-transform:none;letter-spacing:0}
.lang{border-radius:6px;border-color:var(--line)}
.lang button{padding:0 12px;color:var(--ink)}
.lang button[aria-pressed=true]{background:var(--ink)}
.dock{background:var(--paper);display:flex;flex-direction:column;overflow:hidden;box-shadow:none}
.railhead{display:block;padding:24px 24px 18px;border:0;flex:none}
.coast-kicker{font-size:12px;font-weight:600;letter-spacing:.1em;color:var(--ocean);margin:0 0 12px}
.railhead h1{font-size:32px;line-height:1.06;letter-spacing:-.055em;font-weight:600;margin:0 0 12px}
.railhead .what{font-size:14px;line-height:1.5;color:var(--muted);margin:0}
.review-note{font-size:12px;line-height:1.5;color:var(--muted);margin:12px 0 0;padding-left:10px;border-left:2px solid #93a7ad}
.list-heading{display:flex;align-items:center;justify-content:space-between;padding:0 24px 8px;flex:none}
.rail-eyebrow{display:block;margin:0;font-size:12px;color:var(--muted);letter-spacing:.1em}
#list-toggle{font:inherit;font-size:12px;font-weight:600;background:transparent;color:var(--ocean);border:0;min-height:44px;padding:0 4px;cursor:pointer}
.strip{flex:1;min-height:0;display:flex;flex-direction:column;gap:0;padding:0 16px;overflow-y:auto;overflow-x:hidden;scroll-snap-type:none;mask-image:none;-webkit-mask-image:none;scrollbar-width:thin;scrollbar-color:#b6c6ca transparent}
.strip::-webkit-scrollbar{display:block;width:4px}
.strip::-webkit-scrollbar-thumb{background:#b6c6ca;border-radius:4px}
.card{position:relative;flex:none;max-width:none;width:100%;border:0;border-bottom:1px solid var(--line);border-radius:0;background:transparent;box-shadow:none;padding:17px 30px 17px 8px;scroll-snap-align:none}
.card:after{content:'';position:absolute;right:12px;top:27px;width:7px;height:7px;border-right:1.5px solid var(--muted);border-top:1.5px solid var(--muted);transform:rotate(45deg)}
.card:hover,.card[aria-current=true]{background:#edf3f3;border-radius:6px}
.card .nm{font-size:16px;line-height:1.3;font-weight:600;letter-spacing:-.02em}
.card .pill{font-size:14px;line-height:1.4;font-weight:600;letter-spacing:0;gap:10px;margin-top:6px}
.card .pill .sw{width:26px}
.card .hours{font-size:12px;margin:5px 0 0 36px;color:var(--muted)}
.card.void{background:transparent;border:0;border-bottom:1px dashed #becace;box-shadow:none}
.card.void .nm{font-size:14px;color:var(--muted)}
.card.void .vd{font-size:12px;margin-top:5px;color:var(--muted);font-weight:400}
.dockrow{order:5;flex:none;margin:0;padding:8px 16px;background:var(--sand);backdrop-filter:none;color:var(--ink);border:0;border-top:1px solid var(--line);border-radius:0;box-shadow:none;gap:8px;min-height:60px}
.dockrow .btn-chip{display:inline-flex;background:transparent;color:var(--ink);border:1px solid #b8c8cd;border-radius:6px;font-size:12px;min-height:44px;padding:0 10px}
.dockrow .txt{color:var(--muted);text-decoration-color:#94a6ad;font-size:12px;text-align:left;min-height:44px}
.dockrow .rf{background:transparent;color:var(--ink);height:44px;width:44px}
.counter,.legend-perm,.locate-first{display:none!important}
.forecast{order:4;flex:none;border-top:1px solid var(--line);padding:10px 16px 0;background:var(--paper);max-height:32vh;overflow:auto}
.forecast-title{margin:0 0 8px;font-size:12px;color:var(--muted);font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.forecast-empty{font-size:13px;color:var(--muted);margin:0 0 16px}
.forecast:has(.sea:not([hidden])) .forecast-empty{display:none}
.forecast .sea{margin:0 0 10px;padding:10px;background:#eef3f3;color:var(--ink);border:0;border-radius:8px}
.forecast .sea .head,.forecast .sea .stamp,.forecast .sea .eyebrow,.forecast .sea .lbl,.forecast .sea .foot,.forecast .sea .foot a,.forecast .sea .val{color:var(--muted)}
.forecast .sea .val{color:var(--ink)}
.forecast .sea .lbl{text-shadow:none;white-space:normal}
.forecast .sea .tile{background:#dce8e9;color:var(--ocean);border-radius:50%}
.forecast .sea .cols{margin:0 0 8px}
.forecast .sea .foot{margin:0;line-height:1.4}
.forecast .sea .foot>div+div{margin-top:3px}
.forecast .sea .stamp{font-size:inherit;font-weight:400;white-space:normal}
.leaflet-marker-icon.lbl.sea{background:transparent;padding:0;margin:0;border-radius:0}
.fab,.compass{box-shadow:0 2px 8px #0002;border-radius:50%;width:44px;height:44px}
.fab:focus-visible,.compass:focus-visible,.dockrow :focus-visible{outline-color:var(--ocean)}
/* Detail rhythm: 20px side inset, 12px between sections, 8px within a component. */
.sheet{--detail-inset:20px;--detail-gap:12px;--detail-tight:8px;background:var(--paper);box-shadow:0 -4px 24px #0002}
.sheet-body{padding:16px var(--detail-inset) 24px}
.sheet h2{font-size:27px;font-weight:600;letter-spacing:-.045em;line-height:1.1}
.sheet .sub{font-weight:400;line-height:1.5;margin:8px 0 20px}
.sheet .close{box-shadow:none;top:10px;right:28px;width:44px;height:44px;border:1px solid var(--line);border-radius:50%;background:var(--paper);color:var(--ink)}
.statuscard{display:grid;grid-template-columns:44px minmax(0,1fr);column-gap:10px;row-gap:4px;align-items:center;background:#2d6781;border-radius:10px;padding:16px;border-left:0}
.statuscard>.tile{grid-column:1;grid-row:1 / span 3;margin:0;width:44px;height:44px;align-self:start}
.statuscard>.eyebrow{grid-column:2;grid-row:1;margin:0}
.statuscard .instr{grid-column:2;grid-row:2;font-size:18px;line-height:1.23;margin:0}
.statuscard .why,.statuscard .sos911{grid-column:1 / -1}
.statuscard .hours{grid-column:2;grid-row:3;margin:0;font-size:13px;line-height:1.35}
.statuscard .why{font-size:14px;line-height:1.48;margin:12px 0 0}
.statuscard>.tile .symbol{width:44px;height:44px}
.statuscard>.tile svg{width:28px;height:28px}
.sheet .escape{display:block;line-height:1.5}
.zone-detail{display:flex;flex-direction:column;min-height:100%}
.zone-top,.zone-lower{flex:none}
.sheet-weather{border:1px solid var(--line);border-radius:10px;background:#f4f8f9;padding:12px;margin:14px 0;color:var(--ink)}
.weather-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.weather-head .eyebrow{margin:0}
.weather-time{font-size:11px;color:var(--muted);white-space:nowrap}
.weather-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:12px}
.weather-metrics>div{min-width:0;display:flex;flex-direction:column;gap:3px}
.weather-metrics span{font-size:11px;color:var(--muted)}
.weather-metrics strong{font-size:17px;line-height:1.2;font-weight:700;white-space:nowrap}
.weather-foot,.weather-empty{font-size:11px;line-height:1.4;color:var(--muted);margin:10px 0 0}
.weather-foot a{color:var(--ocean)}
.caveat{border-left:0;padding-left:0}
.sos911{background:transparent;border:0;border-top:1px solid #ffffff35;border-radius:0;padding:var(--detail-tight) 0 0;margin-top:var(--detail-gap)}
.sos911 .lead{text-transform:none;letter-spacing:0;font-weight:400;font-size:13px;margin-bottom:var(--detail-tight)}
.sos911 .dial{background:transparent;border:1px solid #ffffff80;border-radius:999px;min-height:44px;font-size:16px}
.sheet .trust{font-size:13px;line-height:1.6}
.sheet .actions{gap:8px}
.sheet .btn{border-radius:6px;min-height:44px}
.sheet-expand{align-self:flex-start;margin:0 24px;padding:0;border:0;background:transparent;color:var(--ocean);font:inherit;font-size:12px;font-weight:600;min-height:44px;cursor:pointer}
.sheet .eyebrow{letter-spacing:.07em}
.legend .oth{display:none}
.legend .row .txt{display:block}
.legend .cur{font-size:14px;line-height:1.4}
.selection-open .dock{visibility:hidden;pointer-events:none}
@media(min-width:820px){
 .dock{top:var(--header);bottom:0;left:0;width:var(--panel);border-right:1px solid var(--line);backdrop-filter:none}
 #list-toggle{display:none}
 .list-heading{padding-top:12px;padding-bottom:8px}
 .sheet,.sheet[data-stop]{top:var(--header);bottom:0;left:0;right:auto;width:var(--panel);height:auto;border-radius:0;border-right:1px solid var(--line);box-shadow:none;transform:translateX(-102%)}
 .sheet.open{transform:translateX(0)}
 .sheet-body{padding-top:22px}
 .sheet-expand{display:none}
 .leaflet-bottom.leaflet-left{left:var(--panel)}
 .fab{bottom:28px;right:24px}.compass{bottom:80px;right:24px}
}
@media(max-width:819px){
 :root{--header:72px}
 .topbar{padding:8px 12px;gap:8px}
 .brand{font-size:14px;gap:7px;line-height:1.15;max-width:none;white-space:normal}
 .brand img{width:44px;height:44px}
 .brand-text{max-width:90px}
 .brand small,.region-label{display:none}
 .sos{padding:0 8px;min-width:44px;justify-content:center}.sos .word{display:none}
 .lang button{padding:0;min-width:44px}
 .dock{bottom:0;height:46dvh;min-height:260px;max-height:calc(100dvh - var(--header) - 80px);border-radius:18px 18px 0 0;padding-bottom:var(--safe-pad);box-shadow:0 -4px 24px #0002}
 .railhead{padding:18px 20px 4px}
 .coast-kicker{font-size:12px;margin-bottom:6px}
 .railhead h1{font-size:25px;margin:0 0 4px}
 .railhead .what{display:none}
 .review-note{margin:8px 0 0;font-size:12px;line-height:1.35}
 .list-heading{padding:0 20px;min-height:44px}
 .strip{padding:0 12px}
 .card{padding:12px 28px 12px 8px}
 .card .pill{font-size:13px;margin-top:4px}
 .card .nm{font-size:15px}
 .dockrow{padding:4px 12px;min-height:52px}
 .forecast{display:none}
 .list-expanded .dock{height:calc(100dvh - var(--header) - 48px);max-height:none}
 .list-expanded .forecast{display:block}
 .sheet,.sheet[data-stop=peek]{height:56dvh;max-height:calc(100dvh - var(--header));border-radius:18px 18px 0 0}
 .sheet[data-stop=half]{height:72dvh}
 .sheet[data-stop=full]{height:calc(100dvh - var(--header))}
 .sheet-body{padding:4px 20px 24px}
 .sheet h2{font-size:27px}
 .sheet .sub{margin-bottom:16px}
 .sheet-expand{margin-left:20px}
 .sheet .close{top:15px}
 .selection-open .fab,.selection-open .compass{visibility:hidden}
 .selection-open .leaflet-bottom.leaflet-left{display:none}
}
@media(max-height:500px) and (max-width:819px){
 .dock{min-height:0;height:48dvh;max-height:calc(100dvh - var(--header))}
 .railhead{display:none}.dockrow{min-height:44px;padding:0 12px}
 .list-expanded .dock{height:calc(100dvh - var(--header))}
}
@media(prefers-reduced-motion:reduce){.sheet,.compass #needle{transition:none}*{scroll-behavior:auto!important}}

/* Symbol system revision: pictograms identify the meaning; strokes stay on the map. */
.railhead{padding:20px 24px 14px}
.railhead h1{font-size:22px;letter-spacing:-.03em;margin:0 0 7px}
.railhead .what{font-size:13px}
.list-heading{padding-top:0}
.symbol{display:inline-grid;place-items:center;flex:none;width:32px;height:32px;border-radius:50%;background:#edf1f2;color:#47616c}
.symbol svg{width:23px;height:23px;display:block}
.symbol.no-swim{background:#bf2935;color:white}
.symbol.high-risk{background:#a8313b;color:white}
.symbol.conditional{background:#fff0c8;color:#845200;border:1px solid #c69734}
.symbol.lower-risk{background:#e2f1e6;color:#237349;border:1px solid #9fbfac}
.symbol.rescue_station{background:#f7a727;color:#172f3a}
.symbol.proposed_rescue_station{background:#fff8e9;color:#875700;border:1.5px dashed #b5802f}
.symbol.proposed_cg_station{background:#fff;color:#52646b;border:1.5px dashed #71838b}
.symbol.rip_current,.symbol.strong_current_area{background:#fff0ef;color:#bb2333}
.card{display:flex;align-items:center;gap:10px;padding:11px 24px 11px 8px;min-height:63px}
.card .beach-symbol{width:42px;height:42px;border-radius:50%}
.card .beach-symbol svg{width:28px;height:28px}
.beach-copy{display:block;min-width:0}
.beach-status{display:block;font-size:12px;font-weight:600;line-height:1.3;margin-top:3px;color:var(--ink)}
.card .nm{font-size:14px}
.card:after{right:8px;top:50%}
.card.void .beach-symbol{height:42px;width:42px;background:transparent}
.statuscard>.tile{display:grid;background:transparent}
.dockrow #legend-open{display:none}
.map-key{position:absolute;z-index:1000;top:calc(var(--header) + 16px);right:16px;width:auto;background:var(--paper);padding:0;border:1px solid var(--line);border-radius:12px;box-shadow:0 2px 12px #102d3b18}
.map-key .key-toggle{display:flex;align-items:center;justify-content:space-between;gap:20px;width:100%;min-height:42px;padding:10px 15px;background:transparent;border:0;border-radius:12px;color:var(--ink);font-family:inherit;font-size:12px;font-weight:700;line-height:1.3;letter-spacing:.05em;text-transform:uppercase;cursor:pointer}
.map-key .key-toggle:hover{background:#f1f6f6}
.map-key .key-toggle:focus-visible{outline:2px solid var(--ocean);outline-offset:-3px}
.key-toggle-icon{width:8px;height:8px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);transition:transform .18s}
.map-key.is-open .key-toggle-icon{transform:rotate(225deg)}
.map-key.is-open .key-toggle{border-bottom:1px solid var(--line);border-radius:12px 12px 0 0}
.map-key .key-content{padding:15px 17px 14px}
.source-note{font-size:11px;line-height:1.45;color:var(--muted);margin:11px 0 0;padding-top:10px;border-top:1px solid var(--line)}
.source-layer-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 16px}
.source-layer-grid label{display:flex;align-items:center;gap:7px;min-width:0;font-size:12px;line-height:1.3;cursor:pointer}
.source-layer-grid input{accent-color:var(--ocean);flex:none;width:16px;height:16px;margin:0}
.source-layer-grid .symbol{width:25px;height:25px}
.source-layer-grid .symbol svg{width:18px;height:18px}
.key-special{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:12px 0 0;padding-top:10px;border-top:1px solid var(--line);font-size:11px;color:var(--muted)}
.key-special>div{display:flex;align-items:center;gap:7px;min-width:0}
.key-special .symbol{width:21px;height:21px;flex:none}
.key-special .symbol svg{width:16px;height:16px}
.projected-marker{background:transparent;border:0}
.projected-marker .symbol{width:30px;height:30px;border-radius:50%;box-shadow:0 1px 5px #102d3b70;border:1px solid white}
.projected-marker .symbol svg{width:21px;height:21px}
.projected-number{position:absolute;top:-8px;right:-9px;min-width:18px;height:18px;padding:1px 3px;border-radius:9px;background:#132f3c;color:white;text-align:center;font:700 10px/16px Arial,sans-serif;box-shadow:0 0 0 1px white}
.projected-place .symbol{width:20px;height:20px;margin:5px;background:#f6f0d6;color:#284f54;opacity:.9}
.projected-place .symbol svg{width:14px;height:14px}
body.map-overview .projected-marker:not(.projected-place) .symbol{width:22px;height:22px;margin:4px}
body.map-overview .projected-marker:not(.projected-place) .symbol svg{width:16px;height:16px}
body.map-overview .projected-number{display:none}
.key-section-label{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);margin:0 0 10px}
.key-short{display:none}
.key-divider{border-top:1px solid var(--line);padding-top:13px;margin-top:14px}
.key-grid{display:grid;grid-template-columns:1fr;gap:11px}
.key-grid>div{display:flex;align-items:center;gap:9px;font-size:12px;line-height:1.3}
.key-grid .symbol{width:29px;height:29px;border-radius:50%}
.key-grid .symbol svg{width:21px;height:21px}
.coast-key{border-top:1px solid var(--line);padding-top:10px;margin-top:12px;display:flex;gap:9px;align-items:center;font-size:12px;line-height:1.35;color:var(--muted)}
.coast-samples{display:flex;gap:3px;flex:none}
.coast-samples i{display:block;width:9px;height:20px;border-radius:3px;background:#c62828}
.coast-samples i:nth-child(2){background:#f5b942}.coast-samples i:nth-child(3){background:#1f9d55}
.station-marker{position:relative;display:grid;place-items:center;width:40px;height:40px;background:var(--paper);border:2px solid white;border-radius:50%;box-shadow:0 1px 6px #0006}
.station-marker .symbol{width:36px;height:36px}
.station-marker .number{position:absolute;top:-7px;right:-9px;min-width:22px;padding:2px 4px;border-radius:5px;background:var(--ink);color:white;font-size:11px;line-height:16px;text-align:center;font-weight:600}
.station-marker.planned{border:1px dashed #9b742c}
.leaflet-control-scale{padding:5px 8px 2px!important;background:#fffefaee;border-radius:4px;margin-left:14px!important;margin-bottom:16px!important;box-shadow:0 1px 4px #0003}
.leaflet-control-scale-line{position:relative;box-sizing:border-box;height:26px;padding:0 0 10px!important;background:transparent!important;border:0!important;color:#132f3c!important;text-shadow:none!important;font-size:12px!important;text-align:right;min-width:40px}
.leaflet-control-scale-line:after{content:'';position:absolute;bottom:0;left:0;right:0;height:7px;border:1px solid #132f3c;background:linear-gradient(90deg,#132f3c 0 25%,#fff 25% 50%,#132f3c 50% 75%,#fff 75%)}
.selection-open .leaflet-bottom.leaflet-left{display:block}
@media(min-width:820px){
 .sheet{z-index:1200}
 .sheet-body{flex:1;min-height:0;overflow-y:hidden;scrollbar-gutter:auto;padding-top:20px;padding-bottom:20px}
 .zone-detail{height:100%}
 .zone-detail .zone-lower{order:2;margin-top:var(--detail-gap)}
 .zone-detail .sheet-weather{order:3}
 .zone-detail>.footlink{order:4;margin-top:auto;text-align:center}
 .zone-detail.compact-weather .sheet-weather{display:flex;align-items:center;flex-wrap:wrap;gap:2px 10px;padding:8px 10px;margin:10px 0}
 .zone-detail.compact-weather .weather-head{display:block;flex:none}
 .zone-detail.compact-weather .weather-time{display:none}
 .zone-detail.compact-weather .weather-metrics{display:flex;gap:9px;margin:0}
 .zone-detail.compact-weather .weather-metrics>div{display:block;white-space:nowrap}
 .zone-detail.compact-weather .weather-metrics span{display:none}
 .zone-detail.compact-weather .weather-metrics strong{font-size:12px}
 .zone-detail.compact-weather .weather-foot{flex-basis:100%;margin:0;font-size:10px}
 .zone-detail.weather-hidden .sheet-weather{display:none}
 .sheet .sub{margin:4px 0 var(--detail-gap)}
 .sheet .statuscard{margin-bottom:var(--detail-gap)}
 .sheet .caveat{margin-bottom:var(--detail-gap);font-size:14px;line-height:1.4}
 .sheet .escape{margin-bottom:var(--detail-gap)}
 .sheet .trust{margin-bottom:var(--detail-gap);line-height:1.45}
 .sheet .actions{margin-bottom:var(--detail-tight)}
 .sheet .btn{min-height:40px}
 .sheet .footlink{margin-top:4px}
 .fab{bottom:24px;right:24px}
 .compass{bottom:24px;right:76px}
 .map-key{display:block;max-height:none;overflow:visible}
 .map-key.is-open{width:min(570px,calc(100vw - var(--panel) - 32px))}
 .key-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 12px}
 .key-status{grid-template-columns:repeat(2,minmax(0,1fr))}
 .source-layer-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
 .coast-key{margin-top:10px;padding-top:10px}
}
@media(min-width:820px) and (min-height:800px){
 .forecast{display:flex;flex-direction:column;justify-content:center;min-height:220px;padding-bottom:10px}
}
@media(min-width:820px) and (max-height:760px){
 .sheet-body{padding-top:16px;padding-bottom:16px}
 .sheet .sub{margin-bottom:6px}
 .sheet .statuscard{padding:10px;margin-bottom:4px}
 .sheet .statuscard .why{margin-top:8px}
 .sheet .statuscard .sos911{display:flex;align-items:center;gap:10px;margin-top:8px}
 .sheet .statuscard .sos911 .lead{flex:1;margin:0;letter-spacing:0;line-height:1.25}
 .sheet .statuscard .sos911 .dial{flex:none;width:116px}
 .sheet .caveat{margin-bottom:4px;line-height:1.35}
 .sheet .escape{margin-bottom:4px}
 .sheet .trust{margin-bottom:4px;line-height:1.35}
 .sheet .actions{margin-bottom:4px}
 .sheet .footlink{margin-top:0}
 .zone-detail .sheet-weather{display:none}
}
@media(min-width:820px) and (max-width:1100px){.key-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:819px){
 .railhead{padding:15px 20px 3px}.railhead h1{font-size:20px;margin:0 0 5px}.railhead .what{display:block;font-size:12px}
 .card{padding:11px 22px 11px 6px;gap:11px}.card .beach-symbol{width:42px;height:42px}.card .beach-symbol svg{width:28px;height:28px}
 .beach-status{font-size:12px}.patrol{font-size:12px;margin-top:5px}
 .map-key{top:calc(var(--header) + 8px);left:auto;right:10px;width:auto;border-radius:9px}
 .map-key.is-open{left:10px;right:10px;width:auto}
 .map-key .key-content{padding:11px 12px}
 .key-short{display:inline}.key-long{display:none}
 .key-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}
 .key-status{grid-template-columns:repeat(2,minmax(0,1fr))}
 .key-grid>div{gap:5px;font-size:11px;align-items:center}
 .key-grid .symbol{width:24px;height:24px}.key-grid .symbol svg{width:19px;height:19px}
 .key-divider{margin-top:7px;padding-top:7px}
 .coast-key{margin-top:7px;padding-top:7px;font-size:12px}.coast-samples i{height:12px;width:6px}
.selection-open .map-key{display:none}
 .selection-open .leaflet-bottom.leaflet-left{bottom:calc(56dvh + 4px)}
 .leaflet-control-scale{margin-bottom:4px!important}
}

/* Shared eight-point rhythm: the map remains the canvas, controls are quiet. */
:root{--paper:#fff;--ink:#18313e;--muted:#526b77;--ocean:#125b73;--line:#d9e4e8;--sand:#f5f8f8}
.topbar{border-bottom:1px solid var(--line)}
.dock{border-right:1px solid var(--line)}
.railhead{padding:20px 20px 12px}
.list-heading{padding-left:20px;padding-right:20px}
.strip{padding-left:12px;padding-right:12px}
.card{padding-left:8px;padding-right:28px}
.card{min-height:54px;padding-top:7px;padding-bottom:7px}
.card .beach-symbol,.card.void .beach-symbol{width:36px;height:36px}
.card .beach-symbol svg{width:24px;height:24px}
.card .nm{font-size:13px}
.beach-status{font-size:11px;margin-top:2px}
.card.void .nm{font-size:13px}
.card.void .vd{font-size:11px;margin-top:2px}
.card:hover,.card[aria-current=true]{background:#edf5f6}
.card:focus-visible{outline:2px solid var(--ocean);outline-offset:-2px}
.symbol{background:#edf4f6;color:#245e70}
.symbol.no-swim{background:#ad2637;color:#fff}
.symbol.high-risk{background:#ad3948;color:#fff}
.symbol.conditional{background:#fff1d4;color:#76500a;border-color:#c8a55e}
.symbol.lower-risk{background:#e7f3ed;color:#215f49;border-color:#b2d1c0}
.symbol.rescue_station{background:#efad36;color:#26343b}
.symbol.proposed_rescue_station{background:#fff9ed;color:#865f1a}
.symbol.rip_current,.symbol.strong_current_area{background:#fff0f0;color:#a8283d}
.statuscard{background:#edf4f6;color:var(--ink);border:1px solid #d9e4e8;box-shadow:none}
.statuscard .eyebrow{color:var(--muted);margin:0}
.statuscard .instr{color:var(--ink);font-weight:750;letter-spacing:-.02em;text-transform:none}
.statuscard .hours{color:var(--ink)}
.statuscard .why{color:var(--ink)}
.statuscard>.tile .symbol{border:0;box-shadow:none}
.sos911{border-top:1px solid #cbdce1;color:var(--ink)}
.sos911 .lead{color:var(--ink)}
.sos911 .dial{color:#fff;background:#a62638;border:1px solid #a62638;text-decoration:none;font-weight:700}
.sos911 .dial:hover{background:#84192a}
.sheet .eyebrow{font-size:11px;font-weight:750;color:var(--muted)}
.zone-lower{padding-top:4px}
.sheet .escape{font-weight:650;color:var(--ink);margin-top:5px}
.sheet .trust{color:var(--muted)}
.sheet .actions{margin-top:12px}
.forecast{border-top:1px solid var(--line);padding:14px 16px 0}
.forecast-title{font-size:11px;letter-spacing:.08em;margin-bottom:8px}
.forecast .sea{border:1px solid var(--line);background:#f2f7f9;border-radius:10px;padding:12px}
.forecast .sea .cols{gap:4px;margin:0 0 10px}
.forecast .sea .col{gap:3px}
.forecast .sea .tile{width:30px;height:30px;background:#e3eef2;color:var(--ocean)}
.forecast .sea .tile svg{width:20px;height:20px}
.forecast .sea .val{font-size:15px;font-weight:700;color:var(--ink)}
.forecast .sea .lbl{font-size:10px;letter-spacing:.04em}
.forecast .sea .foot{padding-top:8px;border-top:1px solid var(--line)}
@media(min-width:820px) and (max-height:780px){
 .railhead{padding-top:10px;padding-bottom:4px}
 .list-heading{padding-bottom:4px}
 .card{min-height:44px;padding-top:3px;padding-bottom:3px}
 .card .beach-symbol,.card.void .beach-symbol{width:32px;height:32px}
 .card .beach-symbol svg{width:22px;height:22px}
 .forecast{padding-top:5px}
 .forecast-title{margin-bottom:5px}
 .forecast .sea{padding:6px;margin-bottom:3px}
 .forecast .sea .cols{margin-bottom:5px}
 .forecast .sea .tile{width:25px;height:25px}
 .forecast .sea .tile svg{width:17px;height:17px}
 .forecast .sea .foot{font-size:10px;padding-top:5px;line-height:1.28}
}
@media(min-width:820px) and (min-height:800px){.forecast{min-height:0;justify-content:flex-start}}
.map-key{box-shadow:0 3px 16px #08273426}
.map-key.is-open{width:min(350px,calc(100vw - var(--panel) - 32px))}
.map-key .key-content{padding:14px 16px 15px}
.source-layer-grid{grid-template-columns:1fr 1fr;gap:10px 12px}
.source-layer-grid label{font-size:12px;min-height:32px;gap:8px}
.source-layer-grid input{width:17px;height:17px}
.source-layer-grid .symbol{width:26px;height:26px}
.key-hint{font-size:11px;line-height:1.4;color:var(--muted);border-top:1px solid var(--line);margin:14px 0 0;padding-top:10px}
.key-data{font-size:11px;line-height:1.45;color:var(--muted);margin-top:9px}
.key-data summary{cursor:pointer;color:var(--ocean);font-weight:650}
.key-data p{margin:7px 0 0}
.key-data a{color:var(--ocean)}
.cg-current-pulse{animation:cg-current-breathe 3.4s ease-in-out infinite;pointer-events:none}
.cg-current-phase-1{animation-delay:-.65s}
.cg-current-phase-2{animation-delay:-1.3s}
.cg-current-phase-3{animation-delay:-1.95s}
@keyframes cg-current-breathe{0%,100%{opacity:.18}36%,68%{opacity:1}}
@media(prefers-reduced-motion:reduce){.cg-current-pulse{animation:none}}
@media(max-width:819px){
 /* Keep the coast legible above the dock while offering its forecast at first glance. */
 .dock{height:54dvh}
 .railhead{padding:12px 20px 2px}
 .railhead h1{font-size:18px;line-height:1.2;margin-bottom:3px}
 .forecast{display:block;order:0;flex:none;max-height:none;overflow:visible;border:0;padding:5px 12px 6px}
 .forecast-title{margin:0 0 4px;font-size:11px}
 .forecast .sea{margin:0;padding:7px 9px}
 .forecast .sea .cols{margin:0 0 5px}
 .forecast .sea .tile{width:23px;height:23px}
 .forecast .sea .tile svg{width:16px;height:16px}
 .forecast .sea .val{font-size:14px}
 .forecast .sea .lbl{font-size:10px}
 .forecast .sea .foot{font-size:10px;line-height:1.25;padding-top:5px}
 .list-expanded .forecast{padding-top:8px}
 .list-heading{min-height:40px}
 .card{min-height:54px}
 /* A layer tray from the bottom leaves more imagery visible than a top overlay. */
 .map-key.is-open{top:auto;bottom:calc(var(--safe-pad) + 8px);left:10px;right:10px;width:auto;max-height:calc(100dvh - var(--header) - 16px);overflow-y:auto}
 .map-key .key-content{padding:12px}
 .source-layer-grid{gap:7px 8px}
 /* Give the first safety instruction more of the initial sheet viewport. */
 .sheet-expand{position:absolute;top:10px;left:0;z-index:2}
 .sheet-body{padding-top:26px}
 .sheet .statuscard{padding:13px}
 .sheet .statuscard .why{margin-top:8px}
 .sheet .statuscard .sos911{display:flex;align-items:center;gap:10px;margin-top:9px}
 .sheet .statuscard .sos911 .lead{flex:1;min-width:0;margin:0;line-height:1.3}
 .sheet .statuscard .sos911 .dial{flex:none;width:116px}
}
@media(max-width:380px) and (max-height:650px){
 /* Small phones still need visible beach choices and an uncut emergency action. */
 .railhead{padding:8px 16px 0}
 .railhead h1{font-size:16px;margin:0}
 .railhead .what{display:none}
 .dock{height:58dvh}
 .forecast{padding-top:0}
 .forecast .sea .foot{display:none}
 .list-expanded .forecast .sea .foot{display:block}
 .sheet[data-stop=peek]{height:calc(100dvh - var(--header))}
 .sheet-expand{display:none}
}

/* Phone map composition: map-first rest state, a map-only tab, and a full list. */
.dock-handle{display:none}
.cg-gps-marker{background:transparent;border:0}
@media(max-width:819px){
 .topbar{height:var(--header);background:transparent;border:0;box-shadow:none;backdrop-filter:none;padding:8px 12px;align-items:flex-start}
 .brand{min-height:44px;padding:2px 9px 2px 3px;border:1px solid #ffffffb0;border-radius:999px;background:#ffffffed;box-shadow:0 2px 12px #071b2850}
 .brand img{width:38px;height:38px}
 .brand-text{font-size:13px;max-width:90px}
 .sos,.lang{background:#ffffffed;box-shadow:0 2px 12px #071b2850;border:1px solid #d9e4e8}
 .sos{color:#a62638}
 .lang button[aria-pressed=true]{background:var(--ink);color:#fff}
 .dock{height:40dvh;min-height:0;max-height:none;padding-top:0;border-radius:18px 18px 0 0;transition:height .32s cubic-bezier(.22,1,.36,1);will-change:height}
 .dock.dragging{transition:none}
 .dock>:not(.dock-handle){transition:opacity .18s ease,visibility 0s linear 0s}
 .dock-handle{display:flex;flex:none;align-items:center;justify-content:center;align-self:center;width:88px;height:28px;min-height:28px;padding:0;border:0;background:transparent;cursor:grab;touch-action:none}
 .dock-grab{display:block;width:44px;height:5px;border-radius:999px;background:#b7c7cf}
 .dock-min .dock{height:54px}
 .dock-min .dock>:not(.dock-handle){opacity:0;visibility:hidden;pointer-events:none;transition:opacity .14s ease,visibility 0s linear .14s}
 .dock-full .dock,.list-expanded .dock{height:calc(100dvh - var(--header));max-height:none}
 .railhead{padding:0 16px 2px}
 .railhead .what{display:none}
 .forecast{padding:2px 12px 4px}
 .forecast .sea .foot{display:none}
 .dock-full .forecast .sea .foot{display:block}
 .list-heading{min-height:36px;padding:0 16px}
 .dockrow{min-height:44px;padding:0 12px}
 .fab,.fab.hidden{display:flex;align-items:center;justify-content:center;width:44px;height:44px;right:72px;bottom:calc(var(--safe-pad) + var(--dock-h) + 12px);padding:0;border-radius:50%;background:#fff}
 .fab svg{width:21px;height:21px;flex:none}
 .compass{right:16px;bottom:calc(var(--safe-pad) + var(--dock-h) + 12px);width:44px;height:44px}
 .map-key{top:calc(var(--header) + 8px);right:12px}
 .map-key.is-open{display:flex;flex-direction:column;top:auto;bottom:0;left:0;right:0;width:auto;height:auto;max-height:45dvh;overflow:hidden;border-radius:18px 18px 0 0;z-index:1100}
 .map-key.is-open:not(.is-closing){animation:layer-tray-in .3s cubic-bezier(.22,1,.36,1) both}
 .map-key.is-closing{animation:layer-tray-out .22s ease-in both;pointer-events:none}
 @keyframes layer-tray-in{from{opacity:.8;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}
 @keyframes layer-tray-out{from{opacity:1;transform:translateY(0)}to{opacity:.8;transform:translateY(100%)}}
 .map-key.is-open .key-toggle{flex:none;min-height:48px;padding:12px 18px}
 .map-key.is-open .key-content{flex:1;min-height:0;overflow-y:auto;padding:12px 18px calc(16px + var(--safe-pad))}
 .legend-mode .dock{visibility:hidden;pointer-events:none}
 .dock-full .map-key,.dock-full .fab,.dock-full .compass,.dock-full .leaflet-bottom.leaflet-left{display:none}
 .sheet,.sheet[data-stop=peek]{height:48dvh}
 .sheet[data-stop=half]{height:72dvh}
 .sheet{transition:transform .32s cubic-bezier(.22,1,.36,1),height .32s cubic-bezier(.22,1,.36,1)}
 .sheet-expand{position:absolute;top:0;left:50%;transform:translateX(-50%);z-index:2;display:flex;align-items:center;justify-content:center;width:88px;height:44px;min-height:44px;margin:0;padding:0;border:0;background:transparent;color:transparent;cursor:grab;touch-action:none}
 .sheet-expand::after{content:"";display:block;width:44px;height:5px;border-radius:999px;background:#b7c7cf}
 .sheet-body{padding-top:44px}
 /* The why stays at every stop: the sheet moves by transform now, and content
    that appears as it rises would re-lay out the sheet mid gesture. */
 .map-key{transition:width .24s ease,box-shadow .24s ease}
 .map-key .key-content{animation:key-reveal .24s cubic-bezier(.22,1,.36,1) both}
 @keyframes key-reveal{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
 .fab,.compass,.sos,.lang,.brand,.key-toggle{transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,transform .18s ease}
 .fab:active,.compass:active,.sos:active,.lang button:active,.key-toggle:active{transform:scale(.96)}
 .card,.sheet button:not(.sheet-expand),.source-layer-grid label{transition:background-color .18s ease,transform .18s ease}
 .card:active,.sheet button:not(.sheet-expand):active{transform:scale(.985)}
 .source-layer-grid label:active{background:#f1f6f6}
}
@media(max-width:380px) and (max-height:650px){
 .dock{height:50dvh}
 .dock-min .dock{height:54px}
 .dock-full .dock,.list-expanded .dock{height:calc(100dvh - var(--header))}
 .sheet[data-stop=peek]{height:calc(100dvh - var(--header))}
 .sheet-expand{display:flex}
}
@media(max-width:819px) and (prefers-reduced-motion:reduce){
 .dock,.dock>:not(.dock-handle),.sheet,.map-key,.map-key .key-content,.fab,.compass,.sos,.lang,.brand,.key-toggle,.card,.sheet button,.source-layer-grid label{animation:none!important;transition:none!important}
}

/* Phone panels, 2026-09-23: laid out once at full height and moved by transform
   from index.html (createPanel). Nothing here may animate height, bottom or
   transform on the dock, the sheet or the controls that ride on them: a CSS
   transition would trail every frame the finger sets. */
html,body{overscroll-behavior:none}
@media(max-width:819px){
 .dock,.dock-min .dock,.dock-full .dock,.list-expanded .dock{top:auto;bottom:0;height:calc(100dvh - var(--header));min-height:0;max-height:none;
  transition:none;will-change:transform;contain:layout paint;
  box-shadow:0 -2px 18px #0827342e,0 120px 0 0 var(--paper)}
 .dock-min .dock>:not(.dock-handle),.dock>:not(.dock-handle){opacity:1;visibility:visible;pointer-events:auto;transition:none}
 .dock{overflow:hidden}
 /* Below its top stop the panel owns every vertical movement on it. */
 .dock.is-partial,.sheet.is-partial{touch-action:none}
 .dock.is-partial .strip{overflow-y:hidden}
 .sheet.is-partial .sheet-body{overflow-y:hidden}
 .strip,.sheet-body{overscroll-behavior:contain}
 .dock-handle,.railhead,.list-heading,.forecast,.sheet-expand{touch-action:none;user-select:none;-webkit-user-select:none}
 .dock-handle{width:120px;height:26px;min-height:26px;cursor:grab}
 .dock-grab,.sheet-expand::after{transition:background-color .15s ease,width .2s cubic-bezier(.22,1,.36,1)}
 .dock.dragging .dock-grab,.sheet.dragging .sheet-expand::after{background:#7f97a1;width:52px}
 .dock.dragging,.sheet.dragging{cursor:grabbing}
 .railhead{padding:0 20px 4px}
 .railhead h1{font-size:19px;line-height:1.25;letter-spacing:-.02em;margin:0 0 6px}
 .dock-min .railhead{cursor:pointer}
 .sheet,.sheet[data-stop],.sheet[data-stop=peek],.sheet[data-stop=half],.sheet[data-stop=full]{top:auto;bottom:0;height:calc(100dvh - var(--header));max-height:none;
  transition:none;will-change:transform;border-radius:18px 18px 0 0;
  box-shadow:0 -4px 24px #08273433,0 120px 0 0 var(--paper)}
 .sheet:not(.open){transform:translate3d(0,100%,0)}
 .sheet-expand{width:120px}
 /* Controls clear what shows of the panel; --dock-h already includes the
    home-indicator inset because it is measured from the screen's bottom edge. */
 .fab,.fab.hidden,.compass{bottom:calc(var(--dock-h) + 12px);transition:background-color .18s ease,box-shadow .18s ease,scale .12s ease}
 .leaflet-bottom.leaflet-left,.selection-open .leaflet-bottom.leaflet-left{bottom:calc(var(--dock-h) + 6px)}
 .fab,.compass,.leaflet-bottom.leaflet-left{will-change:transform}
 .fab:active,.compass:active{transform:none;scale:.94}
 .sos:active,.lang button:active,.key-toggle:active{transform:none;scale:.96}
 .card:active{transform:none;background:#e6eff1}
}
@media(max-width:819px) and (prefers-reduced-motion:reduce){
 .dock-grab,.sheet-expand::after{transition:none}
}

/* Quieter chrome, 2026-09-23. Labels in sentence case at reading weight; the
   tracked uppercase stays only on the eyebrows, where it names a block. */
.map-key .key-toggle{font-size:13px;font-weight:600;letter-spacing:0;text-transform:none;min-height:44px;padding:10px 14px;gap:14px}
.eyebrow,.forecast-title,.rail-eyebrow,.sheet .eyebrow{letter-spacing:.06em}
.leaflet-control-scale{padding:4px 7px 2px!important}
.leaflet-control-scale-line{height:22px;padding:0 0 8px!important;font-size:11px!important}
.leaflet-control-scale-line:after{height:6px}
@media(max-width:819px){
 .map-key{border-radius:999px}
 .map-key.is-open{border-radius:18px 18px 0 0}
 .map-key .key-toggle{border-radius:999px;min-height:40px;padding:8px 14px}
 .map-key.is-open .key-toggle{border-radius:18px 18px 0 0}
}
/* A phone held sideways crosses 820 px and gets the desktop rail, with 390 px
   of height to share. The beaches are what the rail is for, so the header
   shrinks and the forecast steps out; the beach sheet still carries weather. */
@media(min-width:820px) and (max-height:500px){
 :root{--header:56px}
 .topbar{padding:4px 16px}
 .brand img{width:40px;height:40px}
 .brand small,.region-label{display:none}
 .railhead{padding:10px 20px 2px}.railhead .what{display:none}
 .forecast{display:none}
 .dockrow{min-height:40px;padding:0 12px}
}
.panel-dragging,.panel-dragging *{user-select:none;-webkit-user-select:none}
html,body{overflow:clip}
/* Poppins runs wider than Inter; the negative tracking tuned for Inter crowds it. */
.statuscard .instr,.pill,.sheet .escape{letter-spacing:0}
.sheet h2,.railhead h1{letter-spacing:-.02em}

/* 2026-09-23, Daniel's phone review. */
@media(max-width:819px){
 /* The forecast heading sits on the same inset and rhythm as BEACHES. */
 .forecast{padding:0 16px 6px}
 .forecast-title,.list-heading .rail-eyebrow{display:flex;align-items:center;min-height:36px;margin:0;font-size:11px;font-weight:700;letter-spacing:.06em}
 .list-heading{padding:0 16px}
 /* More air inside the card, smaller readings, one footer line. */
 .forecast .sea{padding:12px 16px 10px}
 .forecast .sea .cols{gap:8px;margin:0 0 10px}
 .forecast .sea .tile{width:20px;height:20px;background:transparent}
 .forecast .sea .tile svg{width:16px;height:16px}
 .forecast .sea .val{font-size:13px}
 .forecast .sea .lbl{font-size:9.5px;letter-spacing:.05em}
 .forecast .sea .foot,.dock-full .forecast .sea .foot{display:block;margin:0;padding-top:8px;font-size:10.5px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
 /* The brand pill hugs its wordmark: the text box shrinks to its longest word. */
 .brand{padding:2px 14px 2px 3px;gap:8px}
 .brand-text{width:min-content;max-width:none}
}
.forecast .sea .foot a{color:inherit}
.forecast .sea .foot .stamp{white-space:nowrap}
/* The lifebuoy carries its own colour; its disc is plain white. */
.symbol.rescue_station,.symbol.proposed_rescue_station{background:#fff;border:0}
.symbol.rescue_station svg,.symbol.proposed_rescue_station svg{width:86%;height:86%}
/* Beach names open their beach; the hit area is larger than the ink. */
.leaflet-marker-icon.lbl.zone.tap{pointer-events:auto;cursor:pointer}
.leaflet-marker-icon.lbl.zone.tap::after{content:"";position:absolute;inset:-12px -8px}
.leaflet-marker-icon.lbl.zone.tap:focus-visible{outline:2px solid #fff;outline-offset:3px}

/* Rip currents as moving water (2026-09-23). The streaks advance one dash
   period (14 px) every 0.6 s, about 23 px/s: slow and steady like water, well
   under the 50-100 px/s of a UI "marching ants" selection. Linear on purpose:
   a current does not ease in and out. Negative offset = forward along the
   drawn line, which runs from the sand out to sea. */
@keyframes cg-rip-flow{from{stroke-dashoffset:0}to{stroke-dashoffset:-14}}
.cg-rip-flow{animation:cg-rip-flow .6s linear infinite}
.cg-rip-channel{mix-blend-mode:normal}
/* Nothing moves while the map itself moves, below the zoom where rips show in
   detail, or when the reader asked for less motion; the dashes and the head
   still say which way. */
.leaflet-dragging .cg-rip-flow,.leaflet-zoom-anim .cg-rip-flow,.map-overview .cg-rip-flow{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){.cg-rip-flow{animation:none}}

/* 2026-09-23 round three. The closed legend is a twin of the ES/EN pill:
   same width, height, corner, edge and shadow, label centred, no chevron. */
@media(max-width:819px){
 .map-key:not(.is-open){width:var(--lang-w,auto);border-radius:6px;border:1px solid #d9e4e8;box-shadow:0 2px 12px #071b2850;background:#ffffffed}
 .map-key:not(.is-open) .key-toggle{justify-content:center;min-height:44px;padding:0 10px;border-radius:6px;font-size:13px;font-weight:600}
}
.key-toggle-icon{display:none}
.key-section+.key-section{margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
.key-section .key-section-label{margin:0 0 8px}
.symbol.place-badge,.projected-place .symbol{background:#f6f3ea;color:#284f54}
/* Beach sheets no longer carry a subtitle line (Daniel, 2026-09-23); the
   name sits directly over the instruction. */
.sheet h2+.statuscard,.sheet h2+.why{margin-top:16px}
.key-close{display:grid;place-items:center;width:32px;height:32px;margin:-6px -6px -6px 0;border-radius:50%;border:1px solid var(--line);font-size:20px;font-weight:400;line-height:1;color:var(--ink)}

/* Saved copy sheet (2026-09-23): short, platform-specific, swipe to close. */
.sheet.no-close .close{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;padding:0}
.saved-status{display:inline-flex;align-items:center;gap:8px;margin:10px 0 14px;padding:6px 12px;border-radius:999px;background:#eef3f5;color:var(--muted);font-size:13px;font-weight:600}
.saved-status.is-ok{background:#e7f1f4;color:var(--ink)}
.saved-status.is-ok::before{content:"";width:8px;height:8px;border-radius:50%;background:#2f8f6b}
.saved-steps{margin:6px 0 10px;padding:0;list-style:none;counter-reset:s}
.saved-steps li{counter-increment:s;position:relative;padding:8px 0 8px 36px;font-size:15px;line-height:1.4;border-top:1px solid var(--line)}
.saved-steps li:first-child{border-top:0}
.saved-steps li::before{content:counter(s);position:absolute;left:0;top:7px;width:24px;height:24px;border-radius:50%;background:var(--ink);color:#fff;font-size:12px;font-weight:700;display:grid;place-items:center}
.saved-note,.saved-done{font-size:13px;line-height:1.45;color:var(--muted);margin:4px 0 0}
/* Distance to each beach, right-aligned before the chevron. */
.card .card-dist{margin-left:auto;padding-left:8px;flex:none;font-size:12px;font-weight:600;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.dist-origin{margin:-4px 16px 4px;font-size:11px;line-height:1.35;color:var(--muted)}
@media(min-width:820px){.dist-origin{margin:-2px 20px 6px}}
/* Legend tray: a grabber instead of a close mark; a drag owns the transform. */
.key-close{display:none}
.key-grab{display:none}
@media(max-width:819px){
 .map-key.is-open .key-grab{display:block;width:44px;height:5px;margin:8px auto -4px;border-radius:999px;background:#b7c7cf}
 .map-key.is-open{touch-action:none}
 .map-key.is-open .key-content{touch-action:pan-y;overscroll-behavior:contain}
 .map-key.dragging,.map-key.dragging .key-content{animation:none!important}
 .map-key.dragging .key-grab{background:#7f97a1;width:52px}
}
@media(max-width:819px){.map-key.is-open.opened:not(.is-closing){animation:none}}
.btn.install{background:var(--ink);border-color:var(--ink);color:#fff;font-size:15px}
/* No close button on any phone sheet (Daniel, 2026-09-23): swiping down closes
   every panel. The button stays in the page, visually hidden, for screen
   readers and keyboards; Escape also closes. Desktop keeps it: no swipe there. */
@media(max-width:819px){
 .sheet .close{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;padding:0}
 .sheet h2{padding-right:0}
}
/* Confirmed stations at the whole-coast view: small, no number, still tappable. */
body.map-overview .station-marker{transform:scale(.62)}
body.map-overview .station-marker .number{display:none}
body.map-overview .projected-marker .symbol.rescue_station{box-shadow:0 1px 4px #102d3b90}
