/* ==========================================================================
   Leme to Pontal Swimming Association
   site.css : design system and shared components
   Tokens and rules follow DESIGN.md. Flat specificity, single class selectors.
   ========================================================================== */

/* --- Fonts ---------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../../fonts/archivo-latin.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../../fonts/archivo-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, 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: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../../fonts/archivo-italic-latin.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(../../fonts/archivo-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* the public site is light only, so form controls and scrollbars stay light
     even when the operating system asks for dark */
  color-scheme: light;

  --foam: #F3F6F8;
  --surface: #FFFFFF;
  --tide: #D6DFE6;
  --edge: #6B7C8C;
  --slate: #4B5D6E;
  --ink: #0F2740;
  --gold: #D6A93A;
  --danger: #B4472F;

  /* the route band is always a dark sea */
  --sea: #0F2740;
  --sea-text: #E8EEF3;
  --sea-rule: #2C4560;

  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 64px;
  --s9: 96px;

  --r-control: 6px;
  --r-surface: 10px;

  --wrap: 1200px;
  --header-h: 72px;

  --step: 150ms;
  --drawer-step: 200ms;

  /* Motion. One entrance, one drawing line, short answers to a pointer.
     Nothing here runs longer than 700ms and nothing repeats. */
  --enter: 600ms;      /* the hero rising into place */
  --enter-step: 90ms;  /* one hero element after the next */
  --draw-step: 120ms;  /* one segment of the course line */
  --fade-step: 200ms;  /* a course dot or its label */
  --reveal: 500ms;     /* a figure rising when its block is reached */
  --reveal-step: 90ms;
  --menu-step: 160ms;  /* a dropdown panel, a disclosure marker */
  --hover-step: 200ms; /* a lift, an image scale, an underline */
  --press-step: 120ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- Reset and base ------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--foam);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  font-stretch: 100%;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--s4);
  font-weight: 600;
  font-stretch: 112%;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
}

h1 { font-size: 2.6rem; font-stretch: 118%; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.25rem; }

p { margin: 0 0 var(--s4); }

a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--tide);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--step) ease, text-decoration-color var(--step) ease;
}

a:hover {
  text-decoration-color: var(--ink);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

ul, ol { margin: 0 0 var(--s4); padding-left: 1.25em; }

hr {
  border: 0;
  border-top: 1px solid var(--tide);
  margin: var(--s6) 0;
}

/* Two tone ring: gold alone is 2:1 on foam, so the ink outline carries the
   contrast on light surfaces and the gold ring carries it on the dark band. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  box-shadow: 0 0 0 5px var(--gold);
}

/* on the gold band both tokens turn against the band, so the ring is fixed */
.live-band :focus-visible {
  outline-color: #0F2740;
  box-shadow: 0 0 0 5px #F3F6F8;
}

::selection {
  background: var(--gold);
  color: #0F2740;
}

/* --- Layout helpers ------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding-left: var(--s5);
  padding-right: var(--s5);
}

.page {
  padding-top: var(--s7);
  padding-bottom: var(--s9);
}

.section {
  padding-top: var(--s8);
  padding-bottom: var(--s8);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3) var(--s5);
  margin-bottom: var(--s5);
}

.section-title {
  margin: 0;
  font-size: 2rem;
}

.section-more {
  font-size: 0.9375rem;
  font-weight: 500;
}

.meta {
  font-size: 0.875rem;
  font-weight: 500;
  font-stretch: 100%;
  color: var(--slate);
  line-height: 1.4;
}

.nums {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.skip-link {
  position: absolute;
  left: var(--s4);
  top: -100px;
  z-index: 100;
  background: var(--gold);
  color: #0F2740;
  padding: var(--s3) var(--s4);
  border-radius: var(--r-control);
  text-decoration: none;
  font-weight: 600;
}

.skip-link:focus {
  top: var(--s3);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (min-width: 900px) {
  .section {
    padding-top: var(--s9);
    padding-bottom: var(--s9);
  }
}

/* --- Header --------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--surface);
  box-shadow: 0 1px 0 var(--tide);
}

.header-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  height: var(--header-h);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  text-decoration: none;
  color: var(--ink);
  flex: 0 0 auto;
}

.brand-crest {
  width: 48px;
  height: 48px;
  object-fit: contain;
  flex: 0 0 auto;
}

.brand-name {
  font-weight: 600;
  font-stretch: 112%;
  font-size: 1.0625rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.brand-name-short {
  display: none;
}

/* --- Primary nav ---------------------------------------------------------- */

.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--s2);
  background: transparent;
  border: 1px solid var(--edge);
  border-radius: var(--r-control);
  color: var(--ink);
  font: inherit;
  font-weight: 500;
  font-size: 0.9375rem;
  padding: var(--s2) var(--s3);
  cursor: pointer;
  transition: border-color var(--step) ease;
}

.nav-toggle:hover {
  border-color: var(--slate);
}

.nav-toggle-bars {
  display: inline-block;
  width: 16px;
  height: 2px;
  background: currentColor;
  position: relative;
}

.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: '';
  position: absolute;
  left: 0;
  width: 16px;
  height: 2px;
  background: currentColor;
}

.nav-toggle-bars::before { top: -5px; }
.nav-toggle-bars::after { top: 5px; }

.nav {
  display: flex;
  align-items: center;
  gap: var(--s4);
  min-width: 0;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: var(--s1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-item {
  position: relative;
}

.nav-link {
  display: block;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-control);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--step) ease;
}

.nav-link:hover {
  background: var(--foam);
}

.nav-disclosure {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
  padding: var(--s2) var(--s3);
  border-radius: var(--r-control);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--step) ease;
}

.nav-disclosure:hover {
  background: var(--foam);
}

.nav-caret {
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  flex: 0 0 auto;
}

.nav-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 236px;
  max-width: 320px;
  background: var(--surface);
  border: 1px solid var(--tide);
  border-radius: var(--r-surface);
  padding: var(--s2);
  margin: 0;
  list-style: none;
  z-index: 50;
}

.nav-panel-right {
  left: auto;
  right: 0;
}

.nav-panel[hidden] {
  display: none;
}

.nav-panel-link {
  display: block;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-control);
  font-size: 0.9375rem;
  color: var(--ink);
  text-decoration: none;
  transition: background-color var(--step) ease;
}

.nav-panel-link:hover {
  background: var(--foam);
}

.lang-switch {
  display: flex;
  align-items: center;
  gap: var(--s1);
  flex: 0 0 auto;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
}

.lang-link {
  color: var(--slate);
  text-decoration: none;
  padding: var(--s1) var(--s2);
  border-radius: var(--r-control);
  transition: color var(--step) ease, background-color var(--step) ease;
}

.lang-link:hover {
  color: var(--ink);
  background: var(--foam);
}

.lang-current {
  color: var(--ink);
  font-weight: 600;
  padding: var(--s1) var(--s2);
}

.lang-sep {
  color: var(--tide);
}

/* --- Mobile drawer -------------------------------------------------------- */

/* The drawer is laid out as soon as it is unhidden and only then gets the open
   class, so the panel has a frame to slide from. */
.drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
}

.drawer-scrim {
  position: absolute;
  inset: 0;
  background: rgba(15, 39, 64, 0.44);
  border: 0;
  padding: 0;
  width: 100%;
  cursor: pointer;
}

.drawer-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(400px, 88vw);
  background: var(--surface);
  border-left: 1px solid var(--tide);
  padding: var(--s5);
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform var(--drawer-step) ease;
}

.drawer-open .drawer-panel {
  transform: translateX(0);
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  margin-bottom: var(--s5);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--tide);
}

.drawer-title {
  margin: 0;
  font-size: 1.25rem;
}

.drawer-close {
  background: transparent;
  border: 1px solid var(--tide);
  border-radius: var(--r-control);
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  padding: var(--s2) var(--s3);
  cursor: pointer;
}

.drawer-nav {
  list-style: none;
  margin: 0 0 var(--s5);
  padding: 0;
}

.drawer-group {
  border-bottom: 1px solid var(--tide);
  padding: var(--s3) 0;
}

.drawer-group-name {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
  margin-bottom: var(--s2);
}

.drawer-sub {
  list-style: none;
  margin: 0;
  padding: 0;
}

.drawer-link {
  display: block;
  padding: var(--s2) 0;
  color: var(--ink);
  text-decoration: none;
  font-size: 1.0625rem;
}

.drawer-link:hover {
  text-decoration: underline;
  text-decoration-color: var(--ink);
}

.drawer-foot {
  padding-top: var(--s3);
}

@media (max-width: 1023px) {
  .nav-toggle { display: inline-flex; }
  .nav { display: none; }
}

/* the full wordmark only fits beside eight nav items on wide screens */
@media (max-width: 1499px) {
  .brand-name-full { display: none; }
  .brand-name-short { display: inline; }
}

@media (max-width: 1140px) {
  .nav-link,
  .nav-disclosure { padding-left: var(--s2); padding-right: var(--s2); }
}

/* the last stop before the drawer: eight items still fit on one line at 1024 */
@media (max-width: 1080px) {
  .nav { gap: var(--s2); }
  .nav-link,
  .nav-disclosure {
    font-size: 0.875rem;
    padding-left: var(--s1);
    padding-right: var(--s1);
  }
}

/* --- Live tracking band --------------------------------------------------- */

.live-band {
  background: var(--gold);
  color: #0F2740;
}

.live-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s4);
  padding-top: var(--s3);
  padding-bottom: var(--s3);
}

.live-status {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-weight: 600;
  font-size: 0.9375rem;
}

.live-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #0F2740;
  flex: 0 0 auto;
}

.live-link {
  color: #0F2740;
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: underline;
  text-decoration-color: rgba(15, 39, 64, 0.4);
  text-underline-offset: 3px;
}

.live-link:hover {
  text-decoration-color: #0F2740;
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: var(--s3) var(--s5);
  border-radius: var(--r-control);
  border: 1px solid transparent;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--step) ease, border-color var(--step) ease,
    color var(--step) ease, transform var(--press-step) var(--ease-out);
}

.btn-primary {
  background: var(--gold);
  border-color: var(--gold);
  color: #0F2740;
}

.btn-primary:hover {
  background: #C49A2C;
  border-color: #C49A2C;
}

.btn-secondary {
  background: transparent;
  border-color: var(--edge);
  color: var(--ink);
}

.btn-secondary:hover {
  border-color: var(--ink);
  background: var(--surface);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
}

/* --- Hero ----------------------------------------------------------------- */

.hero {
  padding-top: var(--s7);
  padding-bottom: var(--s7);
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s6);
  align-items: center;
}

.hero-title {
  font-size: clamp(2.1rem, 4vw, 2.7rem);
  font-stretch: 120%;
  margin: 0 0 var(--s4);
  max-width: 24ch;
}

.hero-lead {
  font-size: 1.1875rem;
  color: var(--slate);
  max-width: 46ch;
  margin: 0 0 var(--s5);
}

.hero-figure {
  margin: 0;
  border-radius: var(--r-surface);
  overflow: hidden;
  background: var(--tide);
}

.hero-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

@media (min-width: 900px) {
  .hero {
    padding-top: var(--s8);
    padding-bottom: var(--s8);
  }
  .hero-grid {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--s7);
  }
  .hero-photo {
    aspect-ratio: 5 / 4;
    max-height: 420px;
  }
}

/* --- Route band (the one bold thing) -------------------------------------- */

.routeband {
  background-color: var(--sea);
  background-image: url(../img/wave.svg);
  background-size: 260px 65px;
  background-repeat: repeat;
  color: var(--sea-text);
}

.routeband-inner {
  padding-top: var(--s8);
  padding-bottom: var(--s8);
}

.routeband-title {
  color: var(--sea-text);
  font-size: 2rem;
  margin: 0 0 var(--s2);
}

.routeband-lead {
  color: #C9D6E1;
  max-width: 60ch;
  margin: 0 0 var(--s7);
}

.course {
  list-style: none;
  margin: 0 0 var(--s7);
  padding: 0;
  display: grid;
  gap: var(--s4);
  position: relative;
}

.course-stop {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  position: relative;
  padding-left: var(--s5);
}

.course-stop::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--sea);
  border: 2px solid var(--gold);
  z-index: 1;
}

/* The line is drawn stop by stop, from one dot centre to the next, so it can
   never miss the dots or run past the last one. */
.course-stop::after {
  content: '';
  position: absolute;
  left: 5px;
  top: calc(0.55em + 6px);
  bottom: calc(-1 * (var(--s4) + 0.55em + 6px));
  width: 2px;
  background: var(--gold);
}

.course-stop:last-child::after {
  content: none;
}

.course-major::before {
  background: var(--gold);
}

.course-place {
  font-weight: 500;
  font-size: 0.9375rem;
  color: #C3D1DD;
}

.course-major .course-place {
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--sea-text);
}

.course-km {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--gold);
  white-space: nowrap;
}

.routes-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s6);
  border-top: 1px solid var(--sea-rule);
  padding-top: var(--s6);
}

.routes-circuit-name {
  font-size: 1.25rem;
  color: var(--sea-text);
  margin: 0 0 var(--s4);
}

.routes-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.route-row {
  padding: var(--s3) 0;
  border-top: 1px solid var(--sea-rule);
}

.route-name {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  font-weight: 500;
  font-size: 1rem;
  color: var(--sea-text);
}

.route-km {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--gold);
  white-space: nowrap;
}

.route-ends {
  font-size: 0.875rem;
  color: #A8B9C7;
  margin: var(--s1) 0 0;
}

.routeband-foot {
  margin-top: var(--s6);
  padding-top: var(--s5);
  border-top: 1px solid var(--sea-rule);
}

.routeband-link {
  color: var(--sea-text);
  font-weight: 500;
  text-decoration-color: var(--sea-rule);
}

.routeband-link:hover {
  text-decoration-color: var(--sea-text);
}

/* The stops stay one vertical timeline until the band has room to lay them out
   in reading order across the full width. */
@media (min-width: 1024px) {
  .course {
    display: flex;
    align-items: flex-start;
    gap: var(--s2);
    padding-top: var(--s6);
  }
  .course-stop {
    display: block;
    padding-left: 0;
    padding-top: var(--s5);
    text-align: left;
    flex: 1 1 auto;
  }
  .course-stop::before {
    top: 0;
    left: 0;
  }
  /* the dot centre is 6px down and 6px in, so the 2px line starts at 5px */
  .course-stop::after {
    left: 6px;
    right: calc(-1 * (var(--s2) + 6px));
    top: 5px;
    bottom: auto;
    width: auto;
    height: 2px;
  }
  .course-km {
    display: block;
  }
}

@media (min-width: 900px) {
  .routeband-inner {
    padding-top: var(--s9);
    padding-bottom: var(--s9);
  }
  .routes-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s7);
  }
}

/* --- Records block -------------------------------------------------------- */

.records-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s5);
}

.record {
  border-top: 2px solid var(--ink);
  padding-top: var(--s4);
}

.record-time {
  font-size: 2.6rem;
  font-stretch: 118%;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  margin: 0 0 var(--s2);
}

.record-name {
  font-size: 1.25rem;
  font-weight: 600;
  font-stretch: 108%;
  margin: 0 0 var(--s1);
}

.record-meta {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
  margin: 0;
}

.records-note {
  margin-top: var(--s6);
  padding-top: var(--s5);
  border-top: 1px solid var(--tide);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s5);
}

.records-count {
  margin: 0;
  font-size: 1.0625rem;
}

.records-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  font-size: 0.9375rem;
  font-weight: 500;
}

@media (min-width: 700px) {
  .records-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s7);
  }
}

/* --- News ----------------------------------------------------------------- */

.news-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s6);
}

.news-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--tide);
}

.news-row {
  border-bottom: 1px solid var(--tide);
  padding: var(--s4) 0;
}

.news-date {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--s1);
}

.news-title {
  display: block;
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--ink);
}

.news-source {
  display: block;
  font-size: 0.875rem;
  color: var(--slate);
  margin-top: var(--s1);
}

.news-featured {
  border-top: 2px solid var(--ink);
  padding-top: var(--s4);
}

.news-featured-title {
  font-size: 1.5rem;
  margin: var(--s2) 0 var(--s3);
}

.news-featured-title a {
  text-decoration-color: var(--tide);
}

.news-featured-text {
  color: var(--slate);
  margin: 0 0 var(--s4);
}

@media (min-width: 900px) {
  .news-grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: var(--s7);
  }
}

/* --- Album grid ----------------------------------------------------------- */

.album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--s5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.album-card {
  display: block;
  text-decoration: none;
  color: var(--ink);
}

.album-cover {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-surface);
  background: var(--tide);
  margin-bottom: var(--s3);
}

.album-title {
  display: block;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.35;
  margin: 0 0 var(--s1);
}

.album-card:hover .album-title {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.album-count {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
}

/* --- Empty state ---------------------------------------------------------- */

.empty {
  border: 1px dashed var(--tide);
  border-radius: var(--r-surface);
  padding: var(--s5);
  color: var(--slate);
}

.empty p {
  margin: 0 0 var(--s2);
}

.empty p:last-child {
  margin-bottom: 0;
}

/* --- Alerts --------------------------------------------------------------- */

.alert {
  border: 1px solid var(--tide);
  border-left: 3px solid var(--slate);
  border-radius: var(--r-control);
  background: var(--surface);
  padding: var(--s4) var(--s5);
  margin-bottom: var(--s5);
}

.alert-good {
  border-left-color: var(--gold);
}

.alert-bad {
  border-left-color: var(--danger);
}

.alert p {
  margin: 0;
}

/* --- Breadcrumb and page title -------------------------------------------- */

.breadcrumb {
  padding-top: var(--s5);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
}

.breadcrumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumb-item a {
  color: var(--slate);
}

.breadcrumb-item a:hover {
  color: var(--ink);
}

.breadcrumb-sep {
  color: var(--tide);
}

.breadcrumb-current {
  color: var(--ink);
}

.page-title {
  padding-top: var(--s5);
  padding-bottom: var(--s6);
  border-bottom: 1px solid var(--tide);
  margin-bottom: var(--s7);
}

.page-title h1 {
  margin: 0;
  max-width: 20ch;
}

.page-lead {
  margin: var(--s4) 0 0;
  font-size: 1.1875rem;
  color: var(--slate);
  max-width: 60ch;
}

/* --- Prose ---------------------------------------------------------------- */

.prose {
  max-width: 68ch;
}

.prose p {
  margin: 0 0 var(--s4);
}

.prose h2 {
  font-size: 1.5rem;
  margin: var(--s7) 0 var(--s3);
}

.prose h3 {
  font-size: 1.25rem;
  margin: var(--s6) 0 var(--s3);
}

.prose ul,
.prose ol {
  margin: 0 0 var(--s4);
  padding-left: 1.35em;
}

.prose li {
  margin-bottom: var(--s2);
}

.prose img {
  border-radius: var(--r-surface);
  margin: var(--s5) 0;
}

.prose-steps {
  counter-reset: step;
  list-style: none;
  padding-left: 0;
}

.prose-steps li {
  counter-increment: step;
  position: relative;
  padding-left: var(--s7);
  margin-bottom: var(--s5);
}

.prose-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.1em;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--edge);
  border-radius: 50%;
  font-size: 0.875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* --- Document download rows ----------------------------------------------- */

.docs {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--tide);
  max-width: 68ch;
}

.doc-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--tide);
}

.doc-name {
  flex: 1 1 240px;
  font-weight: 500;
}

.doc-kind,
.doc-lang {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
  font-variant-numeric: tabular-nums;
}

.doc-action {
  margin-left: auto;
  font-size: 0.9375rem;
  font-weight: 600;
}

/* The records and the crossings were the only two pages here with a table, and
   both are now boards of rows laid out in data.css. The admin keeps its own
   .table in admin.css, which is the only stylesheet an admin page loads, so
   nothing on the site reads a table rule from here any more. */

/* --- Details groups ------------------------------------------------------- */

/* The only disclosure left on the site is the one folded into a row of the
   records board or the crossings register, so the group that used to stand a
   set of them on the crossings page, and the count that used to head one, are
   gone with it. What a small one looks like is in data.css. */

.disclosure {
  border-bottom: 1px solid var(--tide);
}

.disclosure > summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s4) 0;
  cursor: pointer;
  font-size: 1.25rem;
  font-weight: 600;
  font-stretch: 108%;
  list-style: none;
}

.disclosure > summary::-webkit-details-marker {
  display: none;
}

.disclosure-body {
  padding-bottom: var(--s5);
}

/* --- Photo grid and lightbox ---------------------------------------------- */

.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--s4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.photo-link {
  display: block;
  border-radius: var(--r-surface);
  overflow: hidden;
  background: var(--tide);
}

.photo-thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* pinned to the viewport and centred in it: the browser gives a modal dialog
   position: fixed on its own, and a position of our own would put the box at
   the top of the page instead, off screen whenever the grid has been scrolled */
.lightbox {
  position: fixed;
  inset: 0;
  margin: auto;
  border: 0;
  padding: var(--s2) var(--s2) var(--s3);
  background: transparent;
  max-width: 96vw;
  max-height: 96vh;
  max-height: 96svh;
  overflow: auto;
  overscroll-behavior: contain;
  color: var(--sea-text);
}

/* a dialog is display: none until it is open, so the box is set on [open] */
.lightbox[open] {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
}

.lightbox::backdrop {
  background: rgba(8, 16, 25, 0.92);
}

/* shown only once a photo has been loading for longer than a blink */
.lightbox-progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(243, 246, 248, 0.16);
}

.lightbox-progress-bar {
  display: block;
  width: 38%;
  height: 100%;
  background: var(--gold);
  animation: lightbox-progress 1.1s ease-in-out infinite;
}

@keyframes lightbox-progress {
  from { transform: translateX(-100%); }
  to { transform: translateX(300%); }
}

.lightbox-figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
}

/* the box is the photo's own shape, held by the ratio site.js reads off the
   thumbnail, so it is as wide as the viewport allows without ever passing 82vh
   and the caption and the buttons always sit below the picture. Heights are
   measured against the small viewport, the part of a phone screen left once
   the browser's own bars are showing, so nothing ends up under them */
.lightbox-stage {
  position: relative;
  flex: 0 0 auto;
  width: min(1280px, 92vw, calc(82vh * var(--lightbox-ratio, 1.5)));
  width: min(1280px, 92vw, calc(82svh * var(--lightbox-ratio, 1.5)));
  aspect-ratio: var(--lightbox-ratio, 1.5);
  overflow: hidden;
  border-radius: var(--r-surface);
  background: var(--sea);
}

/* the 640px thumbnail the grid already loaded, blurred and pushed a little past
   the edges so the blur has no soft rim of its own */
.lightbox-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(6px);
  transform: scale(1.06);
}

.lightbox-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity var(--step) ease;
}

.lightbox-image-loaded {
  opacity: 1;
}

.lightbox-caption {
  font-size: 0.875rem;
  font-weight: 500;
  color: #C3D1DD;
  font-variant-numeric: tabular-nums;
}

.lightbox-error {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--s3);
  margin: 0;
  font-size: 0.9375rem;
  color: #E8EEF3;
  text-align: center;
}

.lightbox-error[hidden] {
  display: none;
}

.lightbox-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
}

.lightbox-btn {
  background: rgba(243, 246, 248, 0.12);
  border: 1px solid rgba(243, 246, 248, 0.3);
  color: #E8EEF3;
  border-radius: var(--r-control);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  padding: var(--s2) var(--s4);
  cursor: pointer;
  transition: background-color var(--step) ease;
}

.lightbox-btn:hover {
  background: rgba(243, 246, 248, 0.24);
}

.lightbox-btn[disabled],
.lightbox-btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}

.lightbox-btn[aria-disabled="true"]:hover {
  background: rgba(243, 246, 248, 0.12);
}

/* on a phone the photo gives room back so the controls stay on screen */
@media (max-width: 640px) {
  .lightbox-stage {
    width: min(92vw, calc(68vh * var(--lightbox-ratio, 1.5)));
    width: min(92vw, calc(68svh * var(--lightbox-ratio, 1.5)));
  }
}

/* the error line is an extra row, so the photo gives it the height it needs */
.lightbox-stage-tight {
  width: min(1280px, 92vw, calc(66vh * var(--lightbox-ratio, 1.5)));
  width: min(1280px, 92vw, calc(66svh * var(--lightbox-ratio, 1.5)));
}

@media (prefers-reduced-motion: reduce) {
  .lightbox-progress-bar {
    width: 100%;
    animation: none;
  }
}

/* --- Forms ---------------------------------------------------------------- */

.form {
  max-width: 44rem;
}

.field {
  margin-bottom: var(--s5);
}

.field-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate);
  margin-bottom: var(--s2);
}

.input,
.select,
.textarea {
  display: block;
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: var(--r-control);
  padding: var(--s3) var(--s4);
  transition: border-color var(--step) ease;
}

.input:hover,
.select:hover,
.textarea:hover {
  border-color: var(--slate);
}

.textarea {
  min-height: 9rem;
  resize: vertical;
}

.field-error {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--danger);
  margin-top: var(--s2);
}

.field-hint {
  display: block;
  font-size: 0.875rem;
  color: var(--slate);
  margin-top: var(--s2);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 var(--s5);
}

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

/* --- Pagination ----------------------------------------------------------- */

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  list-style: none;
  margin: var(--s7) 0 0;
  padding: 0;
  font-variant-numeric: tabular-nums;
}

.pagination li a,
.pagination li span {
  display: inline-block;
  min-width: 40px;
  text-align: center;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--edge);
  border-radius: var(--r-control);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--surface);
  transition: border-color var(--step) ease;
}

.pagination li a:hover {
  border-color: var(--ink);
}

.pagination .active span {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--foam);
}

.pagination .disabled span {
  color: var(--slate);
  opacity: 0.6;
}

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--tide);
  margin-top: var(--s9);
}

.footer-wave {
  height: 8px;
  background-color: var(--sea);
  background-image: url(../img/wave.svg);
  background-size: 160px 40px;
  background-repeat: repeat;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s6);
  padding-top: var(--s8);
  padding-bottom: var(--s6);
}

.footer-col-title {
  font-size: 1rem;
  font-weight: 600;
  font-stretch: 108%;
  margin: 0 0 var(--s3);
}

.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-list li {
  margin-bottom: var(--s2);
  font-size: 0.9375rem;
  line-height: 1.45;
}

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

.footer-brand {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  margin-bottom: var(--s4);
}

.footer-crest {
  width: 56px;
  height: 56px;
  object-fit: contain;
  flex: 0 0 auto;
}

.footer-name {
  font-weight: 600;
  font-stretch: 108%;
  line-height: 1.2;
  max-width: 18ch;
}

.social-row {
  display: flex;
  gap: var(--s3);
  margin-top: var(--s4);
}

.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--edge);
  border-radius: var(--r-control);
  color: var(--ink);
  transition: border-color var(--step) ease;
}

.social-link:hover {
  border-color: var(--ink);
}

.social-icon {
  width: 20px;
  height: 20px;
  display: block;
}

.footer-bar {
  border-top: 1px solid var(--tide);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s5);
  padding-top: var(--s5);
  padding-bottom: var(--s6);
  font-size: 0.875rem;
  color: var(--slate);
}

.footer-bar p {
  margin: 0;
}

.footer-bar a {
  color: var(--slate);
}

.footer-bar a:hover {
  color: var(--ink);
}

.footer-bar-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s4);
}

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

@media (min-width: 1024px) {
  .footer-grid {
    grid-template-columns: 1.2fr 1fr 1fr 1.2fr;
    gap: var(--s7);
  }
}

/* --- Motion ---------------------------------------------------------------
   Every movement below is a transform or an opacity, so nothing here can move
   the layout. Each entrance runs once. The only property animated outside that
   pair is the height of a disclosure, which site.js drives with the Web
   Animations API because a height cannot be faked with a transform.
   -------------------------------------------------------------------------- */

/* The hero entrance is written into the markup rather than switched on by JS,
   so it starts with the first paint, needs no script and cannot flash. The
   fill mode holds the first frame through the delay and the last one after. */

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero-enter {
  animation: hero-rise var(--enter) var(--ease-out) var(--enter-delay, 0ms) both;
}

.hero-enter-2 { --enter-delay: var(--enter-step); }
.hero-enter-3 { --enter-delay: calc(2 * var(--enter-step)); }
.hero-enter-4 { --enter-delay: calc(3 * var(--enter-step)); }
.hero-enter-5 { --enter-delay: calc(4 * var(--enter-step)); }

/* The course line. Nothing is hidden by the stylesheet on its own: site.js
   arms the band, and only a browser that ran the script can be left with a
   half drawn line. Each stop carries its own index, so one rule times all of
   them. The line is vertical until the band has room to lay the stops across
   the page, so the segment is scaled on the axis it is drawn on. */

.course.is-armed .course-stop::before,
.course.is-armed .course-place,
.course.is-armed .course-km {
  opacity: 0;
}

.course.is-armed .course-stop::after {
  transform: scaleY(0);
  transform-origin: top;
}

.course.is-drawn .course-stop::before,
.course.is-drawn .course-place,
.course.is-drawn .course-km {
  opacity: 1;
  transition: opacity var(--fade-step) ease
    calc(var(--stop-index, 0) * var(--draw-step));
}

.course.is-drawn .course-stop::after {
  transform: scaleY(1);
  transition: transform var(--draw-step) linear
    calc(var(--stop-index, 0) * var(--draw-step));
}

@media (min-width: 1024px) {
  .course.is-armed .course-stop::after {
    transform: scaleX(0);
    transform-origin: left;
  }
  .course.is-drawn .course-stop::after {
    transform: scaleX(1);
  }
}

/* A figure that rises when its block is reached. Same observer, once only. */

.reveal-armed {
  opacity: 0;
  transform: translateY(12px);
}

.reveal-shown {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--reveal) ease
      calc(var(--reveal-index, 0) * var(--reveal-step)),
    transform var(--reveal) var(--ease-out)
      calc(var(--reveal-index, 0) * var(--reveal-step));
}

/* Dropdown panels. The hidden attribute stays the state; the class is only
   the painted half of it, and site.js waits for the close before hiding. */

.nav-panel {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--menu-step) ease,
    transform var(--menu-step) var(--ease-out);
}

.nav-panel-open {
  opacity: 1;
  transform: translateY(0);
}

/* The disclosure marker turns with the group it belongs to. The rotation
   itself is in data.css, next to the marker; this is only its timing. */

.disclosure-name::before {
  transition: transform var(--menu-step) var(--ease-out);
}

/* Hover answers: the card lifts, the photo grows inside the frame that clips
   it. Album covers are clipped by the card, product photos by the framed link
   they sit in, and the pilot thumbnail grows from its left edge into the gap
   beside it, so no row can grow past its own line. */

.album-card {
  border-radius: var(--r-surface);
  overflow: hidden;
  transition: transform var(--hover-step) var(--ease-out);
}

.album-cover {
  transition: transform var(--hover-step) var(--ease-out);
}

.album-card:hover {
  transform: translateY(-2px);
}

.album-card:hover .album-cover {
  transform: scale(1.03);
}

.product-photo-link {
  transition: transform var(--hover-step) var(--ease-out);
}

.product-photo {
  transition: transform var(--hover-step) var(--ease-out);
}

.product-photo-link:hover {
  transform: translateY(-2px);
}

.product-photo-link:hover .product-photo {
  transform: scale(1.03);
}

.pilot-row {
  transition: transform var(--hover-step) var(--ease-out);
}

.pilot-thumb {
  transform-origin: left center;
  transition: transform var(--hover-step) var(--ease-out);
}

.pilot-row:hover {
  transform: translateY(-2px);
}

.pilot-row:hover .pilot-thumb {
  transform: scale(1.03);
}

/* A 2px rule that runs in from the left under a nav or footer link. */

.nav-link,
.nav-disclosure {
  position: relative;
}

.nav-link::after,
.nav-disclosure::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 3px;
  height: 2px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--hover-step) var(--ease-out);
}

.nav-link:hover::after,
.nav-link:focus-visible::after,
.nav-disclosure:hover::after,
.nav-disclosure:focus-visible::after {
  transform: scaleX(1);
}

/* In the footer every item of a list is a link, so the underline is the hover
   answer rather than a standing mark. A news title in the last column runs to
   two lines, and an absolutely placed bar would draw one rule across the whole
   box: this rule is painted per line instead, so it follows the text however
   it wraps. It grows from nothing on the left, moves no layout, and is the one
   place a width is animated rather than a transform. */

.footer-list a {
  text-decoration: none;
  background-image: linear-gradient(var(--ink), var(--ink));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size var(--hover-step) var(--ease-out);
}

.footer-list a:hover,
.footer-list a:focus-visible {
  background-size: 100% 2px;
}

/* Buttons already answer with colour. This is the last millimetre of it. */

.btn:hover {
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(1px);
}

/* Under a reduced motion setting every state above arrives at once: the
   durations collapse and the travel is taken out. The nav underline keeps its
   scale and the footer rule keeps its width, because in those two the value is
   the state itself and not a movement. */

@media (prefers-reduced-motion: reduce) {
  :root {
    --step: 0.01ms;
    --drawer-step: 0.01ms;
    --enter: 0.01ms;
    --enter-step: 0ms;
    --draw-step: 0.01ms;
    --fade-step: 0.01ms;
    --reveal: 0.01ms;
    --reveal-step: 0ms;
    --menu-step: 0.01ms;
    --hover-step: 0.01ms;
    --press-step: 0.01ms;
  }

  .drawer-panel {
    transition: none;
  }

  .hero-enter {
    animation-duration: 0.01ms;
    animation-delay: 0ms;
  }

  .course.is-armed .course-stop::before,
  .course.is-armed .course-place,
  .course.is-armed .course-km {
    opacity: 1;
  }

  .course.is-armed .course-stop::after {
    transform: none;
  }

  .reveal-armed {
    opacity: 1;
    transform: none;
  }

  .album-card:hover,
  .album-card:hover .album-cover,
  .product-photo-link:hover,
  .product-photo-link:hover .product-photo,
  .pilot-row:hover,
  .pilot-row:hover .pilot-thumb,
  .btn:hover,
  .btn:active {
    transform: none;
  }
}
