/* Surf Check: the eight-spot pilot selector.

   The :root block below is byte-identical to spot-detail.css's. Two pages with
   no build step cannot share a partial without a third asset route, so the
   palette is duplicated and pinned instead: tests/test_pwa_surf_check.py fails
   if the two blocks drift, which is the failure duplication actually risks. */
:root {
  color-scheme: light;
  --ink: #10282a;
  --ink-soft: #4f6564;
  --paper: #f4f1e9;
  --white: #fffdf8;
  --line: #d6d8ce;
  --sea: #0f5555;
  --sea-dark: #0d2729;
  --foam: #b9e6d4;
  --sun: #f5ad58;
  --warning: #c26a2f;
  --error: #a44335;
  --caveat: #5f6b75;
  --info: #2d6f74;
  --safe-inline: max(18px, env(safe-area-inset-left));
  --radius: 18px;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", sans-serif;
  font-synthesis: none;
}

* {
  box-sizing: border-box;
}

html {
  /* Re-measured from the header on every resize, by the trackHeaderHeight()
     that spot-detail.js also carries. The value here is only what holds
     before the first measurement. Kept out of :root, which is the palette
     the two stylesheets duplicate byte for byte. */
  --header-height: 58px;
  background: var(--paper);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
}

body {
  min-width: 320px;
  margin: 0;
  background:
    radial-gradient(circle at 92% 3%, rgba(185, 230, 212, 0.5), transparent 20rem),
    var(--paper);
}

button,
summary {
  font: inherit;
}

.skip-link {
  position: fixed;
  z-index: 20;
  top: 8px;
  left: 8px;
  padding: 9px 12px;
  border-radius: 8px;
  background: var(--white);
  color: var(--ink);
  transform: translateY(-150%);
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  position: sticky;
  z-index: 10;
  top: 0;
  display: flex;
  min-height: 58px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: max(10px, env(safe-area-inset-top)) var(--safe-inline) 10px;
  background: rgba(13, 39, 41, 0.96);
  color: #f6f2e8;
  backdrop-filter: blur(14px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: inherit;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-decoration: none;
}

.brand-mark {
  display: inline-block;
  width: 25px;
  height: 33px;
}

.brand-mark svg {
  display: block;
  width: 100%;
  height: 100%;
}

.roster-chip {
  padding: 6px 9px;
  border: 1px solid rgba(255, 255, 255, 0.23);
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.state-panel {
  display: grid;
  min-height: calc(100svh - 58px);
  place-content: center;
  justify-items: center;
  padding: 36px var(--safe-inline);
  text-align: center;
}

.state-panel[hidden],
#surf-check-view[hidden],
.roster-chip[hidden],
.spot-group[hidden] {
  display: none;
}

.loading-mark {
  width: 38px;
  height: 38px;
  border: 2px solid var(--line);
  border-top-color: var(--sea);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.error-panel {
  max-width: 34rem;
  margin-inline: auto;
}

.error-panel h1 {
  max-width: 14ch;
  margin: 8px 0 12px;
  font-size: clamp(2rem, 9vw, 3.6rem);
  line-height: 0.96;
}

.error-panel > p:not(.eyebrow) {
  max-width: 44ch;
  color: var(--ink-soft);
  line-height: 1.55;
}

.retry-button {
  min-height: 44px;
  margin-top: 12px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: var(--sea-dark);
  color: white;
  font-weight: 750;
}

.eyebrow {
  margin: 0;
  color: var(--sea);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1.35;
  text-transform: uppercase;
}

.retry-button:focus-visible,
.coast-toggle:focus-visible,
.shore-tab:focus-visible,
.save-button:focus-visible,
.spot-open:focus-visible,
.preview-week:focus-visible {
  outline: 3px solid var(--sun);
  outline-offset: 2px;
}

.check-hero {
  padding: 22px var(--safe-inline) 8px;
}

.check-hero h1 {
  margin: 6px 0 10px;
  font-size: clamp(2.2rem, 11vw, 3.4rem);
  line-height: 0.95;
}

.offline-note {
  max-width: 46ch;
  margin: 0 0 4px;
  padding-left: 10px;
  border-left: 3px solid var(--caveat);
  color: var(--ink-soft);
  font-size: 0.76rem;
  line-height: 1.45;
}

.offline-note[hidden] {
  display: none;
}


.spot-group {
  padding: 10px var(--safe-inline) 6px;
}

.local-group .group-heading h2 {
  color: var(--sea);
}

.local-region + .local-region {
  margin-top: 14px;
}

/* Lighter than the roster's region heading below it: this is a subdivision of
   The Local, not another top-level group, and it carries no collapse control
   to line a caret up against. */
.local-region-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 9px;
  padding-bottom: 6px;
}

.local-region-heading h3 {
  margin: 0;
  color: var(--sea);
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.01em;
}

.local-empty {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
}

.group-heading {
  display: flex;
  width: 100%;
  min-height: 44px;
  align-items: baseline;
  gap: 9px;
  padding: 0 0 8px;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
}

.group-heading h2 {
  margin: 0;
  flex: 1;
  font-size: 1.35rem;
}

.group-note {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.76rem;
}

.spot-list[hidden] {
  display: none;
}

.spot-list-rows {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 10px;
  grid-template-columns: minmax(0, 1fr);
  list-style: none;
}

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

/* Every box between the card and the scroller opts out of min-width:auto.
   Without that the preview's natural width wins, the card grows past the
   column, and the row that was supposed to scroll pushes the page sideways
   instead. */
.spot-row {
  min-width: 0;
  padding: 14px 14px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
}

.spot-head {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.spot-open {
  display: inline-flex;
  min-width: 0;
  min-height: 44px;
  flex: 1;
  align-items: center;
  gap: 9px;
  color: var(--ink);
  text-decoration: none;
}

.spot-name {
  overflow-wrap: anywhere;
  font-size: 1.02rem;
  font-weight: 750;
}

.spot-freshness {
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.spot-freshness.fresh {
  border-color: rgba(44, 138, 120, 0.5);
  color: #2c8a78;
}

.spot-freshness.aging,
.spot-freshness.stale {
  border-color: rgba(194, 106, 47, 0.5);
  color: var(--warning);
}

/* Deliberately not one of the three freshness accents. `offline` says where an
   answer came from, not how old the record is, and reading as either of those
   would be the confusion this exists to prevent. */
.spot-freshness.offline {
  border-color: rgba(95, 107, 117, 0.5);
  color: var(--caveat);
}

.save-button {
  min-height: 44px;
  padding: 0 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font-size: 0.82rem;
  font-weight: 750;
}

.save-button[aria-pressed="true"] {
  border-color: var(--sea-dark);
  background: var(--sea-dark);
  color: var(--white);
}

/* Axis beside the scroller, not inside it, so the scale stays on screen while
   the week scrolls under it. Both halves read the same two custom properties,
   so the ticks cannot drift off the bars. */
/* Axis beside the week, not inside it, so the scale is always on screen.
   The axis is anchored to the BOTTOM of the row rather than offset from the
   top: the day label and the arrow above each bar both sit between the top of
   the row and the baseline, and an offset that tried to account for them would
   have to be re-measured every time either changed. */
.preview-plot {
  /* Taller than the numbers strictly need. The scale stays zero-based and
     roster-wide -- truncating the axis would exaggerate differences that are
     not there -- so height is the honest way to make a real difference
     between two hours visible. */
  --preview-bar-height: 86px;
  --preview-label-row: 15px;
  display: grid;
  gap: 8px;
  grid-template-columns: auto minmax(0, 1fr);
  padding-top: 10px;
}

/* The ticks are absolutely positioned so each sits at its own height, which
   means they add nothing to the column's intrinsic width and an `auto` track
   would collapse to zero, putting every label off the left edge. The column is
   reserved explicitly. */
.preview-axis {
  position: relative;
  min-width: 1.5rem;
  height: var(--preview-bar-height);
  align-self: end;
  /* Clears the per-bar labels, which sit below the baseline the ticks are
     measured from. */
  margin-bottom: var(--preview-label-row);
}

.preview-tick {
  position: absolute;
  right: 0;
  bottom: var(--at);
  color: var(--ink-soft);
  font-size: 0.58rem;
  font-weight: 700;
  transform: translateY(50%);
  white-space: nowrap;
}

/* Four days fill the row and the remaining three scroll in behind them.
   Seven at once fit, but only by making each bar too thin to compare against
   the next; four is the most that stays legible at phone width. */
.preview-week {
  display: flex;
  min-width: 0;
  overflow-x: auto;
  /* A rotated arrow's bounding box is wider than the mark it sits in, so the
     end arrows need a little room or the row is left fractionally scrollable
     by glyphs that are not actually out of place. */
  padding-inline: 3px;
  gap: 4px;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.preview-week::-webkit-scrollbar {
  display: none;
}

.preview-day {
  display: grid;
  /* A quarter of the row, less its share of the three gaps between the four
     visible days. Fixed rather than flexible: days five to seven have to sit
     off the edge at the same width, not be squeezed in beside the others. */
  flex: 0 0 calc((100% - 12px) / 4);
  min-width: 0;
  /* An auto track would take its floor from the day label, which is wider than
     a day of bars needs to be. */
  grid-template-columns: minmax(0, 1fr);
  gap: 5px;
  justify-items: center;
  scroll-snap-align: start;
}

/* A day the cycle owes. Faded and dashed so it reads as still arriving rather
   than as a day with no surf -- an empty column and a flat day must not look
   alike. */
.preview-day.unpublished {
  opacity: 0.55;
}

.preview-day.unpublished .preview-daylabel {
  font-style: italic;
}

.preview-mark.unpublished .preview-bar {
  border-top: 1px dashed var(--ink-soft);
  background: none;
}

.preview-daylabel {
  overflow: hidden;
  max-width: 100%;
  color: var(--ink-soft);
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Stretched by the grid rather than sized at width:100%. A percentage width
   inside a fractional track rounds up, and seven of those roundings are enough
   to push the week over its own container. */
.preview-marks {
  position: relative;
  display: flex;
  justify-self: stretch;
  gap: 2px;
}

/* Gridlines on the same interval as the ticks, drawn in a box that is exactly
   the bar height so they land on the tick values rather than near them. */
.preview-marks::before {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: var(--preview-bar-height);
  background-image:
    linear-gradient(to top, rgba(15, 85, 85, 0.11) 1px, transparent 1px);
  background-position: left bottom;
  background-size: 100% calc(100% / 3);
  content: "";
  pointer-events: none;
}

.preview-mark {
  --wind-accent: #8e9b96;
  display: grid;
  flex: 1 1 0;
  min-width: 0;
  /* Both tracks may shrink below their content. Otherwise the arrow glyph sets
     a floor on the mark, the floor sets one on the day, and seven days of it
     push the week back into scrolling -- which is the thing the row is
     supposed to avoid. */
  grid-template-columns: minmax(0, 1fr);
  align-content: end;
  gap: 5px;
}

/* Above the arrow it describes. Two stacked lines rather than "12 avg." on
   one: four visible days leave each mark about 27px of pitch, and one line
   would either wrap unpredictably or force the week back into scrolling. */
.preview-wind {
  display: grid;
  overflow: hidden;
  width: 100%;
  /* Same floor-breaking as the mark above it: without minmax(0, 1fr) and
     min-width, these two words set an intrinsic width on the mark, the mark
     sets one on the day, and seven days of it take the room back off the spot
     name and the height labels. */
  min-width: 0;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  justify-items: center;
  line-height: 1;
}

.preview-wind-speed,
.preview-wind-avg {
  overflow: hidden;
  max-width: 100%;
  white-space: nowrap;
}

/* Ink, not the wind accent. The arrow carries the colour; at this size the
   side-onshore yellow against the card would not be readable as text. */
.preview-wind-speed {
  color: var(--ink);
  font-size: 0.6rem;
  font-weight: 800;
}

.preview-wind-avg {
  color: var(--ink-soft);
  font-size: 0.48rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.preview-arrow {
  position: relative;
  width: 100%;
  /* Four visible days give each mark roughly 27px of pitch, so the arrow can
     be sized to read rather than squeezed to fit. Its rotated diagonal is its
     widest measurement and is what the pitch has to cover. */
  height: 22px;
  overflow: visible;
  transform: rotate(var(--direction, 0deg));
}

/* Head. */
.preview-arrow::before {
  position: absolute;
  top: 0;
  left: 50%;
  width: 0;
  height: 0;
  border-right: 7px solid transparent;
  border-bottom: 11px solid var(--wind-accent);
  border-left: 7px solid transparent;
  content: "";
  transform: translateX(-50%);
}

/* Shaft. */
.preview-arrow::after {
  position: absolute;
  top: 10px;
  left: 50%;
  width: 4.5px;
  height: 12px;
  background: var(--wind-accent);
  content: "";
  transform: translateX(-50%);
}

/* No bearing published: a dot, which is not a direction and must not look
   like one. */
.preview-arrow.no-direction::before {
  top: 7px;
  width: 8px;
  height: 8px;
  border: 0;
  border-radius: 50%;
  background: var(--wind-accent);
}

.preview-arrow.no-direction::after {
  display: none;
}

.preview-arrow.offshore {
  --wind-accent: #2c8a78;
}

.preview-arrow.side-offshore {
  --wind-accent: #3a7ba8;
}

.preview-arrow.cross-shore {
  --wind-accent: #7f8c88;
}

.preview-arrow.side-onshore {
  --wind-accent: #d4a72c;
}

.preview-arrow.onshore {
  --wind-accent: #d9772f;
}

.preview-bar {
  position: relative;
  width: 100%;
  height: var(--preview-bar-height);
  border-radius: 4px;
}

.preview-label {
  overflow: hidden;
  width: 100%;
  color: var(--ink);
  font-size: 0.64rem;
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.preview-mark.bar .preview-bar::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: var(--bar-height, 0%);
  min-height: 2px;
  border-radius: 4px 4px 2px 2px;
  background: linear-gradient(var(--sea) 0%, #2c8a78 100%);
  content: "";
}

/* Flat is a completed answer, so it gets a drawn baseline. Absent gets a
   dashed one. They must not look like the same thing. */
.preview-mark.flat .preview-bar {
  background: linear-gradient(var(--sea-dark) 0 0) bottom / 100% 3px no-repeat;
}

.preview-mark.shadowed .preview-bar {
  background:
    repeating-linear-gradient(135deg, rgba(95, 107, 117, 0.35) 0 4px, transparent 4px 8px)
    bottom / 100% 12px no-repeat;
}

.preview-mark.absent .preview-bar {
  background: repeating-linear-gradient(90deg, var(--line) 0 3px, transparent 3px 6px)
    bottom / 100% 2px no-repeat;
}

.spot-quality {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: 0.74rem;
}

.spot-unavailable {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  margin: 10px 0 4px;
  gap: 8px;
  color: var(--ink-soft);
  font-size: 0.82rem;
  line-height: 1.45;
}

.unavailable-code {
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--warning);
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.spot-unavailable.damaged .unavailable-code,
.spot-unavailable.refused .unavailable-code {
  color: var(--error);
}

/* Directly under the row's bars, because that is where the arrows it explains
   are. Sized to sit quietly: it is a key, not a second heading. */
.wind-legend {
  display: flex;
  flex-wrap: wrap;
  margin: 7px 0 0;
  padding: 0;
  gap: 3px 9px;
  color: var(--ink-soft);
  font-size: 0.53rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  list-style: none;
  text-transform: uppercase;
}

.wind-legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.wind-legend-item::before {
  width: 0;
  height: 0;
  border-right: 3.5px solid transparent;
  border-bottom: 7px solid var(--wind-accent);
  border-left: 3.5px solid transparent;
  content: "";
}

.wind-legend-item.offshore {
  --wind-accent: #2c8a78;
}

.wind-legend-item.side-offshore {
  --wind-accent: #3a7ba8;
}

.wind-legend-item.cross-shore {
  --wind-accent: #7f8c88;
}

.wind-legend-item.side-onshore {
  --wind-accent: #d4a72c;
}

.wind-legend-item.onshore {
  --wind-accent: #d9772f;
}

.preview-legend {
  padding: 18px var(--safe-inline) calc(30px + env(safe-area-inset-bottom));
}

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

.legend-item {
  display: grid;
  gap: 2px;
  grid-template-columns: 5.5rem minmax(0, 1fr);
}

.legend-term {
  color: var(--ink);
  font-size: 0.76rem;
  font-weight: 800;
}

.legend-meaning {
  color: var(--ink-soft);
  font-size: 0.78rem;
  line-height: 1.45;
}

/* Primary navigation. Shared with The Search; see search.css. */
.site-nav { display: flex; gap: 4px; }
.nav-link {
  display: inline-block;
  padding: 7px 12px;
  border-radius: 999px;
  color: var(--foam);
  font-size: 0.8rem;
  font-weight: 600;
  text-decoration: none;
}
.nav-link-current {
  background: var(--sea);
  color: var(--white);
}

/* RIG-174. The page opens as a grid of coasts. A card is a real button that
   says how many spots it holds and today's best Surf Rating on it, and an open
   card spans the row with its shores as tabs. */
.coast-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 158px), 1fr));
  gap: 10px;
  padding: 10px var(--safe-inline) 18px;
}

.coast-card {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  scroll-margin-top: calc(var(--header-height) + 10px);
}

.coast-card.open {
  grid-column: 1 / -1;
  border-color: var(--sea-dark);
  box-shadow: 0 10px 26px rgba(13, 39, 41, 0.1);
}

.coast-toggle {
  display: grid;
  width: 100%;
  min-height: 112px;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: start;
  gap: 4px 10px;
  padding: 14px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: left;
}

.coast-card.open .coast-toggle {
  position: sticky;
  z-index: 4;
  top: var(--header-height);
  min-height: 0;
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--white);
}

.coast-toggle::after {
  grid-column: 2;
  grid-row: 1;
  width: 9px;
  height: 9px;
  margin-top: 6px;
  border-right: 2px solid var(--sea);
  border-bottom: 2px solid var(--sea);
  content: "";
  transform: rotate(45deg);
  transition: transform 220ms ease;
}

.coast-card.open .coast-toggle::after {
  transform: rotate(-135deg);
}

.coast-title {
  display: grid;
  grid-column: 1;
  grid-row: 1;
  gap: 2px;
  min-width: 0;
}

.coast-group {
  color: var(--sea);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.coast-title h2 {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.1;
  overflow-wrap: anywhere;
}

.coast-count {
  grid-column: 1 / -1;
  color: var(--ink-soft);
  font-size: 0.74rem;
}

.coast-best {
  grid-column: 1 / -1;
  color: var(--ink);
  font-size: 0.74rem;
  font-weight: 700;
}

/* RIG-177. The coast card takes the colour of today's best Surf Rating on that
   coast. The accents are the spot page's four hue bands, duplicated because a
   no-build PWA shares no partial, and pinned against it. The card itself is a
   38% tint of the accent over the white, precomputed so its contrast is fixed:
   dark ink stays at 8.5:1 or better on all eight and the sea eyebrow at 4.7:1,
   so a rated card sets its secondary text in ink, where the softer grey would
   fall to 3.4:1. The name on the card carries the rating; the colour repeats. */
.rating-rank-1 {
  --rating-accent: #85a0df;
  --rating-card: #d1daee;
}

.rating-rank-2 {
  --rating-accent: #5b7fd6;
  --rating-card: #c1cdeb;
}

.rating-rank-3 {
  --rating-accent: #5ab69e;
  --rating-card: #c0e2d6;
}

.rating-rank-4 {
  --rating-accent: #139a7f;
  --rating-card: #a5d7ca;
}

.rating-rank-5 {
  --rating-accent: #00785f;
  --rating-card: #9ecabe;
}

.rating-rank-6 {
  --rating-accent: #cf8a14;
  --rating-card: #edd1a1;
}

.rating-rank-7 {
  --rating-accent: #ad6700;
  --rating-card: #e0c49a;
}

.rating-rank-8 {
  --rating-accent: #b8397e;
  --rating-card: #e4b3ca;
}

.coast-card.rated {
  border-color: var(--rating-accent);
  border-left: 6px solid var(--rating-accent);
  background: var(--rating-card);
}

.coast-card.rated .coast-count {
  color: var(--ink);
}

.coast-card.rated.open .coast-toggle {
  background: var(--rating-card);
}

.coast-card.rated .coast-body {
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--white);
}

.coast-body {
  display: grid;
  gap: 10px;
  padding: 10px 12px 14px;
}

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

.shore-tabs {
  display: flex;
  overflow-x: auto;
  gap: 6px;
  scrollbar-width: none;
}

.shore-tabs::-webkit-scrollbar {
  display: none;
}

.shore-tab {
  flex: none;
  min-height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink-soft);
  font-size: 0.8rem;
  font-weight: 700;
  white-space: nowrap;
}

.shore-tab small {
  margin-left: 5px;
  font-weight: 600;
  opacity: 0.7;
}

.shore-tab[aria-selected="true"] {
  border-color: var(--sea-dark);
  background: var(--sea-dark);
  color: var(--white);
}

@media (prefers-reduced-motion: reduce) {
  .coast-toggle::after {
    transition: none;
  }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}
