/* assets/css/fonts.css */
/* fonts.css — Inter (text) and Space Grotesk (headings and big numbers),
   self-hosted (variable weight, latin + latin-ext so Hawaiian kahakō vowels render). Replaces the Google Fonts import so the
   installed app has no third-party dependency and works offline.
   Both SIL OFL 1.1 — see /assets/fonts/{inter,space-grotesk}/LICENSE. */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-display: swap;
    font-weight: 100 900;
    src: url("/assets/fonts/inter/inter-latin-ext-wght-normal.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, 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: "Inter";
    font-style: normal;
    font-display: swap;
    font-weight: 100 900;
    src: url("/assets/fonts/inter/inter-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+2074, 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-display: swap;
    font-weight: 300 700;
    src: url("/assets/fonts/space-grotesk/space-grotesk-latin-ext-wght-normal.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, 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-display: swap;
    font-weight: 300 700;
    src: url("/assets/fonts/space-grotesk/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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Metric-matched fallbacks: until the web fonts arrive, Arial (or the phone's
   Roboto) is scaled to their width and line height, so the swap barely moves
   any text (layout shift). Values measured from the font files against Arial. */
@font-face {
    font-family: "Inter Fallback";
    src: local("Arial"), local("Liberation Sans"), local("Helvetica"), local("Roboto");
    size-adjust: 105.15%;
    ascent-override: 92.13%;
    descent-override: 22.94%;
    line-gap-override: 0%;
}
@font-face {
    font-family: "Space Grotesk Fallback";
    src: local("Arial"), local("Liberation Sans"), local("Helvetica"), local("Roboto");
    size-adjust: 103.4%;
    ascent-override: 95.17%;
    descent-override: 28.24%;
    line-gap-override: 0%;
}

/* assets/css/nocturne.css */
/* Nocturne (Lagoon palette) — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* Inter is self-hosted in fonts.css (loaded before this file). */

:root {
  --color-bg: #0b1a22;
  --color-surface: #13262f;
  --color-text: #e6f1f2;
  --color-accent: #2fc4b2; /* Lagoon (Nov 2026): the turquoise of a Hawaiian lagoon over reef,
     on deep reef blue-green grounds; 8.2:1 on --color-bg. Replaced the Nocturne violet. */
  --color-accent-2: #7fd6cb; /* a lighter lagoon for secondary marks */
  --color-divider: color-mix(in srgb, #e6f1f2 16%, transparent);

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #f1f8f8;
  --color-neutral-200: #e1ecee;
  --color-neutral-300: #c9d8db;
  --color-neutral-400: #a9bcc0;
  --color-neutral-500: #8aa0a5;
  --color-neutral-600: #6c8288;
  --color-neutral-700: #52666b;
  --color-neutral-800: #3a4a4f;
  --color-neutral-900: #253236;

  --color-accent-100: #effcfa;
  --color-accent-200: #d6f6f1;
  --color-accent-300: #aeece3;
  --color-accent-400: #76dccf;
  --color-accent-500: #3fc9b8;
  --color-accent-600: #28a596;
  --color-accent-700: #1f7f74;
  --color-accent-800: #185a53;
  --color-accent-900: #103a36;

  --color-accent-2-100: #effcfa;
  --color-accent-2-200: #d6f6f1;
  --color-accent-2-300: #aeece3;
  --color-accent-2-400: #8fd5cc;
  --color-accent-2-500: #6cbab0;
  --color-accent-2-600: #549a91;
  --color-accent-2-700: #3f7770;
  --color-accent-2-800: #2d5550;
  --color-accent-2-900: #1c3633;

  /* Deck section-divider ground — review round 3: saturation as presence.
     Dividers take a saturated deep indigo (hue 277, the neutral ramp's own
     family; C 0.094 — written when the accent held C 0.030, before the
     round-7 blurple raised it past the ground's) with a lighter bloom and
     a ghost tint of the same hue, while the slide grounds stay
     desaturated. Deck-scale fills only — not interface colors. */
  --color-section: #262a60;
  --color-section-glow: #353b80;
  --color-section-ghost: #4c5397;

  --font-heading: "Space Grotesk", "Space Grotesk Fallback", "Inter", system-ui, sans-serif;
  --font-heading-weight: 500;
  --font-body: "Inter", "Inter Fallback", system-ui, sans-serif;

  --space-1: 2.8px;
  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --space-6: 16.8px;
  --space-8: 22.4px;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 0 0 1px #3a4a4f;
  --shadow-md: 0 0 0 1px #52666b, 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px #8aa0a5, 0 16px 40px rgba(0,0,0,0.65);
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }

.lighten{mix-blend-mode:lighten;background-color:transparent}

/* ══════════════════════════════════════════════════════════════════════════
   Components — built with the tokens above. Plain CSS
   on plain HTML: no JavaScript, no build step. Each class is documented in
   readme.md and demonstrated in foundations/ and components/.
   ══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-size: 15px; line-height: 1.55; font-weight: 400; }
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.12; letter-spacing: -0.015em; margin: 0 0 var(--space-2);
}
h1 { font-size: 42px; }
h2 { font-size: 32px; }
h3 { font-size: 25px; }
h4 { font-size: 20px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; }
h6 { letter-spacing: 0.08em; text-transform: uppercase; }
p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent); text-underline-offset: 3px; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — rules — */
/* Rules fade to transparent at both ends instead of stopping cleanly — a
   Nocturne signature. The ramp is 48px an end (one deck baseline unit),
   painted from the same divider token. Freestanding rules fade; box
   outlines, in-control separators, and short accent marks stay solid. */
.hr {
  height: 1px; border: 0; margin: var(--space-4) 0;
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent);
}

/* — buttons — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; color: var(--color-text); /* matches the .input's 14px —
     the pair sits side by side in sign-up rows */
  background: transparent; border: 1px solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
}
.btn svg { display: block; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { color: var(--color-accent); border-color: var(--color-accent); }
.btn-primary:active { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }
.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
/* Hover only where a pointer can hover: on touch it sticks after the tap. */
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover:not(:active) { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
  .btn-secondary:hover:not(:active) { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
  .btn-ghost:hover:not(:active) { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
}
.btn-icon { width: 36px; height: 36px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); }

/* — forms — */
.field > label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.input {
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
@media (hover: hover) and (pointer: fine) {
  .input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
}
.input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
textarea.input { min-height: 90px; resize: vertical; }
.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
@media (hover: hover) and (pointer: fine) {
  .radio:hover .dot { border-color: var(--color-accent); }
}
.radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
.radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 13px; cursor: pointer;
}
.seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
.seg-opt:has(input:checked) { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }
@media (hover: hover) and (pointer: fine) {
  .seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
}
.seg-opt:not(:has(input:checked)):active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* — cards — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
.card-kicker { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
.card-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; line-height: 1.2;
}
.card-body { margin: 0; font-size: 13px; opacity: 0.8; flex: 1; }
.card-meta {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — tags — */
.tag {
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 3px 10px;
  border-radius: calc(var(--radius-md) * 0.75);
}
.tag-accent { background: var(--color-accent-800); color: var(--color-accent-100); }
.tag-accent-2 { background: var(--color-accent-2-800); color: var(--color-accent-2-100); }
.tag-neutral { background: var(--color-neutral-800); color: var(--color-neutral-100); }
.tag-outline { border: 1px solid var(--color-accent); color: var(--color-accent); }

/* — navigation — */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: none;
}
.nav-brand {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}
.nav a { color: inherit; text-decoration: none; font-size: 14px; }
.nav a[aria-current='page'] { color: var(--color-accent); }
@media (hover: hover) and (pointer: fine) {
  .nav a:hover { color: var(--color-accent); }
}

/* — tables — */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th {
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  padding: var(--space-2); border-bottom: 1px solid transparent; /* keeps layout; the row paints the fading rule */
}
.table td {
  padding: var(--space-2);
  border-bottom: 1px solid transparent;
}
/* Row rules as row-level strips so the end-fade spans the row, not each cell. */
.table thead tr {
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
.table tbody tr {
  background: linear-gradient(to right,
    transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
    color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
@media (hover: hover) and (pointer: fine) {
  .table tbody tr:hover {
    /* the hover tint layers over the row rule, which keeps painting */
    background:
      linear-gradient(color-mix(in srgb, var(--color-text) 4%, transparent),
                      color-mix(in srgb, var(--color-text) 4%, transparent)) no-repeat 0 0 / 100% 100%,
      linear-gradient(to right,
        transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
        color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
  }
}

/* — dialog — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}
.dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
.dialog-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}
.dialog-body { font-size: 14px; opacity: 0.85; }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }


/* assets/js/vendor/leaflet.css */
/* required styles */

.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
	position: absolute;
	left: 0;
	top: 0;
	}
.leaflet-container {
	overflow: hidden;
	}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
	  -webkit-user-drag: none;
	}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
	background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
	image-rendering: -webkit-optimize-contrast;
	}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
	width: 1600px;
	height: 1600px;
	-webkit-transform-origin: 0 0;
	}
.leaflet-marker-icon,
.leaflet-marker-shadow {
	display: block;
	}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
	max-width: none !important;
	max-height: none !important;
	}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
	max-width: none !important;
	max-height: none !important;
	width: auto;
	padding: 0;
	}

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

.leaflet-container.leaflet-touch-zoom {
	-ms-touch-action: pan-x pan-y;
	touch-action: pan-x pan-y;
	}
.leaflet-container.leaflet-touch-drag {
	-ms-touch-action: pinch-zoom;
	/* Fallback for FF which doesn't support pinch-zoom */
	touch-action: none;
	touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
	-ms-touch-action: none;
	touch-action: none;
}
.leaflet-container {
	-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
	-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
	filter: inherit;
	visibility: hidden;
	}
.leaflet-tile-loaded {
	visibility: inherit;
	}
.leaflet-zoom-box {
	width: 0;
	height: 0;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	z-index: 800;
	}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
	-moz-user-select: none;
	}

.leaflet-pane         { z-index: 400; }

.leaflet-tile-pane    { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane  { z-index: 500; }
.leaflet-marker-pane  { z-index: 600; }
.leaflet-tooltip-pane   { z-index: 650; }
.leaflet-popup-pane   { z-index: 700; }

.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg    { z-index: 200; }

.leaflet-vml-shape {
	width: 1px;
	height: 1px;
	}
.lvml {
	behavior: url(#default#VML);
	display: inline-block;
	position: absolute;
	}


/* control positioning */

.leaflet-control {
	position: relative;
	z-index: 800;
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}
.leaflet-top,
.leaflet-bottom {
	position: absolute;
	z-index: 1000;
	pointer-events: none;
	}
.leaflet-top {
	top: 0;
	}
.leaflet-right {
	right: 0;
	}
.leaflet-bottom {
	bottom: 0;
	}
.leaflet-left {
	left: 0;
	}
.leaflet-control {
	float: left;
	clear: both;
	}
.leaflet-right .leaflet-control {
	float: right;
	}
.leaflet-top .leaflet-control {
	margin-top: 10px;
	}
.leaflet-bottom .leaflet-control {
	margin-bottom: 10px;
	}
.leaflet-left .leaflet-control {
	margin-left: 10px;
	}
.leaflet-right .leaflet-control {
	margin-right: 10px;
	}


/* zoom and fade animations */

.leaflet-fade-anim .leaflet-popup {
	opacity: 0;
	-webkit-transition: opacity 0.2s linear;
	   -moz-transition: opacity 0.2s linear;
	        transition: opacity 0.2s linear;
	}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
	opacity: 1;
	}
.leaflet-zoom-animated {
	-webkit-transform-origin: 0 0;
	    -ms-transform-origin: 0 0;
	        transform-origin: 0 0;
	}
svg.leaflet-zoom-animated {
	will-change: transform;
}

.leaflet-zoom-anim .leaflet-zoom-animated {
	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
	}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
	-webkit-transition: none;
	   -moz-transition: none;
	        transition: none;
	}

.leaflet-zoom-anim .leaflet-zoom-hide {
	visibility: hidden;
	}


/* cursors */

.leaflet-interactive {
	cursor: pointer;
	}
.leaflet-grab {
	cursor: -webkit-grab;
	cursor:    -moz-grab;
	cursor:         grab;
	}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
	cursor: crosshair;
	}
.leaflet-popup-pane,
.leaflet-control {
	cursor: auto;
	}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
	cursor: move;
	cursor: -webkit-grabbing;
	cursor:    -moz-grabbing;
	cursor:         grabbing;
	}

/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
	pointer-events: none;
	}

.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}

/* visual tweaks */

.leaflet-container {
	background: #ddd;
	outline-offset: 1px;
	}
.leaflet-container a {
	color: #0078A8;
	}
.leaflet-zoom-box {
	border: 2px dotted #38f;
	background: rgba(255,255,255,0.5);
	}


/* general typography */
.leaflet-container {
	font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
	font-size: 12px;
	font-size: 0.75rem;
	line-height: 1.5;
	}


/* general toolbar styles */

.leaflet-bar {
	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
	border-radius: 4px;
	}
.leaflet-bar a {
	background-color: #fff;
	border-bottom: 1px solid #ccc;
	width: 26px;
	height: 26px;
	line-height: 26px;
	display: block;
	text-align: center;
	text-decoration: none;
	color: black;
	}
.leaflet-bar a,
.leaflet-control-layers-toggle {
	background-position: 50% 50%;
	background-repeat: no-repeat;
	display: block;
	}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
	background-color: #f4f4f4;
	}
.leaflet-bar a:first-child {
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	}
.leaflet-bar a:last-child {
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
	border-bottom: none;
	}
.leaflet-bar a.leaflet-disabled {
	cursor: default;
	background-color: #f4f4f4;
	color: #bbb;
	}

.leaflet-touch .leaflet-bar a {
	width: 30px;
	height: 30px;
	line-height: 30px;
	}
.leaflet-touch .leaflet-bar a:first-child {
	border-top-left-radius: 2px;
	border-top-right-radius: 2px;
	}
.leaflet-touch .leaflet-bar a:last-child {
	border-bottom-left-radius: 2px;
	border-bottom-right-radius: 2px;
	}

/* zoom control */

.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
	font: bold 18px 'Lucida Console', Monaco, monospace;
	text-indent: 1px;
	}

.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out  {
	font-size: 22px;
	}


/* layers control */

.leaflet-control-layers {
	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
	background: #fff;
	border-radius: 5px;
	}
.leaflet-control-layers-toggle {
	background-image: url(/assets/js/vendor/images/layers.png);
	width: 36px;
	height: 36px;
	}
.leaflet-retina .leaflet-control-layers-toggle {
	background-image: url(/assets/js/vendor/images/layers-2x.png);
	background-size: 26px 26px;
	}
.leaflet-touch .leaflet-control-layers-toggle {
	width: 44px;
	height: 44px;
	}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
	display: none;
	}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
	display: block;
	position: relative;
	}
.leaflet-control-layers-expanded {
	padding: 6px 10px 6px 6px;
	color: #333;
	background: #fff;
	}
.leaflet-control-layers-scrollbar {
	overflow-y: scroll;
	overflow-x: hidden;
	padding-right: 5px;
	}
.leaflet-control-layers-selector {
	margin-top: 2px;
	position: relative;
	top: 1px;
	}
.leaflet-control-layers label {
	display: block;
	font-size: 13px;
	font-size: 1.08333em;
	}
.leaflet-control-layers-separator {
	height: 0;
	border-top: 1px solid #ddd;
	margin: 5px -10px 5px -6px;
	}

/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
	background-image: url(/assets/js/vendor/images/marker-icon.png);
	}


/* attribution and scale controls */

.leaflet-container .leaflet-control-attribution {
	background: #fff;
	background: rgba(255, 255, 255, 0.8);
	margin: 0;
	}
.leaflet-control-attribution,
.leaflet-control-scale-line {
	padding: 0 5px;
	color: #333;
	line-height: 1.4;
	}
.leaflet-control-attribution a {
	text-decoration: none;
	}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
	text-decoration: underline;
	}
.leaflet-attribution-flag {
	display: inline !important;
	vertical-align: baseline !important;
	width: 1em;
	height: 0.6669em;
	}
.leaflet-left .leaflet-control-scale {
	margin-left: 5px;
	}
.leaflet-bottom .leaflet-control-scale {
	margin-bottom: 5px;
	}
.leaflet-control-scale-line {
	border: 2px solid #777;
	border-top: none;
	line-height: 1.1;
	padding: 2px 5px 1px;
	white-space: nowrap;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	background: rgba(255, 255, 255, 0.8);
	text-shadow: 1px 1px #fff;
	}
.leaflet-control-scale-line:not(:first-child) {
	border-top: 2px solid #777;
	border-bottom: none;
	margin-top: -2px;
	}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
	border-bottom: 2px solid #777;
	}

.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	box-shadow: none;
	}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	border: 2px solid rgba(0,0,0,0.2);
	background-clip: padding-box;
	}


/* popup */

.leaflet-popup {
	position: absolute;
	text-align: center;
	margin-bottom: 20px;
	}
.leaflet-popup-content-wrapper {
	padding: 1px;
	text-align: left;
	border-radius: 12px;
	}
.leaflet-popup-content {
	margin: 13px 24px 13px 20px;
	line-height: 1.3;
	font-size: 13px;
	font-size: 1.08333em;
	min-height: 1px;
	}
.leaflet-popup-content p {
	margin: 17px 0;
	margin: 1.3em 0;
	}
.leaflet-popup-tip-container {
	width: 40px;
	height: 20px;
	position: absolute;
	left: 50%;
	margin-top: -1px;
	margin-left: -20px;
	overflow: hidden;
	pointer-events: none;
	}
.leaflet-popup-tip {
	width: 17px;
	height: 17px;
	padding: 1px;

	margin: -10px auto 0;
	pointer-events: auto;

	-webkit-transform: rotate(45deg);
	   -moz-transform: rotate(45deg);
	    -ms-transform: rotate(45deg);
	        transform: rotate(45deg);
	}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
	background: white;
	color: #333;
	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
	}
.leaflet-container a.leaflet-popup-close-button {
	position: absolute;
	top: 0;
	right: 0;
	border: none;
	text-align: center;
	width: 24px;
	height: 24px;
	font: 16px/24px Tahoma, Verdana, sans-serif;
	color: #757575;
	text-decoration: none;
	background: transparent;
	}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
	color: #585858;
	}
.leaflet-popup-scrolled {
	overflow: auto;
	}

.leaflet-oldie .leaflet-popup-content-wrapper {
	-ms-zoom: 1;
	}
.leaflet-oldie .leaflet-popup-tip {
	width: 24px;
	margin: 0 auto;

	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
	}

.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
	border: 1px solid #999;
	}


/* div icon */

.leaflet-div-icon {
	background: #fff;
	border: 1px solid #666;
	}


/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
	position: absolute;
	padding: 6px;
	background-color: #fff;
	border: 1px solid #fff;
	border-radius: 3px;
	color: #222;
	white-space: nowrap;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	pointer-events: none;
	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
	}
.leaflet-tooltip.leaflet-interactive {
	cursor: pointer;
	pointer-events: auto;
	}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	position: absolute;
	pointer-events: none;
	border: 6px solid transparent;
	background: transparent;
	content: "";
	}

/* Directions */

.leaflet-tooltip-bottom {
	margin-top: 6px;
}
.leaflet-tooltip-top {
	margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
	left: 50%;
	margin-left: -6px;
	}
.leaflet-tooltip-top:before {
	bottom: 0;
	margin-bottom: -12px;
	border-top-color: #fff;
	}
.leaflet-tooltip-bottom:before {
	top: 0;
	margin-top: -12px;
	margin-left: -6px;
	border-bottom-color: #fff;
	}
.leaflet-tooltip-left {
	margin-left: -6px;
}
.leaflet-tooltip-right {
	margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	top: 50%;
	margin-top: -6px;
	}
.leaflet-tooltip-left:before {
	right: 0;
	margin-right: -12px;
	border-left-color: #fff;
	}
.leaflet-tooltip-right:before {
	left: 0;
	margin-left: -12px;
	border-right-color: #fff;
	}

/* Printing */

@media print {
	/* Prevent printers from removing background-images of controls. */
	.leaflet-control {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
		}
	}

/* assets/vendor/phosphor/regular/style.css */
/* Phosphor Icons 2.1.1 (MIT), self-hosted: woff2 only, subset by bin/subset-icons.py. */
@font-face {
  font-family: "Phosphor";
  src: url("/assets/vendor/phosphor/regular/Phosphor.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

.ph {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: "Phosphor" !important;
  speak: never;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Enable Ligatures ================ */
  letter-spacing: 0;
  -webkit-font-feature-settings: "liga";
  -moz-font-feature-settings: "liga=1";
  -moz-font-feature-settings: "liga";
  -ms-font-feature-settings: "liga" 1;
  font-feature-settings: "liga";
  -webkit-font-variant-ligatures: discretionary-ligatures;
  font-variant-ligatures: discretionary-ligatures;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.ph.ph-arrow-left:before {
  content: "\e058";
}
.ph.ph-arrow-u-up-left:before {
  content: "\e08a";
}
.ph.ph-bell:before {
  content: "\e0ce";
}
.ph.ph-bell-ringing:before {
  content: "\e5e8";
}
.ph.ph-bell-slash:before {
  content: "\e0d4";
}
.ph.ph-boat:before {
  content: "\e786";
}
.ph.ph-calendar-blank:before {
  content: "\e10a";
}
.ph.ph-calendar-dots:before {
  content: "\e7b4";
}
.ph.ph-calendar-plus:before {
  content: "\e714";
}
.ph.ph-caret-down:before {
  content: "\e136";
}
.ph.ph-chart-line:before {
  content: "\e154";
}
.ph.ph-check:before {
  content: "\e182";
}
.ph.ph-cloud-slash:before {
  content: "\e1b6";
}
.ph.ph-compass:before {
  content: "\e1c8";
}
.ph.ph-crosshair:before {
  content: "\e1d6";
}
.ph.ph-device-mobile:before {
  content: "\e1e0";
}
.ph.ph-download-simple:before {
  content: "\e20c";
}
.ph.ph-export:before {
  content: "\eaf0";
}
.ph.ph-eye:before {
  content: "\e220";
}
.ph.ph-floppy-disk:before {
  content: "\e248";
}
.ph.ph-gauge:before {
  content: "\e628";
}
.ph.ph-island:before {
  content: "\ee06";
}
.ph.ph-link:before {
  content: "\e2e2";
}
.ph.ph-lock:before {
  content: "\e2fa";
}
.ph.ph-map-pin:before {
  content: "\e316";
}
.ph.ph-map-trifold:before {
  content: "\e31a";
}
.ph.ph-minus:before {
  content: "\e32a";
}
.ph.ph-moon:before {
  content: "\e330";
}
.ph.ph-path:before {
  content: "\e39c";
}
.ph.ph-pencil-simple:before {
  content: "\e3b4";
}
.ph.ph-person-simple-swim:before {
  content: "\e736";
}
.ph.ph-plus-square:before {
  content: "\ed4a";
}
.ph.ph-polygon:before {
  content: "\e6d0";
}
.ph.ph-ruler:before {
  content: "\e6b8";
}
.ph.ph-share-network:before {
  content: "\e408";
}
.ph.ph-sign-in:before {
  content: "\e428";
}
.ph.ph-sign-out:before {
  content: "\e42a";
}
.ph.ph-sparkle:before {
  content: "\e6a2";
}
.ph.ph-star:before {
  content: "\e46a";
}
.ph.ph-sun:before {
  content: "\e472";
}
.ph.ph-trash:before {
  content: "\e4a6";
}
.ph.ph-user-circle:before {
  content: "\e4c4";
}
.ph.ph-warning:before {
  content: "\e4e0";
}
.ph.ph-warning-circle:before {
  content: "\e4e2";
}
.ph.ph-waves:before {
  content: "\e6de";
}
.ph.ph-wifi-slash:before {
  content: "\e4f2";
}
.ph.ph-wind:before {
  content: "\e5d2";
}
.ph.ph-x:before {
  content: "\e4f6";
}

/* assets/vendor/phosphor/fill/style.css */
/* Phosphor Icons 2.1.1 (MIT), self-hosted: woff2 only, subset by bin/subset-icons.py. */
@font-face {
  font-family: "Phosphor-Fill";
  src: url("/assets/vendor/phosphor/fill/Phosphor-Fill.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

.ph-fill {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: "Phosphor-Fill" !important;
  speak: never;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Enable Ligatures ================ */
  letter-spacing: 0;
  -webkit-font-feature-settings: "liga";
  -moz-font-feature-settings: "liga=1";
  -moz-font-feature-settings: "liga";
  -ms-font-feature-settings: "liga" 1;
  font-feature-settings: "liga";
  -webkit-font-variant-ligatures: discretionary-ligatures;
  font-variant-ligatures: discretionary-ligatures;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.ph-fill.ph-arrow-left:before {
  content: "\e058";
}
.ph-fill.ph-arrow-u-up-left:before {
  content: "\e08a";
}
.ph-fill.ph-bell:before {
  content: "\e0ce";
}
.ph-fill.ph-bell-ringing:before {
  content: "\e5e8";
}
.ph-fill.ph-bell-slash:before {
  content: "\e0d4";
}
.ph-fill.ph-boat:before {
  content: "\e786";
}
.ph-fill.ph-calendar-blank:before {
  content: "\e10a";
}
.ph-fill.ph-calendar-dots:before {
  content: "\e7b4";
}
.ph-fill.ph-calendar-plus:before {
  content: "\e714";
}
.ph-fill.ph-caret-down:before {
  content: "\e136";
}
.ph-fill.ph-chart-line:before {
  content: "\e154";
}
.ph-fill.ph-check:before {
  content: "\e182";
}
.ph-fill.ph-cloud-slash:before {
  content: "\e1b6";
}
.ph-fill.ph-compass:before {
  content: "\e1c8";
}
.ph-fill.ph-crosshair:before {
  content: "\e1d6";
}
.ph-fill.ph-device-mobile:before {
  content: "\e1e0";
}
.ph-fill.ph-download-simple:before {
  content: "\e20c";
}
.ph-fill.ph-export:before {
  content: "\eaf0";
}
.ph-fill.ph-eye:before {
  content: "\e220";
}
.ph-fill.ph-floppy-disk:before {
  content: "\e248";
}
.ph-fill.ph-gauge:before {
  content: "\e628";
}
.ph-fill.ph-island:before {
  content: "\ee06";
}
.ph-fill.ph-link:before {
  content: "\e2e2";
}
.ph-fill.ph-lock:before {
  content: "\e2fa";
}
.ph-fill.ph-map-pin:before {
  content: "\e316";
}
.ph-fill.ph-map-trifold:before {
  content: "\e31a";
}
.ph-fill.ph-minus:before {
  content: "\e32a";
}
.ph-fill.ph-moon:before {
  content: "\e330";
}
.ph-fill.ph-path:before {
  content: "\e39c";
}
.ph-fill.ph-pencil-simple:before {
  content: "\e3b4";
}
.ph-fill.ph-person-simple-swim:before {
  content: "\e736";
}
.ph-fill.ph-plus-square:before {
  content: "\ed4a";
}
.ph-fill.ph-polygon:before {
  content: "\e6d0";
}
.ph-fill.ph-ruler:before {
  content: "\e6b8";
}
.ph-fill.ph-share-network:before {
  content: "\e408";
}
.ph-fill.ph-sign-in:before {
  content: "\e428";
}
.ph-fill.ph-sign-out:before {
  content: "\e42a";
}
.ph-fill.ph-sparkle:before {
  content: "\e6a2";
}
.ph-fill.ph-star:before {
  content: "\e46a";
}
.ph-fill.ph-sun:before {
  content: "\e472";
}
.ph-fill.ph-trash:before {
  content: "\e4a6";
}
.ph-fill.ph-user-circle:before {
  content: "\e4c4";
}
.ph-fill.ph-warning:before {
  content: "\e4e0";
}
.ph-fill.ph-warning-circle:before {
  content: "\e4e2";
}
.ph-fill.ph-waves:before {
  content: "\e6de";
}
.ph-fill.ph-wifi-slash:before {
  content: "\e4f2";
}
.ph-fill.ph-wind:before {
  content: "\e5d2";
}
.ph-fill.ph-x:before {
  content: "\e4f6";
}

/* assets/css/base.css */
/*
 * base.css — app-level bridges on top of nocturne.css.
 * Nocturne (loaded first) already sets the dark palette, Inter, the
 * component classes (.btn, .seg, .card, .table, .dialog, .input …) and the
 * :focus-visible ring. This file keeps only the guards the app still needs
 * and a few element defaults Nocturne doesn't cover.
 */

/* Components below (and Nocturne) set explicit `display`, which would
   otherwise defeat the `hidden` attribute. Restore it, the normalize.css way. */
[hidden] { display: none !important; }

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

html, body {
    margin: 0;
    padding: 0;
    /* A single overlong token (raw pasted URL) must never scroll the page.
       clip, not hidden: hidden made body a scroll container that never
       scrolls, which broke position: sticky (the Plan screen's Save bar);
       hidden stays as the fallback where clip isn't supported. */
    overflow-x: hidden;
    overflow-x: clip;
    width: 100%;
    /* No overscroll-behavior here: where overflow-x falls back to hidden,
       body is a scroll container, and Firefox for Android stops touch
       scrolling when it can't hand the gesture on to the page. */
}

body {
    background: var(--color-bg);
    color: var(--color-text);
    -webkit-tap-highlight-color: transparent;
}

a { color: var(--color-accent-300); text-decoration: none; }

/* Touch has no hover: browsers fake one on tap and leave it stuck, so every
   :hover rule in the app sits behind this query; touch gets :active. */
@media (hover: hover) and (pointer: fine) {
    a:hover { color: var(--color-accent-200); }
}

/* Controls fire on tap without the double-tap-zoom wait, and a long press
   doesn't select their label or pop the link callout. Content links stay
   selectable. */
button, a, [role="button"], .seg-opt, .radio {
    touch-action: manipulation;
}
button, [role="button"], .seg-opt, .radio {
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
}

/* Native controls follow the dark ground (date-picker icon, scrollbars). */
:root {
    color-scheme: dark;
    /* Go / Caution / No-go. The no-go red is too dark for small text on a
       card (3.9:1), so text takes the lighter shade (6.3:1). */
    --color-go: #35b06a;
    --color-caution: #e0bb4a;
    --color-no-go: #d9575a;
    --color-no-go-text: #ef8a8c;
    /* Weather icons (sky.js). */
    --sky-sun: #f5c451;
    --sky-cloud: #dfe2ee;
    --sky-cloud-back: #8f95ad;
    --sky-cloud-storm: #6f7591;
    --sky-rain: #5fd3e6;
}

/* Larger tap targets for the touch build without disturbing Nocturne's
   compact desktop sizing. */
@media (pointer: coarse) {
    .btn { min-height: 44px; }
    .btn-icon { width: 44px; height: 44px; }
    .seg-opt, .context-chip { min-height: 44px; }
    /* Under 16px, iOS zooms the page into a focused field and stays zoomed. */
    .input, input, select, textarea { font-size: 16px; }
}

.hint {
    font-size: 12px;
    color: var(--color-neutral-500);
    margin: 0;
}

.form-error {
    margin: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-no-go-text);
}

/* Utility: a Nocturne faded rule as a standalone element. */
.rule {
    height: 1px;
    border: 0;
    background: linear-gradient(to right,
        transparent, var(--color-divider) 48px,
        var(--color-divider) calc(100% - 48px), transparent);
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* assets/css/layout.css */
/* layout.css — app shell: header, context bar, screen frame, dialogs, footer. */

/* ── Header ─────────────────────────────────────────────────────────────── */
.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 16.8px;
    flex-wrap: wrap;
    /* env(): the installed app draws under the iPhone status bar / notch
       (viewport-fit=cover + black-translucent status bar). */
    padding: calc(11.2px + env(safe-area-inset-top)) calc(22.4px + env(safe-area-inset-right))
        11.2px calc(22.4px + env(safe-area-inset-left));
    background: color-mix(in srgb, #0b1a22 92%, transparent);
    backdrop-filter: blur(8px);
    box-shadow: 0 1px 0 var(--color-divider);
}

.app-brand {
    margin-right: auto;
    display: flex;
    align-items: baseline;
    gap: 8.4px;
}

.app-brand-logo {
    flex: none;
    align-self: center;
    width: 32px;
    height: 32px;
}

.app-brand-name {
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 18px;
    letter-spacing: -0.015em;
}

.app-brand-region {
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-accent);
}

/* The region label doubles as the island switcher. */
.island-btn {
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-height: 32px;
    margin: -4px 0;
    padding: 0 8.4px;
    border: 1px solid color-mix(in srgb, var(--color-accent) 40%, transparent);
    border-radius: 999px;
    background: none;
    font-family: inherit;
    cursor: pointer;
}
.island-btn .ph { font-size: 12px; }
@media (hover: hover) and (pointer: fine) {
    .island-btn:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
}
.island-btn:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
@media (pointer: coarse) {
    .island-btn { min-height: 44px; margin: -8px 0; }
}

.screen-nav.seg { white-space: nowrap; }
.screen-nav .seg-opt {
    background: none;
    border: 0;
    font: inherit;
    font-size: 13px;
    color: var(--color-text);
}
.screen-nav .seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
.screen-nav .seg-opt[aria-selected="true"] {
    color: var(--color-accent);
    box-shadow: inset 0 0 0 1px var(--color-accent);
}
@media (hover: hover) and (pointer: fine) {
    .screen-nav .seg-opt:not([aria-selected="true"]):hover {
        background: color-mix(in srgb, var(--color-text) 7%, transparent);
    }
}
.screen-nav .seg-opt:not([aria-selected="true"]):active {
    background: color-mix(in srgb, var(--color-text) 14%, transparent);
}

/* ── Context bar ────────────────────────────────────────────────────────── */
.context-bar {
    max-width: 1180px;
    margin: 0 auto;
    /* Landscape iPhones land on this (wider) layout: clear the notch side. */
    padding: 16.8px calc(22.4px + env(safe-area-inset-right)) 0 calc(22.4px + env(safe-area-inset-left));
    display: flex;
    align-items: center;
    gap: 11.2px;
    flex-wrap: wrap;
}

.context-chip {
    display: inline-flex;
    align-items: center;
    gap: 8.4px;
    padding: 5.6px 11.2px;
    border: 1px solid var(--color-divider);
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
    .context-chip:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
}
.context-chip:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.context-chip > .ph { color: var(--color-accent); }
.context-chip-label { font-size: 14px; }
.context-chip-detail { font-size: 12px; color: var(--color-neutral-500); }
.context-chip-detail:empty { display: none; }

.context-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8.4px;
}

.context-feedback {
    flex-basis: 100%;
    margin: 0;
    font-size: 12px;
    color: var(--color-neutral-400);
}
.context-bar .form-error { flex-basis: 100%; }

/* Spot view (app.js): one title row (← back, the spot's name, ★, share) over the day strip. */
.spot-back { display: none; }
.is-spot-view .spot-back { display: inline-flex; margin-left: -8.4px; }
.is-spot-view #analyze-btn { display: none; }
.is-spot-view .context-chip { flex: 1 1 0; min-width: 0; padding-inline: 4px; border-color: transparent; }
.is-spot-view .context-chip > .ph { display: none; }
.is-spot-view .context-chip-label {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font: 600 18px/1.25 var(--font-heading);
}
.is-spot-view .context-actions { flex: none; margin-left: 0; }

/* ── Day strip: one tap to pick the day ─────────────────────────────────── */
.day-strip {
    flex: 1 1 100%;
    display: flex;
    align-items: stretch;
    gap: 8.4px;
    min-width: 0;
}
.day-strip-days {
    flex: 1;
    display: flex;
    gap: 5.6px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}
.day-strip-days::-webkit-scrollbar { display: none; }
.day-btn, .day-more {
    flex: none;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 52px;
    min-height: 44px;
    padding: 4px 8px;
    border: 1px solid var(--color-divider);
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    line-height: 1.15;
    cursor: pointer;
    scroll-snap-align: start;
}
.day-btn small { font-size: 11px; color: var(--color-neutral-400); }
.day-btn b { font-size: 15px; font-weight: 500; }
.day-btn[aria-pressed="true"],
.day-more.is-selected {
    border-color: var(--color-accent);
    box-shadow: inset 0 0 0 1px var(--color-accent);
    color: var(--color-accent);
}
.day-btn[aria-pressed="true"] small { color: var(--color-accent); }
.day-more { flex-direction: row; gap: 5.6px; font-size: 13px; }
.day-more .ph { font-size: 16px; color: var(--color-accent); }
@media (hover: hover) and (pointer: fine) {
    .day-btn:not([aria-pressed="true"]):hover,
    .day-more:not(.is-selected):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
}
.day-btn:active, .day-more:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.spots-date-note { margin: 0; padding: 8.4px 16.8px; font-size: 12px; color: var(--color-neutral-400); }
.spots-date-note[hidden] { display: none; }

/* ── Main frame + screens ───────────────────────────────────────────────── */
.app-main {
    max-width: 1180px;
    margin: 0 auto;
    padding: 16.8px calc(22.4px + env(safe-area-inset-right)) 44.8px calc(22.4px + env(safe-area-inset-left));
}

.screen[hidden] { display: none; }

/* ── Empty + error states ───────────────────────────────────────────────── */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 11.2px;
    padding: 56px 22.4px;
    color: var(--color-neutral-400);
}
.empty-state .ph { font-size: 34px; color: var(--color-accent); }
.empty-state p { margin: 0; max-width: 46ch; font-size: 14px; }

.error-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 11.2px;
    padding: 44.8px 22.4px;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.error-card .ph { font-size: 30px; color: var(--color-accent); }
.error-card p { margin: 0; font-size: 14px; max-width: 52ch; }

/* ── Dialogs ────────────────────────────────────────────────────────────── */
.dialog-backdrop { z-index: 60; }
.dialog-backdrop[hidden] { display: none; }
.dialog {
    width: min(460px, 100%);
    max-height: calc(100vh - 44.8px);
    max-height: calc(100dvh - 44.8px); /* the visible height, URL bar included */
    overflow-y: auto;
    overscroll-behavior: contain; /* scrolling to the end doesn't move the page behind */
}
.dialog-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 11.2px;
}
.dialog .field { margin-top: 11.2px; }
.dialog-actions { align-items: center; }

/* Island picker */
.island-options {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8.4px;
    margin-top: 11.2px;
}
.island-opt {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2.8px;
    min-height: 56px;
    padding: 8.4px 11.2px;
    border: 1px solid var(--color-divider);
    border-radius: 8px;
    cursor: pointer;
}
.island-opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.island-opt-name { font-size: 15px; }
.island-opt-count { font-size: 12px; color: var(--color-neutral-400); }
.island-opt:has(input:checked) { border-color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }
.island-opt:has(input:checked) .island-opt-name { color: var(--color-accent); }
.island-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
    .island-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
}
.island-opt:not(:has(input:checked)):active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.island-locate { width: 100%; margin-top: 11.2px; gap: 6px; }
.island-status { margin: 8.4px 0 0; }
.island-status[hidden] { display: none; }

/* First-visit "Diving on another island?" banner: a floating card like the install
   card, so appearing late (after /api/islands/guess) never pushes the page down (CLS). */
.island-banner {
    position: fixed;
    right: calc(22.4px + env(safe-area-inset-right));
    bottom: calc(22.4px + env(safe-area-inset-bottom));
    z-index: 64;
    width: min(440px, calc(100vw - 32px));
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8.4px 11.2px;
    padding: 11.2px 11.2px 11.2px 14px;
    border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent);
    border-radius: 16px;
    background: var(--color-surface);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5);
}
.island-banner[hidden] { display: none; }
.island-banner > .ph { font-size: 20px; color: var(--color-accent); }
.island-banner p { flex: 1 1 220px; margin: 0; font-size: 13px; }
.island-banner-actions { display: flex; align-items: center; gap: 8.4px; }
.island-banner-actions .btn { gap: 6px; }

#picker-map {
    width: 100%;
    height: 300px;
    border-radius: 8px;
    border: 1px solid var(--color-divider);
    touch-action: none;
}

/* ── About + links to the public island pages (crawlable) ───────────────── */
.app-about {
    max-width: 1180px;
    margin: 0 auto;
    padding: 22.4px calc(22.4px + env(safe-area-inset-right)) 0 calc(22.4px + env(safe-area-inset-left));
    border-top: 1px solid var(--color-divider);
}
.app-about h1 { margin: 0 0 5.6px; font-size: 16px; font-weight: 500; }
.app-about p { margin: 0 0 11.2px; font-size: 13px; color: var(--color-neutral-400); max-width: 70ch; }
.app-about-links { display: flex; flex-wrap: wrap; gap: 8.4px; margin: 0; padding: 0; list-style: none; }
.app-about-links a {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 5.6px 11.2px;
    border: 1px solid var(--color-divider);
    border-radius: 8px;
    color: var(--color-text);
    font-size: 13px;
    text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
    .app-about-links a:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
}
@media (pointer: coarse) {
    .app-about-links a { min-height: 44px; }
}

/* ── Footer ─────────────────────────────────────────────────────────────── */
.app-footer {
    max-width: 1180px;
    margin: 0 auto;
    padding: 22.4px calc(22.4px + env(safe-area-inset-right)) 22.4px calc(22.4px + env(safe-area-inset-left));
}
.app-footer p { margin: 0; font-size: 11px; color: var(--color-neutral-500); }
.app-footer p + p { margin-top: 5.6px; }
.app-footer a { color: var(--color-neutral-500); }

/* ── Installable app: install button, status line, toast, saved copies ──── */
.install-fab {
    position: fixed;
    right: calc(20px + env(safe-area-inset-right));
    bottom: calc(20px + env(safe-area-inset-bottom));
    z-index: 40; /* over the tab bar (30), under dialogs (60) */
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 48px;
    padding: 5px 18px 5px 5px;
    border: 0;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-bg);
    font: 600 14px/1 var(--font-heading);
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: 0 6px 20px color-mix(in srgb, var(--color-accent) 35%, transparent), 0 2px 6px rgba(0, 0, 0, 0.35);
    -webkit-tap-highlight-color: transparent;
}
.install-fab[hidden],
/* The card has its own Install button: one at a time. */
.install-card:not([hidden]) + .install-fab { display: none; }
.install-fab-icon {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--color-bg) 16%, transparent);
    font-size: 20px;
}
.install-fab-icon .ph { display: block; }
.install-fab:active { transform: scale(0.96); filter: brightness(0.94); }
.install-fab:focus-visible { outline: 2px solid var(--color-text); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
    .install-fab:hover:not(:active) { filter: brightness(1.07); }
}
/* Room to scroll the last rows out from under it. */
body:has(.install-fab:not([hidden])) .app-footer { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }

/* The install card (pwa.js): offers the app once it's been used a little. */
.install-card {
    position: fixed;
    right: calc(22.4px + env(safe-area-inset-right));
    bottom: calc(22.4px + env(safe-area-inset-bottom));
    z-index: 65;
    width: min(380px, calc(100vw - 32px));
    padding: 16.8px;
    border: 1px solid color-mix(in srgb, var(--color-accent) 45%, transparent);
    border-radius: 16px;
    background: var(--color-surface);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5);
}
.install-card[hidden] { display: none; }
.install-card-close { position: absolute; top: 8.4px; right: 8.4px; }
.install-card-head { display: flex; gap: 12px; align-items: flex-start; padding-right: 32px; }
.install-card-head img { flex: none; border-radius: 50%; }
.install-card h2 { margin: 2px 0 4px; font-size: 16px; font-weight: 600; }
.install-card-head p { margin: 0; font-size: 13px; line-height: 1.45; color: var(--color-neutral-300); }
.install-card-perks { display: grid; gap: 6px; margin: 12px 0 0; padding: 0; list-style: none; font-size: 13px; }
.install-card-perks li { display: flex; align-items: center; gap: 8.4px; }
.install-card-perks .ph { font-size: 18px; color: var(--color-accent); }
.install-card-steps {
    margin: 12px 0 0;
    padding: 10px 12px 10px 30px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
    font-size: 14px;
    line-height: 1.7;
}
.install-card-steps[hidden] { display: none; }
.install-card-steps .ph { font-size: 17px; vertical-align: -3px; color: var(--color-accent); }
.install-card-actions { display: flex; gap: 8.4px; margin-top: 14px; }
.install-card-actions .btn { flex: 1; justify-content: center; gap: 6px; }
.install-card-actions .btn[hidden] { display: none; }
.install-card-go {
    border: 0;
    background: var(--color-accent);
    color: var(--color-bg);
    font-weight: 600;
}
.install-card-go:active { filter: brightness(0.92); }
.notify-btn { gap: 5.6px; font-size: 13px; }
.units-btn { gap: 5.6px; font-size: 13px; }
.units-btn i { font-size: 18px; }
.units-group { margin-top: 14px; }
.units-group h3 { margin: 0 0 5.6px; font-size: 13px; font-weight: 500; color: var(--color-neutral-400); }
.units-group .seg { display: flex; }
.units-group .seg-opt { flex: 1; justify-content: center; }
.notify-btn[hidden] { display: none; }
.notify-btn.is-on .ph-fill { color: var(--color-caution); }
.notify-btn i { font-size: 18px; }

/* ── Account sheet (account.js) ─────────────────────────────────────────── */
.account-lede { margin: 0 0 11.2px; font-size: 14px; line-height: 1.45; color: var(--color-neutral-300); }
.account-lede b { color: var(--color-text); font-weight: 600; overflow-wrap: anywhere; }
.account-form .hint { margin-top: 11.2px; }
.account-providers[hidden] { display: none; }
/* Google's own button look (dark variant; light.css has the light one). */
.btn-google {
    display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 0;
    background: #131314; color: #e3e3e3; border: 1px solid #8e918f; font-weight: 500;
}
.btn-google:hover { background: #1c1c1d; }
.btn-google .google-g { flex: none; }
.account-or {
    display: flex; align-items: center; gap: 10px; margin: 14px 0 6px;
    font-size: 12.5px; color: var(--color-neutral-400);
}
.account-or::before, .account-or::after { content: ""; flex: 1; height: 1px; background: var(--color-divider); }
.account-code { font-size: 22px; letter-spacing: 6px; text-align: center; font-variant-numeric: tabular-nums; }
.account-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-error { margin: 8px 0 0; font-size: 13px; color: var(--color-no-go-text); }
.form-error[hidden] { display: none; }
.turnstile:empty { display: none; }
.account-links { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px; margin-top: 8px; }
.account-section { margin-top: 16.8px; }
.account-section h3 { margin: 0 0 5.6px; font-size: 13px; font-weight: 500; color: var(--color-neutral-400); }
.account-list { list-style: none; margin: 0; padding: 0; }
.account-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 0;
    border-bottom: 1px solid var(--color-divider);
    font-size: 14px;
}
.account-row small { display: block; margin-left: 22px; font-size: 12px; color: var(--color-neutral-500); }
.account-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16.8px; }
.account-actions .btn { gap: 5.6px; }
.account-danger { color: var(--color-no-go-text); }
.account-danger-btn { color: var(--color-no-go-text); border-color: var(--color-no-go); }

/* ── Saved spots (saved-spots.js) ───────────────────────────────────────── */
.save-spot-btn[aria-pressed="true"] i,
.week-star[aria-pressed="true"] i,
.spot-saved { color: var(--color-caution); }
.spot-saved { font-size: 12px; vertical-align: -1px; }
.week-star {
    padding: 0 5.6px 0 0;
    border: 0;
    background: none;
    color: var(--color-neutral-500);
    font-size: 14px;
    vertical-align: -2px;
    cursor: pointer;
    touch-action: manipulation;
}
.myspot .account-row { align-items: flex-start; }
.myspot-name {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.myspot-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.myspot-actions .btn-ghost { gap: 4px; font-size: 12px; }
.myspot-actions .ph-bell-ringing { color: var(--color-caution); }
.myspot-actions .is-confirming { width: auto; padding: 0 10px; color: var(--color-no-go-text); font-size: 12px; font-weight: 600; }
.myspot-rename { display: flex; gap: 6px; align-items: center; margin-bottom: 2px; }
.myspot-rename input { flex: 1; min-width: 0; padding-block: 5px; }
.myspot-rename .btn { padding-block: 5px; }
.myspot-alert { display: grid; gap: 8px; padding: 8px 0 12px; font-size: 13px; color: var(--color-neutral-300); }
.myspot-alert select { width: auto; margin-left: 4px; padding-block: 4px; }
.myspot-check { display: flex; align-items: center; gap: 6px; }
.myspot-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.account-note { margin: 0 0 8px; }

/* ── Members-only prompt (signInPrompt in account.js) ──────────────────── */
.members-lock {
    display: grid;
    justify-items: center;
    gap: 8px;
    margin: 12px 0;
    padding: 16px;
    border: 1px dashed var(--color-divider);
    border-radius: 12px;
    text-align: center;
}
.members-lock i { font-size: 22px; color: var(--color-accent); }
.members-lock p { margin: 0; max-width: 42ch; font-size: 13px; line-height: 1.45; color: var(--color-neutral-300); }
.day-btn.is-locked { opacity: 0.55; }
.day-btn.is-locked b::after { content: '\e2fa'; margin-left: 2px; font-family: 'Phosphor'; font-size: 10px; font-weight: 400; }

.net-status {
    flex-basis: 100%;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 5.6px;
    font-size: 12px;
    color: var(--color-neutral-400);
}
.net-status[hidden] { display: none; }
.net-status .ph { color: var(--color-caution); font-size: 14px; }

.saved-copy-note {
    display: flex;
    align-items: flex-start;
    gap: 8.4px;
    margin: 0 0 11.2px;
    padding: 8.4px 11.2px;
    border-radius: 8px;
    font-size: 12px;
    color: var(--color-neutral-300);
    background: color-mix(in srgb, #e0bb4a 10%, transparent);
}
.saved-copy-note .ph { flex: none; margin-top: 1px; color: var(--color-caution); font-size: 14px; }
.spots-panel .saved-copy-note { margin: 8.4px 16.8px; }

/* A copy saved on an earlier day: its reads aren't today's, so they lose
   their Go / Caution / No-go and visibility colours. */
.is-stale .verdict-chip,
.is-stale .dive-score,
.is-stale .dive-band,
.is-stale .vis-cat,
.is-stale .hour-bar,
.is-stale .spot-dot,
.is-stale .spot-vis,
.is-stale td.dive-cell {
    filter: grayscale(1);
    opacity: 0.6;
}

.app-toast {
    position: fixed;
    left: 50%;
    bottom: calc(22.4px + env(safe-area-inset-bottom));
    z-index: 70;
    transform: translateX(-50%);
    width: min(440px, calc(100vw - 32px));
    display: flex;
    align-items: center;
    gap: 8.4px;
    padding: 8.4px 8.4px 8.4px 14px;
    border: 1px solid var(--color-divider);
    border-radius: 12px;
    background: var(--color-surface);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    font-size: 13px;
}
.app-toast[hidden] { display: none; }
.app-toast-body { flex: 1; }
.app-toast-body .ph { vertical-align: -2px; }
.app-toast-action { flex: none; }
.app-toast-close { flex: none; }

/* ── Mobile: bottom tab bar + bottom sheets ─────────────────────────────── */
@media (max-width: 700px) {
    /* No backdrop-filter here: it makes the header the containing block for
       position:fixed children, so the bottom tab bar (which lives inside
       the header) would no longer be pinned to the viewport. */
    .app-header {
        padding: calc(11.2px + env(safe-area-inset-top)) calc(16.8px + env(safe-area-inset-right))
            11.2px calc(16.8px + env(safe-area-inset-left));
        backdrop-filter: none;
        background: #0b1a22;
    }
    .context-bar { padding: 11.2px 16.8px 0; }
    .app-main { padding: 11.2px 16.8px 22.4px; }
    /* The footer is the page's last box, so it clears the bottom tab bar. */
    .app-footer { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }

    .context-chip { flex: 1 1 100%; }
    /* The island sits under the app name, so the header stays one row. */
    .app-brand {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: 8.4px;
        align-items: center;
    }
    .app-brand-logo { grid-row: 1 / 3; }
    .app-brand-name { font-size: 17px; line-height: 1.2; }
    .island-btn {
        position: relative;
        justify-self: start;
        min-height: 0;
        margin: 1px 0 0;
        padding: 0;
        border: 0;
        border-radius: 4px;
    }
    .island-btn::after { content: ""; position: absolute; inset: -12px -14px; } /* 44px tap area */
    .island-btn:active { background: none; color: var(--color-text); }

    .island-banner > .ph { display: none; }
    .island-banner p { flex-basis: 100%; padding-right: 40px; }
    .island-banner-actions { flex: 1 1 100%; }
    .island-banner-actions .btn-primary,
    .island-banner-actions .btn-secondary { flex: 1; }
    .island-banner-actions .btn .ph { display: none; }
    #island-banner-close { position: absolute; top: 4px; right: 4px; }
    #island-banner-close .ph { display: inline-block; }
    .context-actions { flex: 1 1 100%; }
    .context-actions .btn-primary { flex: 1; }
    .is-spot-view .context-chip,
    .is-spot-view .context-actions { flex: none; }
    .is-spot-view .context-chip { flex: 1 1 0; }
    .is-spot-view .context-chip-detail { display: none; }

    .screen-nav.seg {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 30;
        display: flex;
        border: 0;
        border-top: 1px solid var(--color-divider);
        border-radius: 0;
        padding-bottom: env(safe-area-inset-bottom); /* clear the iPhone home indicator */
        background: color-mix(in srgb, #0b1a22 96%, transparent);
        backdrop-filter: blur(8px);
    }
    .screen-nav .seg-opt {
        flex: 1;
        flex-direction: column;
        gap: 2.8px;
        min-height: 56px;
        padding: 8.4px 4px;
        font-size: 11px;
        border-left: 0 !important;
    }
    .screen-nav .seg-opt[aria-selected="true"] { box-shadow: none; }
    .screen-nav .seg-opt .ph,
    .screen-nav .seg-opt .ph-fill { font-size: 18px; }

    .dialog-backdrop { align-items: flex-end; padding: 0; }
    .dialog {
        width: 100%;
        border-radius: 14px 14px 0 0;
        max-height: 88vh;
        max-height: 88dvh;
    }
    .dialog-actions { margin-bottom: env(safe-area-inset-bottom); }
    .app-toast { bottom: calc(68px + env(safe-area-inset-bottom)); }
    /* Above the bottom tab bar. */
    .install-fab { right: calc(16px + env(safe-area-inset-right)); bottom: calc(72px + env(safe-area-inset-bottom)); }
    body:has(.install-fab:not([hidden])) .app-footer { padding-bottom: calc(148px + env(safe-area-inset-bottom)); }
    .install-card,
    .island-banner {
        right: 50%;
        bottom: calc(76px + env(safe-area-inset-bottom));
        transform: translateX(50%);
    }
    .units-btn span,
    .notify-btn span { display: none; }
    .dialog::before {
        content: "";
        display: block;
        width: 36px;
        height: 4px;
        margin: 0 auto 8.4px;
        border-radius: 2px;
        background: var(--color-neutral-700);
    }
}

/* ── Marine alert notice (alert-notice.js) ─────────────────────────────── */
.alert-notice .dialog-head { align-items: center; gap: 10px; }
.alert-notice .dialog-title { flex: 1; }
.alert-notice-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    background: color-mix(in srgb, var(--color-caution) 18%, transparent);
    color: var(--color-caution);
    font-size: 22px;
}
.alert-notice-item { display: grid; gap: 6px; margin-bottom: 10px; }
.alert-notice-item h3 { margin: 0; font-size: 15px; }
.alert-notice-where { margin: 0; font-weight: 600; color: var(--color-caution); }
.alert-notice-impact { margin: 0; color: var(--color-neutral-300); }
#alert-dialog-body .hint { margin: 4px 0 0; }

/* assets/css/dashboard.css */
/* dashboard.css — Screen 1, Option 1B (Day ribbon). */

#dashboard-main[hidden] { display: none; }

.dash-stack { display: flex; flex-direction: column; gap: 16.8px; }

.panel {
    padding: 22.4px;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

/* ── Score cards: Visibility (feet) beside Dive conditions (Go/Caution/No-go) ── */
.score-cards {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
    gap: 16.8px;
}
.score-card {
    padding: 14px 16.8px;
    border-radius: 10px;
    background: rgba(233, 233, 237, 0.03);
    border: 1px solid var(--color-divider);
    min-width: 0;
}
.score-card h6 { margin: 0 0 8.4px; color: var(--color-neutral-400); }
/* One size for each card's headline value (Sky, Visibility). */
.vis-cat, .sky-title {
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 34px;
    line-height: 1.05;
    letter-spacing: -0.01em;
}
.vis-meta { margin-top: 6px; font-size: 13px; color: var(--color-neutral-400); }
.vis-sat { display: flex; align-items: center; gap: 6px; }
.vis-sat-note { margin-top: 2px; font-size: 12px; }
.vis-sat-icon {
    flex: none; width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.score-explainer { margin: 8.4px 0 0; font-size: 12px; color: var(--color-neutral-500); }

/* ── Next days: the spot's week, a chip per day (dashboard.js nextDaysCard) ── */
.next-days { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; }
.next-days::-webkit-scrollbar { display: none; }
.next-day, .next-day-more {
    flex: 1 0 auto; min-width: 48px; min-height: 48px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    padding: 6px 8px; border-radius: 8px;
    border: 1px solid var(--color-divider); background: transparent; color: var(--color-text);
    font: inherit; cursor: pointer;
}
.next-day small { font-size: 11px; color: var(--color-neutral-400); }
.next-day b { display: flex; align-items: center; gap: 2px; font-family: var(--font-heading); font-size: 16px; font-weight: 500; }
.next-day b .ph { font-size: 12px; }
.next-day.is-go b { color: var(--color-go); }
.next-day.is-caution b { color: var(--color-caution); }
.next-day.is-no_go b { color: var(--color-no-go-text); }
.next-day.is-unknown b { color: var(--color-neutral-500); }
.next-day[aria-pressed="true"] { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.next-day-more { flex-direction: row; gap: 6px; font-size: 12px; color: var(--color-accent); }

/* ── Sky (sky.js): the day's weather card and the hourly icon row ────────── */
.sky-head { display: flex; align-items: center; gap: 12px; }
.sky-head > div { min-width: 0; }
.sky-icon { flex: none; overflow: visible; }
.sky-icon .sky-sun { fill: var(--sky-sun); }
.sky-icon .sky-rays line { stroke: var(--sky-sun); stroke-width: 2.6; stroke-linecap: round; }
.sky-icon .sky-cloud { fill: var(--sky-cloud); }
.sky-icon .sky-cloud-back { fill: var(--sky-cloud-back); }
.sky-icon .sky-cloud-storm { fill: var(--sky-cloud-storm); }
.sky-icon .sky-drop { stroke: var(--sky-rain); stroke-width: 2.6; stroke-linecap: round; }
.sky-icon .sky-bolt { fill: var(--sky-sun); }
.sky-icon .sky-fog line { stroke: var(--sky-cloud-back); stroke-width: 3; stroke-linecap: round; }
/* Same columns as .hb-bars, so each icon sits over its hour's bar. */
.sky-row { display: flex; gap: 3px; padding: 0 calc(var(--gutter) + 2px) 4px 2px; }
.sky-cell { flex: 1; min-width: 0; display: flex; justify-content: center; }
.sky-cell .sky-icon { width: min(20px, 100%); height: auto; }
.panel > .score-explainer { margin: 14px 0 0; }

.verdict-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid currentColor;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.method-icon {
    display: inline-flex; /* inline in running text and chips */
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    vertical-align: -5px;
    color: var(--color-accent);
    font-size: 21px;
    line-height: 1;
}
.method-icon svg { width: 21px; height: 21px; }
/* In a Go / Caution / No-go chip the icon takes the verdict colour, like the score and label beside it. */
.verdict-chip .method-icon { color: inherit; }
.dive-way .method-icon { color: var(--way-color, var(--color-accent)); }
.verdict-chip.is-go { color: var(--color-go); background: #35b06a1f; }
.verdict-chip.is-caution { color: var(--color-caution); background: #e0bb4a1f; }
.verdict-chip.is-no_go { color: var(--color-no-go-text); background: #d9575a1f; }
.verdict-chip.is-unknown { color: var(--color-neutral-500); }

.verdict-chip b { font-variant-numeric: tabular-nums; }
/* One tile per way in; the selected one drives the reasons below and the hourly chart. */
.dive-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8.4px; }
.dive-way {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    min-width: 0;
    padding: 10px 11px 9px;
    border: 1px solid var(--color-divider);
    border-radius: 10px;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;
}
.dive-way:hover { border-color: var(--color-neutral-500); }
.dive-way:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.dive-way.is-selected {
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}
.dive-best {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-accent);
}
.dive-method { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; white-space: nowrap; }
.dive-score {
    margin-top: 4px;
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 42px;
    line-height: 0.9;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}
.dive-band { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; }
.dive-window { font-size: 12px; color: var(--color-neutral-400); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dive-best { display: block; }
.dive-headline { margin: 0 0 8.4px; font: 600 16px/1.3 var(--font-heading); }
.dive-reason { margin: 10px 0 0; font-size: 13px; color: var(--color-neutral-400); }
.dive-reach { color: var(--color-neutral-500); }
.dive-blue, .dive-note { margin: 10px 0 0; font-size: 12px; color: var(--color-neutral-400); }
.dive-note { color: var(--color-neutral-500); }

/* ── Hourly dive-conditions bars ───────────────────────────────────────── */
.hour-bar {
    width: 100%;
    border-radius: 4px 4px 2px 2px;
    background: linear-gradient(180deg, #3c4058, #282b3c);
    transition: height 400ms cubic-bezier(.22,.61,.36,1);
}
.hourly-card { margin-top: 16.8px; }
.hourly-caption { margin: 11.2px 0 0; font-size: 11px; color: var(--color-neutral-500); }

.hv-window { margin: 0 0 6px; font-size: 12px; font-weight: 600; color: var(--color-accent-300); white-space: nowrap; }
.hv-hours { display: flex; margin-top: 6px; }
.hv-hours span { flex: 1; min-width: 0; text-align: center; font-size: 11px; color: var(--color-neutral-500); }
.hv-hours span.is-best { color: var(--color-accent-300); }

.hb-plot { position: relative; height: 104px; }
/* The right-hand gutter holds the Go / No-go labels, clear of the bars. */
.hv-gutter { --gutter: 58px; }
.hv-gutter .hv-row, .hv-gutter .hv-hours { padding-right: var(--gutter); }
.hv-area { position: absolute; top: 0; bottom: 0; left: 0; right: var(--gutter); }
.hb-band {
    position: absolute; top: -4px; bottom: 0; border-radius: 8px;
    background: color-mix(in srgb, var(--color-accent) 14%, transparent);
}
.hv-line { position: absolute; left: 0; right: 0; border-top: 1px dashed color-mix(in srgb, var(--line) 55%, transparent); pointer-events: none; }
.hv-line span {
    position: absolute; right: 0; bottom: 1px; font-size: 10px; line-height: 1;
    color: var(--line); white-space: nowrap;
}
.hb-bars { position: absolute; inset: 0; display: flex; gap: 3px; align-items: flex-end; padding: 0 2px; }
.hb-col { position: relative; flex: 1; min-width: 0; height: 100%; display: flex; align-items: flex-end; }
.hb-peak {
    position: absolute; left: 50%; translate: -50% -4px; font-size: 12px; font-weight: 700;
    font-variant-numeric: tabular-nums; line-height: 1; z-index: 1;
}

/* Fish activity: a line over the bars, its key next to the best window. */
.hf-peak { margin-left: 12px; white-space: nowrap; }
.hf-key { display: inline-block; width: 14px; height: 2px; margin-right: 2px; vertical-align: middle; border-radius: 1px; }
.hf-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.hf-svg polyline { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.hf-dot {
    position: absolute; width: 6px; height: 6px; border-radius: 50%; translate: -50% 50%;
    box-shadow: 0 0 0 1.5px var(--color-bg); pointer-events: none;
}

/* ── Bottom row: the Read ────────────────────────────────────── */
.dash-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
    gap: 16.8px;
}
.dash-row > * { min-width: 0; } /* let wide content shrink/scroll, not stretch the row */
.dash-row h6 { margin: 0 0 11.2px; color: var(--color-neutral-400); }

.depth-panel { display: flex; gap: 22.4px; }
.depth-ruler {
    flex: none;
    width: 74px;
    position: relative;
    border-radius: 8px;
    background: linear-gradient(#12303a, #0e1018);
    overflow: hidden;
}
.depth-haze {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    background: linear-gradient(rgba(75, 176, 232, 0.28), rgba(75, 176, 232, 0));
}
.depth-mark { position: absolute; left: 0; right: 0; height: 2px; background: var(--color-accent-400); }
.depth-mark-label { position: absolute; left: 6px; font-size: 11px; color: var(--color-accent-300); }
.depth-read p { margin: 0; font-size: 14px; line-height: 1.6; }
.depth-read .read-head { margin: 0 0 8.4px; font-size: 14px; color: var(--color-neutral-400); }
.read-list { display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; font-size: 14px; line-height: 1.45; }
.read-list li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8.4px; align-items: baseline; }
.read-list li > .ph { font-size: 15px; transform: translateY(2px); }
.read-list b { font-weight: 600; margin-right: 2px; }
.read-list .is-go > .ph { color: var(--color-go); }
.read-list .is-caution > .ph { color: var(--color-caution); }
.read-list .is-no_go > .ph { color: var(--color-no-go-text); }
.read-list .is-info > .ph { color: var(--color-accent); }
.read-list .is-no_go b { color: var(--color-no-go-text); }
.read-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.depth-read .read-facts { margin-top: 11.2px; font-size: 13px; color: var(--color-neutral-400); }
.depth-read .disclaimer { margin-top: 11.2px; font-size: 12px; color: var(--color-neutral-500); }

/* Missing-source note under the score. */
.degraded-note {
    margin-top: 8.4px;
    font-size: 12px;
    color: var(--color-neutral-500);
}

/* ── Loading skeleton ──────────────────────────────────────────────────── */
.dashboard-skeleton { display: flex; flex-direction: column; gap: 16.8px; }
.dashboard-skeleton[hidden] { display: none; }
.skeleton-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); gap: 16.8px; }
.skeleton-panel {
    border-radius: 14px;
    background: rgba(233, 233, 237, 0.04);
    min-height: 180px;
    position: relative;
    overflow: hidden;
}
.skeleton-panel-tall { min-height: 260px; }
.skeleton-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(47, 196, 178, 0.08), transparent);
    animation: skeleton-shimmer 1.6s linear infinite;
}
@keyframes skeleton-shimmer {
    from { transform: translateX(-100%); }
    to { transform: translateX(100%); }
}

@media (max-width: 700px) {
    .panel { padding: 16.8px; }
    .hb-bars,
    .sky-row { gap: 2px; }
    .score-cards { grid-template-columns: minmax(0, 1fr); }
    .vis-cat, .sky-title { font-size: 28px; }
    .dive-score { font-size: 34px; }
    .dive-way { padding: 9px 8px 8px; }
    .dive-method { font-size: 12px; gap: 4px; }
    .dive-window { font-size: 11px; }
    .depth-panel { flex-direction: row; }
    .dash-row { gap: 11.2px; }
    .flow-legend { padding: 6px 8.4px; font-size: 11px; }
}

/* ── Spot map overlays: wind / current arrows (flow-layer.js) ─────────── */

.leaflet-marker-icon.flow-arrow { background: none; border: 0; pointer-events: none; }
.flow-arrow span,
.flow-legend-arrow {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    transform-origin: center;
}
.flow-arrow svg { filter: drop-shadow(0 0 2px rgba(6, 16, 21, 0.9)); }
.flow-arrow .flow-move,
.flow-arrow .flow-march { display: block; font-style: normal; }
.flow-arrow.is-wind { opacity: 0.7; }
.flow-arrow.is-current { opacity: 0.95; }

.flow-legend {
    display: grid;
    gap: 8.4px;
    padding: 8.4px 11.2px;
    border-radius: 8px;
    background: rgba(11, 26, 34, 0.88);
    box-shadow: var(--shadow-sm);
    font-size: 12px;
    line-height: 1.3;
}
.flow-legend small { color: var(--color-neutral-400); }
.flow-legend-row { display: flex; align-items: center; gap: 8.4px; }
.flow-legend-arrow { width: 22px; height: 22px; flex: none; }

/* ── Hawaii DOH Brown Water Advisory ──────────────────────────────────── */
.advisory-banner {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 12px 14px;
    border-radius: 10px;
    border: 1px solid #d9575a66;
    background: #d9575a1f;
    color: var(--color-text);
    font-size: 13px;
    line-height: 1.45;
}
.advisory-banner > i { color: #d9575a; font-size: 20px; flex-shrink: 0; }
.advisory-banner strong { color: #ef8a8c; }
.advisory-banner p { margin: 4px 0 0; color: var(--color-neutral-300); }
.advisory-banner a { color: #ef8a8c; white-space: nowrap; }
#plan-conditions .advisory-banner { margin-bottom: 10px; }

.bw-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 999px;
    border: 1px solid #d9575a66;
    background: #d9575a1f;
    color: #ef8a8c;
    font-size: 11px;
    line-height: 16px;
    vertical-align: 1px;
}

/* assets/css/map.css */
/* map.css — Screen 2, Option 2A (map + ranked list) and Leaflet theming. */

.map-screen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 16.8px;
    align-items: start;
}

.map-card {
    position: relative;
    isolation: isolate; /* keep the z-500 overlays below the header / tab bar */
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
#spots-map {
    position: relative; /* before Leaflet sets it: the island picture is placed inside */
    overflow: hidden;
    width: 100%;
    aspect-ratio: 4 / 3;
    background: radial-gradient(120% 100% at 30% 20%, #12303a, #08151b);
    touch-action: none;
}

/* The island's map as a picture until the live tiles cover it (layout.php, map-module.js). */
.map-placeholder {
    position: absolute;
    z-index: 0;
    max-width: none;
    pointer-events: none;
    user-select: none;
    transition: opacity 0.3s;
}
.map-placeholder.is-gone { opacity: 0; }

.map-legend {
    position: absolute;
    left: 11.2px;
    bottom: 11.2px;
    z-index: 500;
    display: flex;
    gap: 11.2px;
    flex-wrap: wrap;
    padding: 8.4px 11.2px;
    border-radius: 8px;
    background: rgba(11, 26, 34, 0.82);
    box-shadow: var(--shadow-sm);
}
.map-legend span {
    display: flex;
    align-items: center;
    gap: 5.6px;
    font-size: 11px;
    color: var(--color-neutral-300);
}
.map-legend i {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
}
/* The depth scale, on its own line under the spot colours (depth-layer.js depthLegendRow). */
.map-legend .depth-legend-row { flex-basis: 100%; }
.map-legend .depth-legend-row b { font-weight: 500; }
.map-legend .depth-legend-row i { width: 72px; height: 7px; border-radius: 4px; }
.map-legend .depth-legend-row small { font-size: 11px; color: var(--color-neutral-400); }

/* Contour numbers on the server-rendered depth tiles (depth-layer.js). */
.depth-tile-label {
    position: absolute;
    transform: translate(-50%, -50%);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    pointer-events: none;
    text-shadow: 0 0 3px var(--halo), 0 0 3px var(--halo), 0 0 2px var(--halo);
}

.map-top-right {
    position: absolute;
    right: 11.2px;
    top: 11.2px;
    z-index: 500;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
    pointer-events: none;
}
.map-top-right > * { pointer-events: auto; }
.map-methods {
    background: rgba(11, 26, 34, 0.88);
    backdrop-filter: blur(6px);
    box-shadow: var(--shadow-sm);
}
.map-methods .seg-opt {
    padding: 5.6px 9.6px;
    font-size: 12px;
    gap: 5px;
}
@media (pointer: coarse) {
    .map-methods .seg-opt { min-height: 36px; padding: 5.6px 8.4px; }
}

.map-conditions-pill {
    display: flex;
    align-items: center;
    gap: 5.6px;
    padding: 5.6px 11.2px;
    border-radius: 999px;
    background: rgba(11, 26, 34, 0.85);
    box-shadow: var(--shadow-sm);
    font-size: 12px;
}
.map-conditions-pill[hidden] { display: none; }
.map-conditions-pill .ph { color: var(--color-accent); }

/* ── Ranked list ───────────────────────────────────────────────────────── */
.spots-panel {
    padding: 16.8px 0;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.spots-panel-head {
    display: flex;
    align-items: center;
    gap: 11.2px;
    flex-wrap: wrap;
    padding: 0 16.8px 11.2px;
}
.spots-panel-head h6 { margin: 0; color: var(--color-neutral-400); }
.spots-panel-head .seg { margin-left: auto; }

.spots-list { max-height: 520px; overflow: auto; overscroll-behavior: contain; }
.spot-row {
    display: grid;
    grid-template-columns: 26px 1fr auto;
    gap: 11.2px;
    align-items: center;
    padding: 9px 16.8px;
    width: 100%;
    background: transparent;
    border: 0;
    font: inherit;
    color: var(--color-text);
    text-align: left;
    cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
    .spot-row:hover { background: rgba(233, 233, 237, 0.05); }
}
.spot-row:active { background: rgba(233, 233, 237, 0.1); }
.spot-row:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.spot-rank { font-size: 12px; color: var(--color-neutral-500); font-variant-numeric: tabular-nums; }
.spot-name { font-size: 14px; }
.spot-meta { font-size: 11px; color: var(--color-neutral-500); }
.spot-verdict { justify-self: end; }

/* ── Dark basemap via filter on plain OSM raster tiles ─────────────────── */
/* The pre-drawn island picture (layout.php) gets it from the theme, set before paint. */
.is-dark-map .leaflet-tile-pane,
html:not([data-theme="light"]) .map-placeholder {
    filter: invert(1) hue-rotate(180deg) brightness(0.92) contrast(0.9) saturate(0.8);
}

/* ── Leaflet chrome → tokens ───────────────────────────────────────────── */
/* isolation: Leaflet's panes/controls use z-index 400–1000; without their own
   stacking context they'd paint over the sticky header and the mobile tab
   bar (z 20/30) and swallow taps on it. */
.leaflet-container { background: transparent; font: inherit; isolation: isolate; }
.leaflet-bar a,
.leaflet-bar a:hover {
    background: var(--color-surface);
    color: var(--color-text);
    border-bottom-color: var(--color-divider);
}
.leaflet-bar {
    border: 1px solid var(--color-divider);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}
.leaflet-tooltip {
    background: var(--color-surface);
    border: 1px solid #3a4a4f;
    border-radius: 8px;
    color: var(--color-text);
    font-size: 12px;
    box-shadow: var(--shadow-md);
}
.leaflet-tooltip::before { display: none; }
.leaflet-control-attribution {
    background: rgba(11, 26, 34, 0.7) !important;
    color: var(--color-neutral-500) !important;
}
.leaflet-control-attribution a { color: var(--color-neutral-400) !important; }

/* Spot dot marker (divIcon). */
.spot-dot {
    display: block;
    border-radius: 50%;
}
.leaflet-marker-icon.spot-dot-wrap { background: none; border: 0; overflow: visible; }
/* Saved spot (saved-spots.js): a star on the dot's top-right edge. */
.pin-saved {
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    font-size: 12px;
    color: var(--color-caution);
    background: var(--color-bg);
    box-shadow: 0 0 0 2px var(--color-caution), 0 1px 4px 3px rgba(0, 0, 0, 0.35);
}
.spot-dot-star {
    position: absolute;
    top: -9px;
    right: -10px;
    font-size: 12px;
    color: var(--color-caution);
    text-shadow: 0 0 2px var(--color-bg), 0 0 2px var(--color-bg);
    pointer-events: none;
}

/* ── Spot view: the same map zoomed in, the day's cards in the list's place (app.js) ── */
.spot-view { min-width: 0; display: flex; flex-direction: column; gap: 16.8px; }
.spot-view[hidden] { display: none; }
.spot-view .dash-row,
.spot-view .score-cards { grid-template-columns: minmax(0, 1fr); }
.is-spot-view .map-top-right { display: none; }
/* The spot colours go; the depth scale stays (and the legend with it only when it has one). */
.is-spot-view .map-legend .legend-dot { display: none; }
.is-spot-view .map-legend:not(:has(.depth-legend-row)) { display: none; }
/* Neighbouring spots stay, faded and smaller, still tappable. */
#spots-map .spot-dot,
#spots-map .pin-saved { transition: opacity 0.3s, scale 0.3s; }
.is-spot-view #spots-map .spot-dot:not(.is-selected),
.is-spot-view #spots-map .pin-saved { opacity: 0.45; scale: 0.8; }
@media (min-width: 701px) {
    /* Wide screens: the map widens over the full width, the cards go under it in two
       columns (scores left, Read right), Timelines across both. */
    .is-spot-view .map-screen { grid-template-columns: minmax(0, 1fr); }
    .is-spot-view #spots-map { aspect-ratio: auto; height: min(52vh, 520px); min-height: 340px; }
    .spot-view .dash-stack,
    .spot-view .dashboard-skeleton { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; gap: 16.8px; }
    .spot-view .dash-stack > :not(.panel):not(.dash-row) { grid-column: 1 / -1; } /* notes and banners span both */
    .spot-view .skeleton-panel-tall { grid-row: span 2; }
    /* Read sits beside the scores. */
    .spot-view .dash-row { display: contents; }
}

@media (max-width: 700px) {
    .map-screen { grid-template-columns: minmax(0, 1fr); }
    .map-screen > * { min-width: 0; }
    #spots-map { aspect-ratio: 1 / 1; }
    .spots-list { max-height: none; overflow: visible; }
    /* Room for the rows before they arrive, so the footer isn't pushed down (a layout shift). */
    .spots-list:empty { min-height: 480px; }
}

/* Filled by app.js once it knows the depth scale; hidden until then. */
.map-legend:empty {
    display: none;
}

/* assets/css/charts.css */
/* charts.css — the "Timelines" disclosure on the dashboard. */

.timelines {
    margin-top: 16.8px;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.timelines[hidden] { display: none; }

.timelines > summary {
    list-style: none;
    cursor: pointer;
    padding: 16.8px 22.4px;
    display: flex;
    align-items: center;
    gap: 8.4px;
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-neutral-400);
}
.timelines > summary::-webkit-details-marker { display: none; }
.timelines > summary .ph { color: var(--color-accent); }
.timelines > summary::after {
    content: "";
    margin-left: auto;
    width: 7px;
    height: 7px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    transition: transform 200ms ease;
}
.timelines[open] > summary::after { transform: rotate(225deg); }

.chart-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16.8px;
    padding: 0 22.4px 22.4px;
}

.chart-box {
    border-radius: 8px;
    background: rgba(233, 233, 237, 0.03);
    box-shadow: var(--shadow-sm);
    padding: 16.8px;
}
.chart-box h3 {
    font-family: var(--font-heading);
    font-weight: 500;
    font-size: 13px;
    margin: 0 0 8.4px;
    color: var(--color-neutral-400);
}
.chart-canvas { position: relative; width: 100%; height: 220px; }

@media (min-width: 700px) {
    .chart-grid { grid-template-columns: 1fr 1fr; }
    .chart-canvas { height: 240px; }
}
@media (min-width: 1100px) {
    .chart-grid { grid-template-columns: 1fr 1fr 1fr; }
}

/* assets/css/plan.css */
/* plan.css — "Plan a dive" screen: the map first (drawing tools and a "what next" hint on it),
   then a panel with the day, the conditions summary, depth and Save (a sheet over the map's
   bottom edge on phones). */

.plan-screen {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(320px, 1fr);
    gap: 16.8px;
    align-items: start;
}
/* Grid items default to min-width:auto, so one wide child (the hourly
   grid) would stretch the whole column — and the map card — past the
   screen. Let them shrink; wide content scrolls inside its own box. */
.plan-screen > * { min-width: 0; }

/* ── Map card ──────────────────────────────────────────────────────────── */
#plan-map {
    width: 100%;
    height: min(76vh, 680px);
    min-height: 360px;
    background: radial-gradient(120% 100% at 30% 20%, #12303a, #08151b);
    touch-action: none;
}
#plan-map.is-drawing { cursor: crosshair; }
/* While drawing, clicks pass through existing shapes to the map. */
#plan-map.is-drawing path.leaflet-interactive { pointer-events: none; }
/* ...and through the entry/exit markers, so a route can start right on the entry point. */
#plan-map.is-drawing .leaflet-marker-icon.plan-point-wrap { pointer-events: none; }

/* The next step, as one line at the top of the map (clear of the zoom buttons and tools). */
.plan-guide {
    position: absolute;
    top: 10px;
    left: 54px;
    right: 66px;
    z-index: 600;
    width: fit-content;
    margin: 0 auto;
    padding: 8px 14px;
    border-radius: 999px;
    background: var(--color-accent);
    color: #0b1a22;
    box-shadow: var(--shadow-sm);
    font-size: 13.5px;
    font-weight: 600;
    text-align: center;
    pointer-events: none;
}
.plan-guide[hidden] { display: none; }

/* Drawing tools: a column of round buttons on the map's right edge. */
.plan-toolbar {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 600;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.plan-toolbar-gap { height: 6px; }
.plan-tool {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--color-divider);
    border-radius: 12px;
    background: rgba(11, 26, 34, 0.92);
    box-shadow: var(--shadow-sm);
    color: var(--color-text);
    font-size: 19px;
    cursor: pointer;
}
.plan-tool-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) {
    .plan-tool:hover:not(:disabled) { border-color: var(--color-accent); }
}
.plan-tool:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.plan-tool[aria-pressed="true"] { color: #0b1a22; background: var(--color-accent); border-color: var(--color-accent); }
.plan-tool:disabled { opacity: 0.45; cursor: not-allowed; }
/* The tool the hint points at (Entry, until there is one). */
.plan-tool.is-next { color: var(--color-accent); border: 2px solid var(--color-accent); }
html.motion-ready .plan-tool.is-next { animation: tool-next 1.8s var(--ease-out) infinite; }
@keyframes tool-next {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-accent) 55%, transparent); }
    70%, 100% { box-shadow: 0 0 0 10px transparent; }
}

/* "Done" for a route or zone being drawn: bottom centre, where the thumb is. */
.plan-finish {
    position: absolute;
    left: 50%;
    bottom: 76px; /* above the depth readout and legend */
    z-index: 600;
    transform: translateX(-50%);
    gap: 6px;
    border-color: var(--color-accent);
    background: var(--color-accent);
    color: #0b1a22;
    box-shadow: var(--shadow-md);
}
.plan-finish[hidden] { display: none; }

.plan-map-status {
    position: absolute;
    left: 54px;
    right: 66px;
    top: 56px;
    z-index: 500;
    width: fit-content;
    margin: 0 auto;
    padding: 5.6px 11.2px;
    border-radius: 999px;
    background: rgba(11, 26, 34, 0.88);
    box-shadow: var(--shadow-sm);
    font-size: 12px;
    text-align: center;
}
.plan-map-status[hidden] { display: none; }

/* Map overlays */
.depth-readout {
    padding: 4px 8.4px;
    border-radius: 6px;
    background: rgba(11, 26, 34, 0.85);
    box-shadow: var(--shadow-sm);
    color: var(--color-neutral-200);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}
/* Colour + halo come inline from the active depth palette. */
.leaflet-marker-icon.depth-label {
    background: none;
    border: 0;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    transform-origin: center;
}

.depth-legend {
    padding: 6px 8.4px 4px;
    border-radius: 8px;
    background: rgba(11, 26, 34, 0.85);
    box-shadow: var(--shadow-sm);
    color: var(--color-neutral-300);
    font-size: 11px;
}
.depth-legend-title { margin-bottom: 4px; letter-spacing: 0.04em; }
.depth-legend-scale { display: flex; }
.depth-legend-scale span { position: relative; display: block; width: 14px; padding-bottom: 12px; }
.depth-legend-scale i { display: block; height: 9px; }
/* Deeper than the last band: no tint, the map's own colour shows. */
.depth-legend-scale i.is-untinted { box-shadow: inset 0 0 0 1px var(--color-divider); }
.depth-legend-scale span:first-child i { border-radius: 3px 0 0 3px; }
.depth-legend-scale span:last-child i { border-radius: 0 3px 3px 0; }
.depth-legend-scale em {
    position: absolute;
    left: 0;
    bottom: 0;
    font-style: normal;
    color: var(--color-neutral-400);
    font-variant-numeric: tabular-nums;
}
.leaflet-marker-icon.plan-point-wrap { background: none; border: 0; }
.plan-point {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #0b1a22;
    border: 2px solid var(--c);
    color: var(--c);
    font-size: 15px;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--c) 25%, transparent);
}
/* Custom divIcons are targeted as .leaflet-marker-icon.<class>: passing a
   className to L.divIcon *replaces* the default .leaflet-div-icon class, so
   .leaflet-div-icon.<class> selectors never match. */
/* Vertex handles: the marker itself is the 18 px dot (centred by Leaflet's
   iconAnchor); ::before extends the grab area by 12 px all round (≈42 px touch target). Colours
   match ROLE_STYLE in dive-plan-map.js. No transforms here — Leaflet
   positions markers with transform, so scaling would fight it. */
.leaflet-marker-icon.plan-vertex {
    box-sizing: border-box;
    border-radius: 50%;
    background: var(--c);
    border: 3px solid #0b1a22;
    box-shadow: 0 0 0 1.5px var(--c), 0 1px 4px rgba(0, 0, 0, 0.6);
    cursor: grab;
    touch-action: none;
}
.leaflet-marker-icon.plan-vertex.is-route { --c: #aeece3; }
.leaflet-marker-icon.plan-vertex.is-zone { --c: #f6d860; }
.leaflet-marker-icon.plan-vertex::before {
    content: "";
    position: absolute;
    inset: -12px;
    border-radius: 50%;
}
.leaflet-marker-icon.plan-vertex.leaflet-drag-target {
    box-shadow: 0 0 0 2px var(--c), 0 0 0 5px rgba(255, 255, 255, 0.25), 0 1px 4px rgba(0, 0, 0, 0.6);
}
@media (hover: hover) and (pointer: fine) {
    .leaflet-marker-icon.plan-vertex:hover {
        box-shadow: 0 0 0 2px var(--c), 0 0 0 5px rgba(255, 255, 255, 0.25), 0 1px 4px rgba(0, 0, 0, 0.6);
    }
}
.leaflet-marker-icon.plan-vertex:active { cursor: grabbing; }
/* The point that finishes the draft: white centre + pulsing ring. */
.leaflet-marker-icon.plan-vertex.is-finish {
    background: #ffffff;
    box-shadow: 0 0 0 2px var(--c), 0 0 0 5px rgba(255, 255, 255, 0.35), 0 1px 4px rgba(0, 0, 0, 0.6);
    animation: vertex-pulse 1.4s ease-in-out infinite;
}
@keyframes vertex-pulse {
    50% { box-shadow: 0 0 0 2px var(--c), 0 0 0 8px rgba(255, 255, 255, 0.12), 0 1px 4px rgba(0, 0, 0, 0.6); }
}
.plan-popup { display: grid; gap: 5.6px; min-width: 120px; }
.plan-popup-info { font-size: 12px; color: var(--color-neutral-300); }
.plan-popup-delete { min-height: 28px; padding: 2px 10px; font-size: 12px; }
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-md);
}
.leaflet-popup-content { margin: 10px 14px; font-size: 13px; }
.leaflet-container a.leaflet-popup-close-button { color: var(--color-neutral-400); }

/* ── Panel ─────────────────────────────────────────────────────────────── */
.plan-panel {
    display: grid;
    /* Explicit shrinkable column: an implicit `auto` column grows to the
       widest child, so when the hourly grid loads it would widen the
       column and push the 100%-wide inputs out of the card. */
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    padding: 16.8px;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.plan-panel > * { min-width: 0; }
.plan-panel .field { margin: 0; }
.plan-panel .input { max-width: 100%; }
.plan-when {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 8.4px;
}
/* Native date/select controls have a wide intrinsic size; don't let it
   push the row wider than the card. */
.plan-when .input { min-width: 0; }
.plan-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8.4px;
    padding: 8.4px 11.2px;
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
    font-size: 13px;
}
.plan-banner[hidden] { display: none; }
.plan-banner .btn { margin-left: auto; }

.plan-block h3 {
    margin: 0 0 8.4px;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-neutral-400);
}
.plan-block .hint { margin: 6px 0 0; }

/* Conditions: the verdict for the planned hours, an hour strip, four facts. */
.plan-verdict {
    --v: var(--color-neutral-500);
    display: grid;
    gap: 12px;
    padding: 14px;
    border-radius: 14px;
    border: 1px solid var(--color-divider);
    background: color-mix(in srgb, var(--color-bg) 55%, var(--color-surface));
}
.plan-verdict.is-go { --v: var(--color-go); }
.plan-verdict.is-caution { --v: var(--color-caution); }
.plan-verdict.is-no_go { --v: var(--color-no-go-text); }
.plan-verdict-head { display: flex; align-items: center; gap: 12px; }
.plan-verdict-score {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--v) 16%, transparent);
    color: var(--v);
    font-family: var(--font-heading);
    font-size: 22px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.plan-verdict-text { display: grid; gap: 2px; min-width: 0; }
.plan-verdict-text strong { font-family: var(--font-heading); font-size: 18px; font-weight: 600; color: var(--v); }
.plan-verdict-text span { font-size: 13px; color: var(--color-neutral-300); }
.plan-verdict:not([class*="is-"]) .plan-verdict-text strong { color: var(--color-text); }

.plan-strip {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(34px, 1fr);
    gap: 5px;
    margin: 0;
    padding: 0 0 2px;
    list-style: none;
    overflow-x: auto;
}
.plan-strip-hour { --h: var(--color-neutral-700); display: grid; justify-items: center; gap: 4px; }
.plan-strip-hour.is-go { --h: var(--color-go); }
.plan-strip-hour.is-caution { --h: var(--color-caution); }
.plan-strip-hour.is-no_go { --h: var(--color-no-go); }
.plan-strip-hour b {
    display: grid;
    place-items: center;
    width: 100%;
    height: 32px;
    box-sizing: border-box;
    border-radius: 8px;
    background: color-mix(in srgb, var(--h) 28%, transparent);
    border: 2px solid transparent;
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.plan-strip-hour.is-best b { border-color: var(--h); }
.plan-strip-hour small { font-size: 11px; color: var(--color-neutral-400); font-variant-numeric: tabular-nums; }

.plan-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
    margin: 0;
}
.plan-facts div { padding: 9px 10px; border-radius: 10px; background: var(--color-surface); }
.plan-facts dt { font-size: 11.5px; color: var(--color-neutral-400); }
.plan-facts dd { margin: 2px 0 0; font-size: 13.5px; font-weight: 500; font-variant-numeric: tabular-nums; }

/* "Hour by hour": one line per condition, a column per planned hour. */
.plan-hourly { margin-top: 10px; }
.plan-hourly > summary,
.plan-more > summary {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    cursor: pointer;
    font-weight: 500;
    color: var(--color-accent);
    list-style: none;
}
.plan-hourly > summary::-webkit-details-marker,
.plan-more > summary::-webkit-details-marker { display: none; }
.plan-hourly > summary::after,
.plan-more > summary::after { content: "▾"; font-size: 12px; transition: rotate var(--dur-fast) var(--ease-out); }
.plan-hourly[open] > summary::after,
.plan-more[open] > summary::after { rotate: 180deg; }
.plan-hours-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
.plan-grid {
    width: 100%;
    border-collapse: separate;
    border-spacing: 3px;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
}
.plan-grid th,
.plan-grid td { padding: 6px 5px; text-align: center; white-space: nowrap; }
.plan-grid thead th { font-weight: 500; color: var(--color-neutral-500); font-size: 11px; }
.plan-grid thead th.is-best { color: var(--color-go); }
.plan-grid tbody th { text-align: left; font-weight: 600; padding-right: 8px; }
.plan-grid tbody th small { display: block; font-weight: 400; font-size: 10.5px; color: var(--color-neutral-500); }
.plan-grid td { border-radius: 6px; background: color-mix(in srgb, var(--color-bg) 55%, var(--color-surface)); }
.plan-grid td.dive-cell { font-weight: 600; }
.plan-grid td.dive-cell.is-go { background: color-mix(in srgb, var(--color-go) 22%, transparent); }
.plan-grid td.dive-cell.is-caution { background: color-mix(in srgb, var(--color-caution) 22%, transparent); }
.plan-grid td.dive-cell.is-no_go { background: color-mix(in srgb, var(--color-no-go) 24%, transparent); }

.plan-depth-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 5px 12px;
    margin: 0;
    font-size: 13px;
}
.plan-depth-list dt { color: var(--color-neutral-500); }
.plan-depth-list dd { margin: 0; font-variant-numeric: tabular-nums; }
.plan-profile { position: relative; height: 160px; margin-top: 10px; min-width: 0; overflow: hidden; }
.plan-profile[hidden] { display: none; }

.plan-more { display: grid; gap: 10px; }
.plan-more[open] { padding-bottom: 4px; }
.plan-more > summary { color: var(--color-text); }
.plan-more-hint { font-weight: 400; font-size: 12.5px; color: var(--color-neutral-400); }
.plan-more .field + .field { margin-top: 10px; }

.plan-actions { display: flex; flex-wrap: wrap; gap: 8.4px; }
.plan-actions .btn[hidden] { display: none; }
/* Save stays in reach while the panel scrolls. */
.plan-save-bar {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -16.8px;
    padding: 10px 16.8px;
    background: var(--color-surface);
    border-top: 1px solid var(--color-divider);
}
.plan-save-bar #plan-save { flex: 1 1 auto; justify-content: center; }
.plan-feedback { margin: 0; }
.plan-feedback.is-error { color: #f08a8a; }
.plan-panel > .hint { margin: 0; }

@media (max-width: 900px) {
    .plan-screen { grid-template-columns: minmax(0, 1fr); gap: 0; }
    #plan-map { height: 58vh; height: 58svh; min-height: 320px; }
    /* The panel is a sheet pulled up over the map's bottom edge. */
    .plan-panel {
        position: relative;
        z-index: 2;
        margin-top: -18px;
        border-radius: 20px 20px 14px 14px;
        box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.25);
    }
    .plan-panel::before {
        content: "";
        justify-self: center;
        width: 40px;
        height: 4px;
        margin: -6px 0 -4px;
        border-radius: 2px;
        background: var(--color-neutral-700);
    }
    /* The sheet covers the map's last 18 px: lift what sits on the bottom edge. */
    .plan-map-card .leaflet-bottom { bottom: 18px; }
    .plan-finish { bottom: 96px; }
}
@media (max-width: 700px) {
    .plan-panel { padding: 14px; gap: 12px; }
    .plan-save-bar { margin: 0 -14px; padding: 10px 14px; bottom: calc(57px + env(safe-area-inset-bottom)); }
    .plan-actions .btn { flex: 1 1 auto; justify-content: center; }
    /* Map overlays: keep the readout and legend from colliding. */
    .depth-readout { max-width: 52vw; font-size: 11px; }
    .depth-legend-scale span { width: 11px; }
}
@media (max-width: 420px) {
    .plan-when { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .plan-when .field:first-child { grid-column: 1 / -1; }
    .plan-guide { font-size: 13px; }
}

/* ── Plan in your account: calendar, reminders (plan-screen.js) ─────────── */
.plan-extra { display: grid; gap: 8px; margin-top: 8px; }
.plan-extra .btn { gap: 5.6px; }
.plan-reminders { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--color-neutral-300); }
.plan-reminders input { margin-top: 2px; }
.plan-keep { justify-self: start; gap: 5.6px; }
.account-row.is-past { opacity: 0.6; }
.plan-reminder-on { color: var(--color-caution); }

/* assets/css/week.css */
/* week.css — the Week screen (every spot × the next 7 days) and its day sheet. */

.week-panel {
    padding: 16.8px 0;
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.week-head { padding: 0 16.8px 11.2px; }
.week-head h6 { margin: 0 0 4px; color: var(--color-neutral-400); }
.week-panel .saved-copy-note { margin: 0 16.8px 11.2px; }
.week-empty { padding: 9px 16.8px; }

/* Seven columns don't fit a phone: the table scrolls sideways inside the
   card (never the page), with the spot names pinned on the left. */
.week-scroll {
    overflow-x: auto;
    overscroll-behavior-x: contain;
}
.week-table {
    width: 100%;
    min-width: 600px;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 12px;
}
.week-table th {
    padding: 5.6px 4px;
    font-weight: 500;
    color: var(--color-neutral-500);
    white-space: nowrap;
}
.week-table thead th { font-size: 11px; text-align: center; }
.week-table td { padding: 2px; }
.week-table .week-spot {
    position: sticky;
    left: 0;
    z-index: 1;
    padding-left: 16.8px;
    min-width: 96px;
    max-width: 120px;
    background: var(--color-surface);
    text-align: left;
    white-space: normal;
    font-size: 13px;
    color: var(--color-text);
}
.week-table thead .week-spot { font-size: 11px; color: var(--color-neutral-500); }
.week-table td:last-child { padding-right: 16.8px; }

.week-cell {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    width: 100%;
    min-width: 62px;
    padding: 6px 2px 5px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: rgba(233, 233, 237, 0.03);
    font: inherit;
    color: var(--color-text);
    cursor: pointer;
    transition: background 120ms ease-out, transform 120ms ease-out;
}
.week-cell b {
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.week-cell.is-go b { color: var(--color-go); }
.week-cell.is-caution b { color: var(--color-caution); }
.week-cell.is-no_go b { color: var(--color-no-go-text); }
.week-cell.is-unknown b { color: var(--color-neutral-500); }
.week-cell.is-go { background: #35b06a14; }
.week-cell.is-no_go { background: #d9575a0f; }
/* Go to dive with Excellent visibility: the days the push announces. */
.week-cell.is-great { border-color: #35b06a99; }
.week-mark { font-size: 12px; margin-right: 2px; vertical-align: 1px; }
.week-legend { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; margin-left: 4px; }
.week-legend .ph { vertical-align: -1px; }
.week-legend .is-go { color: var(--color-go); }
.week-legend .is-caution { color: var(--color-caution); }
.week-legend .is-no_go { color: var(--color-no-go-text); }
.week-vis { font-size: 11px; white-space: nowrap; }
.week-conf { font-size: 11px; color: var(--color-neutral-500); font-variant-numeric: tabular-nums; }
.week-bw {
    position: absolute;
    top: 3px;
    right: 4px;
    font-size: 11px;
    color: #c8915a;
}

/* Further ahead, less certain: the forecast fades with each day. */
.week-cell.lead-2 > * { opacity: 0.92; }
.week-cell.lead-3 > * { opacity: 0.85; }
.week-cell.lead-4 > * { opacity: 0.78; }
.week-cell.lead-5 > * { opacity: 0.7; }
.week-cell.lead-6 > * { opacity: 0.62; }

@media (hover: hover) and (pointer: fine) {
    .week-cell:hover { background: rgba(233, 233, 237, 0.08); }
}
.week-cell:active { background: rgba(233, 233, 237, 0.12); transform: scale(0.97); }
.week-cell:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

.is-stale .week-cell b,
.is-stale .week-vis { filter: grayscale(1); }

/* ── Day sheet ─────────────────────────────────────────────────────────── */
.day-sheet-date { margin: 2px 0 11.2px; font-size: 13px; color: var(--color-neutral-400); }
.day-sheet {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 9px 16.8px;
    margin: 0;
    font-size: 14px;
}
.day-sheet dt { color: var(--color-neutral-500); }
.day-sheet dd { margin: 0; }
.day-sheet-note {
    margin: 14px 0 0;
    padding: 8.4px 11.2px;
    border-radius: 8px;
    font-size: 12px;
    color: var(--color-neutral-300);
    background: color-mix(in srgb, #c8915a 14%, transparent);
}
.day-sheet-link { margin: 14px 0 0; font-size: 13px; }
.day-sheet-link a { color: var(--color-accent); }

/* assets/css/motion.css */
/*
 * motion.css — timing tokens, press feedback and the "appear" animations
 * (things that animate when they stop being [hidden]). Leaving, dragging and
 * measuring live in motion.js. Opening animations wait for html.motion-ready
 * so the first paint is still; base.css stops them all under
 * prefers-reduced-motion.
 */

:root {
    --ease-out: cubic-bezier(.22,.61,.36,1);
    --ease-in: cubic-bezier(.4,0,1,1);
    --ease-spring: cubic-bezier(.34,1.4,.64,1);
    --ease-sheet: cubic-bezier(.32,.72,0,1);
    --dur-fast: 140ms;
    --dur: 240ms;
    --dur-sheet: 380ms;
}

/* The old screen is lifted out of the flow while it slides away. */
.app-main { position: relative; }
.app-main.is-switching { overflow-x: clip; }

/* ── Press feedback: controls give a little under the finger ────────────── */
.btn, .context-chip, .plan-tool, .spot-row, .app-toast-close {
    transition: transform var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.btn:active:not(:disabled),
.context-chip:active,
.plan-tool:active:not(:disabled) { transform: scale(0.96); }
.spot-row:active { transform: scale(0.985); }
.seg-opt { transition: background-color var(--dur-fast) var(--ease-out); }

/* ── Tab bar: sliding indicator, filled + popping icon ──────────────────── */
/* Positioned for the indicator (phones: already fixed as the bottom bar). */
@media (min-width: 701px) {
    .screen-nav.seg { position: relative; }
}
.screen-nav .seg-opt[aria-selected="true"] { box-shadow: none; }
.screen-nav .seg-opt { transition: color var(--dur) var(--ease-out), background-color var(--dur-fast) var(--ease-out); }
.screen-nav .seg-opt .ph,
.screen-nav .seg-opt .ph-fill { transition: transform var(--dur-fast) var(--ease-out); }
.screen-nav .seg-opt:active .ph,
.screen-nav .seg-opt:active .ph-fill { transform: scale(0.86); }
html.motion-ready .screen-nav .seg-opt[aria-selected="true"] .ph-fill {
    animation: tab-pop 420ms var(--ease-spring);
}
@keyframes tab-pop {
    0% { transform: scale(0.8); }
    60% { transform: scale(1.15); }
    100% { transform: none; }
}

.tab-indicator {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--w, 0);
    transform: translateX(var(--x, 0));
    pointer-events: none;
}
.tab-indicator.is-live {
    transition: transform 380ms var(--ease-spring), width 380ms var(--ease-spring);
}
.tab-indicator::before {
    content: "";
    position: absolute;
    inset: 0;
    box-shadow: inset 0 0 0 1px var(--color-accent);
}
@media (max-width: 700px) {
    .tab-indicator::before {
        inset: 0 auto auto 50%;
        width: 32px;
        height: 3px;
        transform: translateX(-50%);
        border-radius: 0 0 3px 3px;
        background: var(--color-accent);
        box-shadow: 0 0 12px color-mix(in srgb, var(--color-accent) 60%, transparent);
    }
}

/* ── Things that appear ─────────────────────────────────────────────────── */
@keyframes fade-in { from { opacity: 0; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(6px); } }

html.motion-ready .form-error:not([hidden]),
html.motion-ready .context-feedback:not([hidden]),
html.motion-ready .net-status:not([hidden]),
html.motion-ready .empty-state:not([hidden]) {
    animation: rise-in var(--dur) var(--ease-out);
}
html.motion-ready .dashboard-skeleton:not([hidden]) { animation: fade-in 200ms var(--ease-out); }
html.motion-ready .map-conditions-pill:not([hidden]) { animation: pill-in 320ms var(--ease-spring); }
@keyframes pill-in { from { opacity: 0; transform: scale(0.8); } }

/* Analyze: the sparkle spins while the read is computed. */
.btn.is-busy:disabled { opacity: 0.8; cursor: progress; }
.btn.is-busy .ph { animation: spin 900ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Hour bars grow from the baseline (motion.js). */
.hour-bar { transform-origin: bottom; }

/* ── Dialogs: pop in on desktop, slide up as a sheet on phones ──────────── */
html.motion-ready .dialog-backdrop:not([hidden]) { animation: fade-in var(--dur) var(--ease-out); }
html.motion-ready .dialog-backdrop:not([hidden]) > .dialog {
    animation: dialog-in 300ms var(--ease-spring);
}
@keyframes dialog-in { from { opacity: 0; transform: scale(0.94) translateY(8px); } }
@media (max-width: 700px) {
    html.motion-ready .dialog-backdrop:not([hidden]) > .dialog {
        animation: sheet-up var(--dur-sheet) var(--ease-sheet);
    }
    /* The handle + title row drags the sheet (motion.js). */
    .dialog-head { touch-action: none; }
}
@keyframes sheet-up { from { transform: translateY(100%); } }

/* ── Toast: springs up; swipe it away ───────────────────────────────────── */
.app-toast { touch-action: none; }
html.motion-ready .app-toast:not([hidden]) { animation: toast-in 380ms var(--ease-spring); }
@keyframes toast-in { from { opacity: 0; translate: 0 24px; } }
html.motion-ready .install-card:not([hidden]) { animation: toast-in 420ms var(--ease-spring); }
/* Weather icons (sky.js): the sun turns and glows, clouds drift, rain falls,
   lightning flashes, fog slides. The small hourly icons keep the sun and the rain. */
@media (prefers-reduced-motion: no-preference) {
    .sky-icon .sky-rays { transform-box: fill-box; transform-origin: center; animation: sky-spin 10s linear infinite, sky-pulse 2.4s ease-in-out infinite; }
    .sky-icon .sky-sun { transform-box: fill-box; transform-origin: center; animation: sky-glow 4s ease-in-out infinite; }
    .sky-icon .sky-cloud { animation: sky-drift 6s ease-in-out infinite alternate; }
    .sky-icon .sky-cloud-back { animation-duration: 8s; animation-direction: alternate-reverse; }
    .sky-icon .sky-drop { animation: sky-fall 1.1s linear calc(var(--i, 0) * -0.37s) infinite; }
    .sky-icon .sky-bolt { animation: sky-flash 4.5s linear infinite; }
    .sky-icon .sky-fog { animation: sky-drift 5s ease-in-out infinite alternate; }
    .sky-icon.is-still .sky-cloud,
    .sky-icon.is-still .sky-fog { animation: none; }
}
/* Divability tiles: switching the way in grows/shrinks the hourly bars (dashboard.js). */
@media (prefers-reduced-motion: no-preference) {
    .hourly-chart .hour-bar { transition: height 0.45s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)), background-color 0.3s; }
    .hourly-chart .hb-peak { animation: hb-peak-in 0.4s 0.2s both; }
}
@keyframes hb-peak-in { from { opacity: 0; } }
@keyframes sky-spin { to { rotate: 360deg; } }
@keyframes sky-glow { 50% { scale: 1.12; opacity: 0.8; } }
@keyframes sky-pulse { 50% { scale: 1.18; } }
@keyframes sky-drift { from { translate: -2px 0; } to { translate: 2px 0; } }
@keyframes sky-fall { 0% { translate: 0 -5px; opacity: 0; } 25%, 70% { opacity: 1; } 100% { translate: -1.5px 7px; opacity: 0; } }
@keyframes sky-flash { 0%, 86%, 100% { opacity: 0.25; } 88%, 92% { opacity: 1; } 90% { opacity: 0.4; } }

/* Install button: springs up, sends out two soft rings, then its arrow
   gives a small "download" bob every few seconds. */
html.motion-ready .install-fab:not([hidden]) { animation: fab-in 520ms var(--ease-spring) backwards; }
.install-fab::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-accent) 55%, transparent);
}
html.motion-ready .install-fab:not([hidden])::after { animation: fab-ring 1.8s ease-out 700ms 2; }
html.motion-ready .install-fab:not([hidden]) .install-fab-icon .ph { animation: fab-bob 5s ease-in-out 1.6s infinite; }
@keyframes fab-in { from { opacity: 0; transform: translateY(18px) scale(0.85); } }
@keyframes fab-ring { 100% { box-shadow: 0 0 0 12px transparent; } }
@keyframes fab-bob {
    0%, 76%, 100% { transform: translateY(0); }
    82% { transform: translateY(3px); }
    88% { transform: translateY(-1px); }
    94% { transform: translateY(1.5px); }
}

/* ── Map markers ────────────────────────────────────────────────────────── */
html.motion-ready .spot-dot { animation: dot-in 320ms var(--ease-spring) backwards; }
@keyframes dot-in { from { opacity: 0; transform: scale(0.3); } }

.spot-dot.is-selected { position: relative; }
html.motion-ready .spot-dot.is-selected { animation: marker-drop 560ms var(--ease-spring) backwards; }
@keyframes marker-drop {
    0% { opacity: 0; transform: translateY(-28px) scale(0.6); }
    60% { opacity: 1; transform: translateY(2px) scale(1.08); }
    100% { transform: none; }
}
.spot-dot.is-selected::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid var(--dot);
    opacity: 0;
    animation: marker-pulse 2s var(--ease-out) 600ms infinite;
}
@keyframes marker-pulse {
    0% { opacity: 0.9; transform: scale(1); }
    100% { opacity: 0; transform: scale(3); }
}

/* A tap on the location picker leaves a ripple (map-module.js). */
.leaflet-marker-icon.tap-ripple-wrap { background: none; border: 0; pointer-events: none; }
.tap-ripple {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 2px solid var(--color-accent);
    animation: tap-ripple 600ms var(--ease-out) forwards;
}
@keyframes tap-ripple {
    from { opacity: 0.9; transform: scale(0.2); }
    to { opacity: 0; transform: scale(1); }
}

/* Wind / current arrows fade in after each pan. */
.flow-arrow > span { animation: fade-in 420ms var(--ease-out) backwards; }
/* Then each arrow drifts along its own direction (up = the way it points, before
   rotation) and fades, looping: moving air or water. Off under reduced motion,
   where the arrows simply stay put. */
@media (prefers-reduced-motion: no-preference) {
    .flow-arrow .flow-move { animation: flow-drift var(--flow-s, 2s) linear var(--flow-delay, 0s) infinite; }
    /* The current's chevrons light up tail to head, one after another. */
    .flow-arrow .flow-march path { animation: flow-march var(--flow-s, 3s) ease-in-out var(--flow-delay, 0s) infinite; }
    .flow-arrow .flow-march path:nth-child(2) { animation-delay: calc(var(--flow-delay, 0s) + var(--flow-s, 3s) / 6); }
    .flow-arrow .flow-march path:nth-child(3) { animation-delay: calc(var(--flow-delay, 0s) + var(--flow-s, 3s) / 3); }
}
@keyframes flow-drift {
    0% { transform: translateY(7px); opacity: 0; }
    20%, 75% { opacity: 1; }
    100% { transform: translateY(-9px); opacity: 0; }
}
@keyframes flow-march { 0%, 100% { opacity: 0.3; } 35% { opacity: 1; } }

/* ── Theme switch: the new theme is revealed as a circle growing from the toggle (theme.js) ── */
::view-transition-old(root),
::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
}
/* Looping animations hold still while the circle grows (theme.js). */
html.is-theme-switching *,
html.is-theme-switching *::before,
html.is-theme-switching *::after {
    animation-play-state: paused !important;
}
::view-transition-old(root) { z-index: 1; }
::view-transition-new(root) {
    z-index: 2;
    /* Ease in-out: at a phone's 10-20 fps a front-loaded curve covered the screen in
       two or three frames. Position and size come from theme.js. */
    animation: theme-reveal var(--reveal-ms, 1100ms) cubic-bezier(.45, 0, .25, 1) both;
}
@keyframes theme-reveal {
    from { clip-path: circle(0px at var(--reveal-x, 50%) var(--reveal-y, 0px)); }
    to { clip-path: circle(var(--reveal-r, 150vmax) at var(--reveal-x, 50%) var(--reveal-y, 0px)); }
}

/* Fallback without View Transitions: colours blend instead of snapping. */
html.is-theme-fading,
html.is-theme-fading *,
html.is-theme-fading *::before,
html.is-theme-fading *::after {
    transition: background-color 0.5s ease, color 0.5s ease, border-color 0.5s ease,
        fill 0.5s ease, stroke 0.5s ease, box-shadow 0.5s ease !important;
}

/* assets/css/light.css */
/* light.css — the light theme. Loaded after every other stylesheet; everything here applies only
   under <html data-theme="light"> (js/theme.js). Nocturne's dark tokens are the default; this
   file re-points the tokens at a light ground and fixes the few hard-coded dark colours. */

html[data-theme="light"] {
    color-scheme: light;

    --color-bg: #f1f6f6;
    --color-surface: #ffffff;
    --color-text: #10262c;
    --color-accent: #0b756a;
    --color-accent-2: #1a8d81;
    --color-divider: color-mix(in srgb, #10262c 16%, transparent);

    /* The neutral ramp mirrored: step 100 is the darkest ink, 900 the faintest tint. */
    --color-neutral-100: #10262c;
    --color-neutral-200: #26393f;
    --color-neutral-300: #3d5257;
    --color-neutral-400: #4e6469;
    --color-neutral-500: #5e7378;
    --color-neutral-600: #83979c;
    --color-neutral-700: #afc0c3;
    --color-neutral-800: #d0dcde;
    --color-neutral-900: #e4eded;

    --color-accent-100: #103a36;
    --color-accent-200: #185a53;
    --color-accent-300: #1f7f74;
    --color-accent-400: #128377;
    --color-accent-800: #aeece3;
    --color-accent-2-100: #1c3633;
    --color-accent-2-800: #c6e9e4;

    --color-go: #1f8a4c;
    --color-caution: #8a6500;
    --color-no-go: #c23b3f;
    --color-no-go-text: #b3282d;
    --sky-sun: #e6a817;
    --sky-cloud: #c4cadb;
    --sky-cloud-back: #9aa2bb;
    --sky-cloud-storm: #7b829c;
    --sky-rain: #0b7f93;

    --shadow-sm: 0 0 0 1px #d0dcde;
    --shadow-md: 0 0 0 1px #d0dcde, 0 6px 18px rgba(16, 38, 44, 0.12);
    --shadow-lg: 0 0 0 1px #afc0c3, 0 16px 40px rgba(16, 38, 44, 0.18);
}

/* Translucent overlays that were tinted for a dark ground. */
html[data-theme="light"] .app-header { background: color-mix(in srgb, #f1f6f6 92%, transparent); }
html[data-theme="light"] .score-card,
html[data-theme="light"] .week-cell,
html[data-theme="light"] .chart-box { background: rgba(16, 38, 44, 0.03); }
html[data-theme="light"] .skeleton-panel { background: rgba(16, 38, 44, 0.05); }
html[data-theme="light"] .spot-row:hover,
html[data-theme="light"] .week-cell:hover { background: rgba(16, 38, 44, 0.06); }
html[data-theme="light"] .spot-row:active,
html[data-theme="light"] .week-cell:active { background: rgba(16, 38, 44, 0.1); }
html[data-theme="light"] .verdict-chip.is-go { background: #1f8a4c1a; }
html[data-theme="light"] .verdict-chip.is-caution { background: #8a65001a; }
html[data-theme="light"] .verdict-chip.is-no_go { background: #c23b3f1a; }
html[data-theme="light"] .advisory-banner strong,
html[data-theme="light"] .advisory-banner a,
html[data-theme="light"] .bw-badge { color: #b3282d; }
html[data-theme="light"] .hour-bar { background: linear-gradient(180deg, #83979c, #5e7378); }
html[data-theme="light"] .week-bw { color: #8a5a2c; }
html[data-theme="light"] .plan-tool { background: rgba(255, 255, 255, 0.94); }
html[data-theme="light"] .plan-tool[aria-pressed="true"] { background: var(--color-accent); }
html[data-theme="light"] .plan-tool[aria-pressed="true"],
html[data-theme="light"] .plan-finish,
html[data-theme="light"] .plan-guide { color: #ffffff; }
html[data-theme="light"] .plan-feedback.is-error { color: #b3282d; }
html[data-theme="light"] .app-toast { box-shadow: 0 8px 28px rgba(16, 38, 44, 0.2); }
html[data-theme="light"] .install-card { box-shadow: 0 12px 36px rgba(16, 38, 44, 0.22); }
html[data-theme="light"] .install-fab {
    box-shadow: 0 6px 18px color-mix(in srgb, var(--color-accent) 30%, transparent), 0 2px 6px rgba(16, 38, 44, 0.18);
}
html[data-theme="light"] .install-fab-icon { background: color-mix(in srgb, #ffffff 18%, transparent); }
html[data-theme="light"] .dialog-backdrop { background: rgba(16, 38, 44, 0.4); }

/* Maps: the OSM tiles stay as they are (no darkening) on a pale ground, and the overlays on top
   of them go white. */
html[data-theme="light"] #spots-map,
html[data-theme="light"] #plan-map { background: #dfe6ef; }
html[data-theme="light"] .map-legend,
html[data-theme="light"] .map-methods,
html[data-theme="light"] .map-conditions-pill,
html[data-theme="light"] .flow-legend,
html[data-theme="light"] .plan-map-status,
html[data-theme="light"] .depth-readout,
html[data-theme="light"] .depth-legend { background: rgba(255, 255, 255, 0.9); color: #10262c; }
html[data-theme="light"] .leaflet-control-attribution { background: rgba(255, 255, 255, 0.75) !important; }
html[data-theme="light"] .leaflet-tooltip { border-color: #d0dcde; }
html[data-theme="light"] .depth-ruler { background: linear-gradient(#cfe3f1, #7fa4bf); }
html[data-theme="light"] .plan-point,
html[data-theme="light"] .leaflet-marker-icon.plan-vertex { border-color: #ffffff; }
html[data-theme="light"] .flow-arrow svg { filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.9)); }

/* Public/native bars follow the ground. */
@media (max-width: 700px) {
    html[data-theme="light"] .app-header { background: #f1f6f6; }
    html[data-theme="light"] .screen-nav.seg { background: color-mix(in srgb, #f1f6f6 96%, transparent); }
}

/* "Continue with Google": Google's light button. */
html[data-theme="light"] .btn-google { background: #fff; color: #1f1f1f; border-color: #747775; }
html[data-theme="light"] .btn-google:hover { background: #f7f8f8; }

