:root {
  --brand: #2a78d6;
  --brand-dark: #184f95;
  --aqua: #1baf7a;
  --ocean-900: #0a3d54;
  --ocean-700: #0f5c7a;

  --surface: #fcfcfb;
  --page-bg: #f6f5f0;
  --ink: #0b0b0b;
  --ink-secondary: #52514e;
  --ink-muted: #898781;
  --gridline: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.1);

  --area-fill: #cde2fb;
  --scanline-a: #f3f7fa;
  --scanline-b: #edf3f8;
  --glow: color-mix(in srgb, #3cc4ff 20%, transparent); /* light azure */

  /* Glowing "kit" look (from jet-boy), shared by boxes, search bars and region chips */
  --kit-radius: 10px;
  --kit-border: color-mix(in srgb, var(--brand) 35%, var(--border));
  --kit-bg: color-mix(in srgb, var(--surface) 70%, transparent);
  --kit-shadow:
    0 0 0 1px color-mix(in srgb, var(--brand) 10%, transparent),
    0 0 16px color-mix(in srgb, var(--brand) 15%, transparent),
    0 0 32px color-mix(in srgb, var(--brand) 8%, transparent);
  --kit-shadow-strong:
    0 0 0 1px color-mix(in srgb, var(--brand) 25%, transparent),
    0 0 16px color-mix(in srgb, var(--brand) 35%, transparent),
    0 0 32px color-mix(in srgb, var(--brand) 20%, transparent);

  --radius: 12px;
  --max-width: 1080px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --brand: #3987e5;
    --brand-dark: #86b6ef;
    --aqua: #199e70;
    --surface: #1a1a19;
    --page-bg: #0d0d0d;
    --ink: #ffffff;
    --ink-secondary: #c3c2b7;
    --ink-muted: #898781;
    --gridline: #2c2c2a;
    --baseline: #383835;
    --border: rgba(255, 255, 255, 0.1);
    --area-fill: #184f95;
    --scanline-a: #0e0d0e;
    --scanline-b: #171819;
    --glow: color-mix(in srgb, #3cc4ff 28%, transparent);
  }
}

/* Logo typeface, self-hosted so that no visitor IP is sent to Google (license: /fonts/LICENSE.txt) */
@font-face {
  font-family: "Special Elite";
  src: url("/fonts/special-elite-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Fine horizontal scanlines */
  background: repeating-linear-gradient(
    0deg,
    var(--scanline-a) 25%,
    var(--scanline-a) 50%,
    var(--scanline-b) 50%,
    var(--scanline-b) 75%
  );
  background-size: 10px 10px;
  color: var(--ink);
  line-height: 1.5;
}

/* Light blue glow rising from the bottom of the window, behind the content */
body::after {
  content: "";
  position: fixed;
  inset: auto 0 0 0;
  height: 35dvh;
  background: linear-gradient(to top, var(--glow), transparent);
  pointer-events: none;
  z-index: -1;
}

a {
  color: var(--brand-dark);
}

h1, h2, h3 {
  line-height: 1.2;
  margin: 0 0 0.5em;
}

main {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 16px 48px;
}

/* Header (all pages): site title on the left, search on the right, a thin line under both */

.site-header {
  border-bottom: 1px solid color-mix(in srgb, #3cc4ff 60%, transparent);
}

.site-header__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  flex-wrap: wrap;
}

/* An h1 on the homepage, a link elsewhere: both must look the same */
.site-logo {
  margin: 0;
  font-family: "Special Elite", system-ui, sans-serif;
  font-size: 1.65rem;
  font-weight: 400;
  line-height: 1.2;
  /* Special Elite's letters sit high in their line box: this centres the letters themselves */
  position: relative;
  top: 0.14em;
  text-shadow: 0 0 12px color-mix(in srgb, var(--brand) 60%, transparent);
  color: var(--ocean-900);
  text-decoration: none;
  white-space: nowrap;
}

@media (prefers-color-scheme: dark) {
  .site-logo {
    color: white;
  }
}

.header-search {
  position: relative;
  flex: 0 1 280px;
}

.header-search input {
  display: block;
  width: 100%;
  padding: 7px 12px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
  font-size: 0.9rem;
  color: var(--ink);
  transition: box-shadow 0.3s ease-in-out, border-color 0.3s ease-in-out;
}

/* Below 16px, iOS zooms the page when the field gets focus */
@media (pointer: coarse) {
  .header-search input {
    font-size: 1rem;
  }
}

/* Title and search don't fit on one row on a phone */
@media (max-width: 560px) {
  .header-search {
    flex-basis: 100%;
  }

  .header-search input {
    font-size: 1rem;
  }
}

.header-search input:hover {
  box-shadow: var(--kit-shadow-strong);
}

/* The stronger glow plus brand border is the focus indicator */
.header-search input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--kit-shadow-strong);
}

.header-search__results {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  /* Wider than the field, so that long port and region names stay on one line */
  width: min(380px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--kit-border);
  border-radius: var(--kit-radius);
  box-shadow: var(--kit-shadow-strong);
  max-height: 320px;
  overflow-y: auto;
  z-index: 20;
  padding: 6px;
}

.header-search__results a {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--ink);
}

.header-search__results a:hover,
.header-search__results a.is-active {
  background: var(--page-bg);
}

.header-search__results .region {
  flex-shrink: 0;
  color: var(--ink-muted);
  font-size: 0.85rem;
}

/* Hero (homepage) */

.hero {
  padding: 20px 0 20px;
}

/* Region map (homepage) */

.map-box {
  margin-bottom: 20px;
  padding: 16px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
}

.france-map {
  display: block;
  width: 100%;
  max-width: 520px;
  height: auto;
  margin: 0 auto;
}

.france-map__region {
  fill: color-mix(in srgb, var(--ink) 4%, transparent);
  stroke: color-mix(in srgb, var(--ink) 18%, transparent);
  stroke-width: 1;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.france-map__region--active {
  fill: color-mix(in srgb, var(--brand) 16%, transparent);
  stroke: color-mix(in srgb, var(--brand) 60%, var(--border));
  cursor: pointer;
  transition: fill 0.2s ease-in-out;
}

.france-map__link:hover .france-map__region--active,
.france-map__link:focus-visible .france-map__region--active {
  fill: color-mix(in srgb, var(--brand) 38%, transparent);
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand) 55%, transparent));
}

.france-map__link:focus {
  outline: none;
}

.france-map__label {
  font-size: 17px;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: middle;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--surface);
  stroke-width: 4px;
  stroke-linejoin: round;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease-in-out;
}

/* No hover on touch screens: keep the clickable regions named */
@media (hover: none) {
  .france-map__label {
    opacity: 1;
    font-size: 22px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Port directory */

.port-directory {
  display: grid;
  gap: 24px;
  margin-top: 16px;
}

/* Glowing box, adapted from jet-boy's Kit component */
.region-group {
  padding: 16px 20px 12px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
  transition: box-shadow 0.3s ease-in-out;
  scroll-margin-top: 16px;
  opacity: 0;
  animation: blink 1.2s ease-in-out forwards;
}

.region-group:hover {
  box-shadow: var(--kit-shadow-strong);
}

@media (prefers-reduced-motion: reduce) {
  .region-group {
    opacity: 1;
    animation: none;
  }
}

/* Neon flicker on appear */
@keyframes blink {
  0% { opacity: 0; }
  10% { opacity: 0.3; }
  15% { opacity: 0; }
  25% { opacity: 0.5; }
  30% { opacity: 0.2; }
  40% { opacity: 0.8; }
  50% { opacity: 1; }
  55% { opacity: 0.9; }
  60% { opacity: 1; }
  100% { opacity: 1; }
}

.region-group h2 {
  font-size: 1.1rem;
  color: var(--brand-dark);
  border-bottom: 2px solid var(--gridline);
  padding-bottom: 6px;
}

.port-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 24px;
}

@media (min-width: 720px) {
  .port-list {
    columns: 3;
  }
}

@media (min-width: 960px) {
  .port-list {
    columns: 4;
  }
}

.port-list li {
  padding: 4px 0;
  break-inside: avoid;
}

/* Homepage: one region at a time, picked on the map (`is-split` is set by home.js; without JS
   every region stays listed). Map above the list on small screens, side by side on wide ones. */
.home-layout.is-split .region-group:not(.is-selected) {
  display: none;
}

.france-map__link.is-selected .france-map__region--active {
  fill: color-mix(in srgb, var(--brand) 38%, transparent);
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand) 55%, transparent));
}

.france-map__label.is-selected {
  opacity: 1;
}

@media (min-width: 900px) {
  .home-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    align-items: start;
  }

  .home-layout .map-box {
    position: sticky;
    top: 16px;
    margin-bottom: 0;
  }

  .home-layout .port-directory {
    margin-top: 0;
  }

  .home-layout .port-list {
    columns: 2;
  }
}

/* Port hero */

.port-hero {
  padding: 24px 0 8px;
}

.port-hero h1 {
  font-size: 1.4rem;
  color: var(--ocean-900);
}

@media (prefers-color-scheme: dark) {
  .port-hero h1 {
    color: white;
  }
}

.port-hero__subtitle {
  color: var(--ink-secondary);
  margin: 0;
}

/* "Saint-Malo — jeudi 8 octobre [calendar]" + back-to-today button on other days */
.port-hero__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-bottom: 4px;
}

.port-hero__head h1 {
  margin: 0;
}

.date-control {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  margin-left: 10px;
}

.date-button {
  display: inline-flex;
  padding: 6px;
  border: 1px solid var(--kit-border);
  border-radius: var(--kit-radius);
  background: var(--kit-bg);
  color: var(--brand-dark);
  cursor: pointer;
  transition: box-shadow 0.2s ease-in-out;
}

.date-button:hover,
.date-button:focus-visible {
  box-shadow: var(--kit-shadow-strong);
}

/* The native date input stays in the page (showPicker needs it rendered) but invisible, under
   the button, so the browser's picker opens next to the icon. */
.date-control__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  border: 0;
  padding: 0;
}

.back-today {
  padding: 4px 12px;
  border-radius: 999px;
  font: inherit;
  font-size: 0.85rem;
  color: var(--brand-dark);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  cursor: pointer;
}

.back-today:hover,
.back-today:focus-visible {
  box-shadow: var(--kit-shadow-strong);
}

/* The tide curve and the beach schematic: side by side, or stacked when narrow */

.tide-panels {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin-bottom: 32px;
}

@media (min-width: 800px) {
  .tide-panels {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Tide curve */

.tide-curve,
.tide-scene {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}

/* Fixed heights: the server-rendered empty box and the curve drawn by port-page.js (at this size)
   take the same room, so there's no layout shift. */
.tide-curve__chart {
  height: 190px;
}

@media (min-width: 561px) {
  .tide-curve__chart {
    height: 240px;
  }
}

@media (min-width: 800px) {
  .tide-curve__chart {
    height: 260px;
  }
}

/* Beach schematic (drawn by tide-scene.js) */

.tide-scene {
  display: flex;
  flex-direction: column;
}

.tide-scene__status {
  min-height: 1.5em;
  margin: 0 0 8px;
  font-weight: 700;
  color: var(--ink-secondary);
}

/* Takes the room left in the box, to match the curve's height next to it */
.tide-scene__chart {
  position: relative;
  flex: 1;
  min-height: 150px;
  overflow: hidden;
  border-radius: 8px;
}

.tide-scene__svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.tide-scene__note {
  margin: 8px 0 0;
  font-size: 0.75rem;
  color: var(--ink-muted);
}

/* Painted at low resolution by tide-scene.js: each canvas pixel stays a sharp square */
.tide-scene__canvas {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  image-rendering: pixelated;
}

/* The labels sit on the painting: the same colours in light and dark mode */
.tide-scene__line {
  stroke: rgba(255, 255, 255, 0.75);
  stroke-width: 1;
  stroke-dasharray: 4 4;
}

.tide-scene__label,
.tide-scene__tag {
  fill: #fff;
  paint-order: stroke;
  stroke: rgba(12, 30, 36, 0.75);
  stroke-width: 3px;
  stroke-linejoin: round;
}

.tide-scene__label {
  font-size: 12px;
}

.tide-scene__tag {
  font-size: 13px;
  font-weight: 700;
}

.tide-curve__svg {
  display: block;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  /* Horizontal drags move the cursor readout; vertical swipes still scroll the page */
  touch-action: pan-y;
}

.tide-curve__area {
  fill: var(--area-fill);
  opacity: 0.6;
}

.tide-curve__line {
  fill: none;
  stroke: var(--brand);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.tide-curve__dot {
  stroke: var(--surface);
  stroke-width: 2;
}

.tide-curve__dot--high {
  fill: var(--brand);
}

.tide-curve__dot--low {
  fill: var(--aqua);
}

.tide-curve__label {
  font-size: 12px;
  fill: var(--ink-secondary);
}

.tide-curve__now {
  stroke: var(--ink-muted);
  stroke-width: 1;
  stroke-dasharray: 4 3;
}

.tide-curve__cursor {
  pointer-events: none;
}

.tide-curve__cursor-line {
  stroke: var(--brand);
  stroke-width: 1.5;
  opacity: 0.7;
}

.tide-curve__cursor-dot {
  fill: var(--brand);
  stroke: var(--surface);
  stroke-width: 2;
}

.tide-curve__cursor-label {
  font-size: 13px;
  font-weight: 700;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--surface);
  stroke-width: 5px;
  stroke-linejoin: round;
}

/* Day card (the curve of the day shown) */

.day-card {
  margin-bottom: 12px;
}

/* Footer */

.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 48px;
  padding: 24px 0;
  color: var(--ink-muted);
  font-size: 0.85rem;
}

.site-footer__inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 16px;
}

.site-footer__disclaimer {
  max-width: 640px;
}

.site-footer a {
  color: var(--ink-muted);
}

/* Legal pages */

.legal-page {
  max-width: 720px;
  padding: 24px 0;
}

.legal-page h2 {
  font-size: 1.15rem;
  margin-top: 1.8em;
  color: var(--brand-dark);
}

.legal-page__updated {
  margin-top: 2.5em;
  color: var(--ink-muted);
  font-size: 0.85rem;
}

/* 404 page */

.not-found {
  padding: 24px 0;
}

.not-found__regions {
  padding-left: 20px;
}

.not-found__regions li {
  padding: 4px 0;
}

/* Homepage: today's coefficients */

.coef-box {
  margin-top: 16px;
  padding: 12px 20px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 32px;
}

.coef-box h2 {
  font-size: 1rem;
  margin: 0;
}

.coef-box__days {
  display: flex;
  gap: 24px;
  margin: 0;
}

.coef-box__days div {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.coef-box__days dt {
  color: var(--ink-muted);
  font-size: 0.85rem;
}

.coef-box__days dd {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.coef-box__spring {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-muted);
}

/* Homepage: intro text under the map */

.home-about {
  margin-top: 40px;
  max-width: 72ch;
}

.home-about h2 {
  font-size: 1.2rem;
}

/* Port pages: tide times for the next days */

.forecast {
  margin-top: 32px;
}

.forecast h2,
.port-about h2 {
  font-size: 1.2rem;
}

.forecast__box {
  background: var(--kit-bg);
  border: 1px solid var(--kit-border);
  border-radius: var(--kit-radius);
  box-shadow: var(--kit-shadow);
  padding: 4px 16px;
}

.forecast__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.forecast__table th,
.forecast__table td {
  padding: 8px 8px 8px 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--gridline);
  font-weight: 400;
}

.forecast__table tbody tr:last-child th,
.forecast__table tbody tr:last-child td {
  border-bottom: 0;
}

.forecast__table thead th {
  color: var(--ink-muted);
  font-size: 0.8rem;
}

.forecast__table td {
  font-variant-numeric: tabular-nums;
}

.forecast__table td span {
  display: inline-block;
  margin-right: 14px;
}

/* Two tides a day don't fit side by side on a phone: stack them */
@media (max-width: 560px) {
  .forecast__box {
    padding: 4px 12px;
  }

  .forecast__table {
    font-size: 0.9rem;
  }

  .forecast__table td span {
    display: block;
    margin-right: 0;
  }
}

/* Port pages: "La marée à …" */

.port-about {
  margin-top: 32px;
  max-width: 72ch;
}

.port-about__warning {
  padding: 8px 12px;
  border-left: 3px solid var(--brand);
  background: color-mix(in srgb, var(--brand) 8%, transparent);
}

.port-about__note {
  font-size: 0.85rem;
  color: var(--ink-muted);
}

/* Port pages: nearby ports */

.nearby {
  margin-top: 32px;
}

.nearby h2 {
  font-size: 1.2rem;
}

.nearby__note {
  color: var(--ink-muted);
  font-size: 0.9rem;
}

.nearby__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px 24px;
}

@media (min-width: 640px) {
  .nearby__list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 980px) {
  .nearby__list {
    grid-template-columns: repeat(3, 1fr);
  }
}

.nearby__list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.nearby__distance {
  color: var(--ink-muted);
  font-size: 0.85rem;
}

.nearby__times {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
}

/* Port pages: the day's tides at a glance, above the curve */

.tide-summary {
  margin: 16px 0 20px;
}

.tide-summary__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

/* One row on wider screens, whatever the number of tides (3 or 4 in a day) */
@media (min-width: 640px) {
  .tide-summary__list {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
  }
}

.tide-summary__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 10px 13px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
  transition: opacity 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}

.tide-summary__type {
  font-size: 0.7rem;
  font-weight: 600;
}

.tide-summary__item--high .tide-summary__type {
  color: var(--brand-dark);
}

.tide-summary__item--low .tide-summary__type {
  color: var(--aqua);
}

.tide-summary__time {
  font-size: 1.45rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.tide-summary__level {
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.tide-summary__coef {
  font-size: 0.7rem;
  color: var(--ink-secondary);
}

.tide-summary__item.is-past {
  opacity: 0.45;
}

.tide-summary__item.is-next {
  border-color: color-mix(in srgb, var(--brand) 70%, var(--border));
  box-shadow: var(--kit-shadow-strong);
}

.tide-summary__item.is-next::after {
  content: "Prochaine";
  position: absolute;
  top: 8px;
  right: 10px;
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--brand-dark);
}

/* Narrow boxes: the top corner would touch "Basse mer", the bottom one is always free */
@media (max-width: 860px) {
  .tide-summary__item.is-next::after {
    top: auto;
    bottom: 8px;
  }
}

/* Port pages: "En direct – La mer monte !" (today only, set by port-page.js) */

.tide-live {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 1.5em;
  margin: 0 0 8px;
  font-weight: 700;
}

/* Hidden keeps its line, so showing it (or switching days) doesn't move the page */
.tide-live[hidden] {
  display: flex;
  visibility: hidden;
}

.tide-live--rising {
  color: var(--brand-dark);
}

.tide-live--falling {
  color: var(--aqua);
}

.tide-live__arrows {
  flex: none;
}

@media (prefers-reduced-motion: no-preference) {
  .tide-live--rising .tide-live__arrows {
    animation: tide-rise 1.4s ease-in-out infinite;
  }

  .tide-live--falling .tide-live__arrows {
    animation: tide-fall 1.4s ease-in-out infinite;
  }
}

.tide-live--falling .tide-live__arrows {
  transform: rotate(180deg);
}

@keyframes tide-rise {
  0% { transform: translateY(4px); opacity: 0.2; }
  50% { opacity: 1; }
  100% { transform: translateY(-4px); opacity: 0.2; }
}

/* Same motion, flipped: rotate first, so the translation is mirrored (moves down) */
@keyframes tide-fall {
  0% { transform: rotate(180deg) translateY(4px); opacity: 0.2; }
  50% { opacity: 1; }
  100% { transform: rotate(180deg) translateY(-4px); opacity: 0.2; }
}

/* Port pages: "La mer à …" map, in the homepage map's style */

.coast-map {
  margin-top: 32px;
}

.coast-map h2 {
  font-size: 1.2rem;
}

.coast-map__box {
  max-width: 560px;
  padding: 16px;
  border-radius: var(--kit-radius);
  border: 1px solid var(--kit-border);
  background: var(--kit-bg);
  box-shadow: var(--kit-shadow);
}

.coast-map__status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  min-height: 28px;
  font-size: 0.9rem;
}

.coast-map__live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  color: var(--brand-dark);
}

.coast-map__live[hidden] {
  display: none;
}

.coast-map__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 60%, transparent);
}

@media (prefers-reduced-motion: no-preference) {
  .coast-map__dot {
    animation: live-pulse 1.8s ease-out infinite;
  }
}

@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 60%, transparent); }
  100% { box-shadow: 0 0 0 8px transparent; }
}

.coast-map__label {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.coast-map__back {
  margin-left: auto;
  padding: 2px 10px;
  border-radius: 999px;
  font: inherit;
  font-size: 0.8rem;
  color: var(--brand-dark);
  border: 1px solid var(--kit-border);
  background: transparent;
  cursor: pointer;
}

.coast-map__back:hover,
.coast-map__back:focus-visible {
  box-shadow: var(--kit-shadow-strong);
}

/* Day timeline: mini tide curve with a native range input on top (mouse, touch and keyboard) */
.coast-timeline {
  position: relative;
  margin: 8px 0 12px;
}

.coast-timeline__curve {
  display: block;
  width: 100%;
  height: 40px;
}

.coast-timeline__area {
  fill: color-mix(in srgb, var(--brand) 12%, transparent);
}

.coast-timeline__line {
  fill: none;
  stroke: color-mix(in srgb, var(--brand) 70%, transparent);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.coast-timeline__marker {
  stroke: var(--brand);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

.coast-timeline__range {
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  height: 40px;
  margin: 0;
  background: transparent;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
}

.coast-timeline__range::-webkit-slider-runnable-track {
  height: 40px;
  background: transparent;
}

.coast-timeline__range::-moz-range-track {
  height: 40px;
  background: transparent;
}

.coast-timeline__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  margin-top: 13px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: var(--kit-shadow-strong);
}

.coast-timeline__range::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 0;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: var(--kit-shadow-strong);
}

.coast-timeline__range:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.coast-timeline__ticks {
  display: flex;
  justify-content: space-between;
  font-size: 0.7rem;
  color: var(--ink-muted);
}

/* Square map, reserved before the grid loads: no layout shift */
.coast-map__frame {
  position: relative;
  aspect-ratio: 1;
}

.coast-map__frame canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.coast-map__water {
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand) 45%, transparent));
}

.coast-map__north {
  position: absolute;
  top: 6px;
  right: 8px;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--ink-muted);
}

.coast-map__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  font-size: 0.85rem;
}

.coast-map__legend li {
  display: flex;
  align-items: center;
  gap: 6px;
}

.coast-map__swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

.coast-map__swatch--sea {
  background: color-mix(in srgb, var(--brand) 40%, transparent);
  border: 1px solid var(--brand);
}

.coast-map__swatch--foreshore {
  background: color-mix(in srgb, var(--ink) 10%, transparent);
}

.coast-map__swatch--coast {
  height: 0;
  border-top: 2px solid color-mix(in srgb, var(--ink) 35%, transparent);
}

.coast-map__note {
  max-width: 72ch;
  font-size: 0.8rem;
  color: var(--ink-muted);
}
