:root {
  color-scheme: light;
  --background: #eaeff4;
  --paper: #ffffff;
  --ink: #202326;
  --muted: #5d6368;
  --faint: #7b8084;
  --line: #aeb2b1;
  --line-light: #d5d7d5;
  --blue: #174d78;
  --cobalt: #00378c;
  --red: #a33b32;
  --orchid: darkorchid;
}

* {
  box-sizing: border-box;
}

html {
  background: var(--background);
}

body {
  min-width: 320px;
  margin: 0;
  color: var(--ink);
  background: var(--background);
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
  /* The full-bleed footer banner is 100vw wide (includes the scrollbar
     gutter), so clip the stray horizontal overflow it would otherwise add. */
  overflow-x: hidden;
  overflow-x: clip;
}

.page {
  width: min(1080px, calc(100% - 28px));
  margin: 0 auto;
}

.site-header {
  /* Header palette, scoped to the dark band and inherited by its children. */
  --header-bg: #1e3a54;
  --header-ink: #eef3f8;
  --header-muted: #a9bdd1;
  --header-art: #d7e2ec;
  --header-error: #ff9f95;
  --header-line: rgba(255, 255, 255, 0.16);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 20px;
  /* Full-bleed: break out of the centered .page column to the viewport edges,
     then re-apply the page gutter as padding so the content stays aligned with
     .page. Mirrors the .footer__scene breakout. The extra bottom padding
     leaves blank navy for .content to overlap. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: 14px max(14px, calc(50vw - 540px)) 26px;
  background: var(--header-bg);
  border-bottom: 1px solid var(--header-line);
}

/* Header text on the navy band. The global h1/a/--muted inks are dark, so
   every ink inside .site-header is restated in the light header palette. */
.site-header h1 {
  color: var(--header-ink);
}

.site-header .site-subtitle {
  color: var(--header-muted);
}

.site-header .header-links a {
  color: var(--header-ink);
}

/* Weather illustration on the dark band: line art and rain use light inks so
   they stay visible; clouds and fog are already near-white. */
.site-header .weather-sun {
  stroke: var(--header-art);
}

.site-header .weather-aircraft {
  fill: var(--header-art);
}

.site-header .weather-visual {
  border-bottom-color: var(--header-line);
}

.site-header .weather-rain i {
  background: #8fb4d6;
}

.site-header .header-weather__summary {
  color: var(--header-muted);
}

.site-header .header-weather.is-error .header-weather__summary {
  color: var(--header-error);
}

.site-heading {
  min-width: 0;
}

.site-title {
  flex: 0 0 auto;
}

/* The brand is an <h1> on the homepage and a <p> on every other page (there
   the page topic owns the only <h1>). Both tags carry .site-title__text, so the
   brand typography and the light header ink live on the class, not the element;
   otherwise the <p> variant would fall back to the dark 14px body text. */
.site-title__text {
  margin-bottom: 2px;
  color: var(--header-ink);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.035em;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: 2px;
  color: var(--blue);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.035em;
}

.site-subtitle,
.header-links,
.header-weather__summary,
.card__meta,
.card__date,
.card__time {
  font-family: "Courier New", Courier, monospace;
}

.site-subtitle {
  margin-bottom: 0;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.header-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 8px;
  font-size: 10px;
}

a {
  color: var(--blue);
}

.header-links a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
  white-space: nowrap;
}

.header-link__icon {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.header-links a:hover,
.footer a:hover {
  text-decoration: underline;
}

.footer {
  color: var(--muted);
  font-size: 10px;
  line-height: 1.5;
}

/* Footer scene: the full-bleed mountain engraving with the directory/FAQ card
   and the support board sitting on it. The source WebP is pure black with an
   alpha channel, so it is used as an alpha mask over a solid cobalt fill: the
   transparent background stays transparent and the antialiased alpha gradation
   becomes the ink's softness. `mask-size: cover` fills the viewport edge to
   edge, cropping the sides on narrow screens and scaling up on ultrawide ones.
   The inner grid keeps its columns on the .page width, while margin-inline
   breaks only the scene out to the viewport edges (mirrors .site-header). */
.footer__scene {
  /* The engraving keeps its natural 3840:335 aspect at desktop widths; the
     min-height reserves enough room for the full peaks even on very wide,
     short screens, so nothing is clipped at the top. */
  --footer-mountains: calc(100vw * 335 / 3840);
  position: relative;
  width: 100vw;
  min-height: calc(var(--footer-mountains) + 20px);
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  margin-top: 7vh;
  margin-top: 7svh;
  /* The two footer blocks sit above the range and the range slides under
     them; the 20 px bottom inset is the only strip of bare peaks. */
  padding: clamp(20px, 3svh, 36px) max(14px, calc(50vw - 540px)) 20px;
  overflow: hidden;
}

.footer__mountains {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--footer-mountains);
  /* --cobalt mixed with 33% of --background: keeps the ink from reading too
     bold. Precomputed because a static colour works everywhere, with no
     color-mix()/fallback split. Recompute if --cobalt or --background change. */
  background-color: #4d74ae;
  -webkit-mask-image: url("/footer-range.webp?v=20261002d");
  mask-image: url("/footer-range.webp?v=20261002d");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center bottom;
  mask-position: center bottom;
  -webkit-mask-size: cover;
  mask-size: cover;
  pointer-events: none;
}

/* One footer composition instead of two cards: a shared top rule, directory
   links on the left and the support note on the right. The note ends on the
   scene's bottom line, so it reads as the last footer block, not a widget. */
.footer__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
  align-items: start;
  gap: 32px;
  padding-top: 14px;
  border-top: 1px solid var(--line-light);
}

/* The left group is a translucent patch rather than a card: on the page colour
   it is invisible, and only starts reading as a surface once a short viewport
   pushes it into the peaks. */
.footer__meta {
  justify-self: start;
  align-self: start;
  width: fit-content;
  max-width: 100%;
  min-width: 0;
  /* The padding is a readability patch, not an indent: pull it back so the
     links still start on the footer rule's left edge. */
  margin-left: -12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(234, 239, 244, 0.86);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* One grouped link list, one format: every footer link is muted and
   underlined; hover turns it blue. */
.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 0;
  font-size: 10px;
  line-height: 1.5;
}

.footer__links a {
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 2px;
}

.footer__links a:hover {
  color: var(--blue);
  text-decoration-color: currentColor;
}

.content {
  position: relative;
  z-index: 1;
  /* The content sheet rides up into the navy header: the negative margin lets
     its top edge bite into the band, leaving header visible on either side.
     --background matches the body, so only the overlap reads as a cut. Keep the
     header's bottom padding greater than this overlap. */
  margin-top: -16px;
  padding: 0 0 34px;
  background: var(--background);
}

.header-weather {
  --cloud-height: 30%;
  --rain-start: 18%;
  justify-self: end;
  width: clamp(340px, 42vw, 500px);
  min-width: 0;
  padding-left: 16px;
}

.weather-visual {
  position: relative;
  height: 76px;
  overflow: hidden;
  border-bottom: 1px solid var(--line-light);
}

/* Black-and-white, unfilled sun. It is positioned by --sun-x/--sun-y, which
   weather.js derives from sunrise, sunset and the current time; the bottom
   edge of .weather-visual is the horizon. It sits behind clouds, rain and the
   aircraft (z-index 1). */
.weather-sun {
  position: absolute;
  z-index: 1;
  bottom: var(--sun-y, 0%);
  left: var(--sun-x, 50%);
  display: none;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--ink);
  stroke-linecap: round;
  stroke-width: 1.4;
  transform: translate(-50%, 50%);
}

.has-sun .weather-sun {
  display: block;
}

.weather-aircraft {
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 50%;
  width: auto;
  height: 42%;
  aspect-ratio: 1;
  fill: var(--ink);
  transform: translate(-50%, -50%) rotate(90deg);
  animation: weather-float 3s ease-in-out infinite;
}

.weather-clouds {
  position: absolute;
  z-index: 2;
  right: 5%;
  bottom: var(--cloud-height);
  left: 5%;
  height: 22px;
  opacity: 0;
  transition: opacity 160ms ease;
}

.has-clouds .weather-clouds {
  opacity: 1;
}

.weather-cloud {
  position: absolute;
  bottom: 0;
  left: var(--cloud-left);
  width: var(--cloud-width);
  height: 8px;
  border: 1px solid #b9bdbe;
  border-radius: 999px;
  background: #f7f8f7;
}

.weather-cloud::before,
.weather-cloud::after {
  position: absolute;
  bottom: 3px;
  border: 1px solid #b9bdbe;
  border-bottom: 0;
  border-radius: 999px 999px 0 0;
  background: #f7f8f7;
  content: "";
}

.weather-cloud::before {
  left: 12%;
  width: 38%;
  height: 13px;
}

.weather-cloud::after {
  right: 10%;
  width: 34%;
  height: 10px;
}

/* Cloud slots. Rendered markup carries no inline styles (strict CSP), so the
   per-cloud custom properties live here. */
.weather-cloud:nth-child(1) {
  --cloud-left: 8%;
  --cloud-width: 24%;
}

.weather-cloud:nth-child(2) {
  --cloud-left: 30%;
  --cloud-width: 34%;
}

.weather-cloud:nth-child(3) {
  --cloud-left: 64%;
  --cloud-width: 26%;
}

.weather-rain {
  position: absolute;
  z-index: 3;
  top: var(--rain-start);
  right: 0;
  bottom: 0;
  left: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}

.has-rain .weather-rain {
  opacity: 0.72;
}

.weather-rain i {
  position: absolute;
  top: -12px;
  left: var(--rain-x);
  width: 1px;
  height: 10px;
  background: #4f7893;
  transform: rotate(12deg);
  animation: weather-rain-fall 1.15s linear infinite;
  animation-delay: var(--rain-delay);
}

/* Rain slots. Same story as the clouds above: no inline styles in markup. */
.weather-rain i:nth-child(1) { --rain-x: 8%; --rain-delay: -0.2s; }
.weather-rain i:nth-child(2) { --rain-x: 17%; --rain-delay: -0.8s; }
.weather-rain i:nth-child(3) { --rain-x: 27%; --rain-delay: -0.5s; }
.weather-rain i:nth-child(4) { --rain-x: 37%; --rain-delay: -1.1s; }
.weather-rain i:nth-child(5) { --rain-x: 46%; --rain-delay: -0.35s; }
.weather-rain i:nth-child(6) { --rain-x: 55%; --rain-delay: -0.9s; }
.weather-rain i:nth-child(7) { --rain-x: 64%; --rain-delay: -0.6s; }
.weather-rain i:nth-child(8) { --rain-x: 73%; --rain-delay: -0.1s; }
.weather-rain i:nth-child(9) { --rain-x: 82%; --rain-delay: -0.75s; }
.weather-rain i:nth-child(10) { --rain-x: 91%; --rain-delay: -0.4s; }

/* Fog. Blurred, slowly drifting bands layered above the aircraft (z-index 5)
   so an FG observation reads as reduced visibility. Band geometry lives in
   nth-child slots, matching the cloud/rain pattern so markup stays style-free
   under strict CSP. */
.weather-fog {
  position: absolute;
  z-index: 5;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}

.has-fog .weather-fog {
  opacity: 1;
}

.weather-fog__band {
  position: absolute;
  top: var(--fog-top);
  left: -30%;
  width: 160%;
  height: var(--fog-height);
  border-radius: 999px;
  background: #fbfcfb;
  opacity: var(--fog-opacity);
  filter: blur(5px);
  animation: weather-fog-drift var(--fog-duration) ease-in-out infinite alternate;
  animation-delay: var(--fog-delay);
}

/* Fog slots. Thicker and denser toward the ground, like real fog. */
.weather-fog__band:nth-child(1) { --fog-top: 6%;  --fog-height: 22px; --fog-opacity: 0.35; --fog-duration: 14s; --fog-delay: 0s; }
.weather-fog__band:nth-child(2) { --fog-top: 30%; --fog-height: 28px; --fog-opacity: 0.45; --fog-duration: 18s; --fog-delay: -4s; }
.weather-fog__band:nth-child(3) { --fog-top: 56%; --fog-height: 30px; --fog-opacity: 0.55; --fog-duration: 16s; --fog-delay: -8s; }
.weather-fog__band:nth-child(4) { --fog-top: 78%; --fog-height: 26px; --fog-opacity: 0.65; --fog-duration: 20s; --fog-delay: -2s; }

.header-weather__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 10px;
  margin: 0;
  padding-top: 4px;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.35;
  white-space: normal;
}

.header-weather__item {
  min-width: 0;
}

.header-weather__wind {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

/* The arrow points the way the wind blows, so the reported (source) direction
   is rotated by 180deg in weather.js. */
.header-weather__wind-arrow {
  width: 9px;
  height: 9px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
  transform: rotate(var(--wind-rotate, 0deg));
}

.header-weather.is-error .header-weather__summary {
  color: var(--red);
}

@keyframes weather-float {
  0%,
  100% {
    transform: translate(-50%, calc(-50% + 1px)) rotate(90deg);
  }
  50% {
    transform: translate(-50%, calc(-50% - 3px)) rotate(90deg);
  }
}

@keyframes weather-rain-fall {
  from {
    opacity: 0;
    transform: translate(0, -8px) rotate(12deg);
  }
  15% {
    opacity: 1;
  }
  to {
    opacity: 0;
    transform: translate(10px, 88px) rotate(12deg);
  }
}

@keyframes weather-fog-drift {
  from {
    transform: translateX(-6%);
  }
  to {
    transform: translateX(6%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .weather-aircraft {
    animation: none;
  }

  .weather-rain i {
    top: 30%;
    opacity: 0.7;
    animation: none;
  }

  .weather-fog__band {
    animation: none;
  }
}

.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.card {
  --scrim-strong: 0.55;
  --scrim-soft: 0.3;
  --card-pad: clamp(9px, 2.4cqw, 26px);
  position: relative;
  container-type: inline-size;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: 1px solid var(--line);
  background: #0e1116;
}

/* Published photos are cropped to exactly 3:2 by the pipeline, so the hero
   uses that ratio too and nothing is cropped out of frame. */
.card--hero {
  grid-column: 1 / -1;
  aspect-ratio: 3 / 2;
}

.card__image {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card__scrim {
  position: absolute;
  z-index: 2;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(5, 7, 11, var(--scrim-strong)) 0%,
    rgba(5, 7, 11, var(--scrim-soft)) 16%,
    rgba(5, 7, 11, 0) 38%
  );
  pointer-events: none;
}

.card__overlay {
  position: absolute;
  z-index: 3;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px;
  padding: var(--card-pad);
  color: #fff;
  paint-order: stroke fill;
  -webkit-text-stroke: clamp(0.3px, 0.13cqw, 1.1px) rgba(0, 0, 0, 0.85);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 5px rgba(0, 0, 0, 0.65);
  pointer-events: none;
}

/* Facts on the enlarged photo that will one day link to a group page. They are
   anchors without href, so they look and behave exactly like the plain facts on
   the grid; only the base link colour has to be neutralised. */
.card__title-link,
.card__meta-item--route {
  color: inherit;
}

/* The group pages now exist, so hero facts are real links. They stay
   overlay-white and must win the hit test against the overlay, which is
   pointer-transparent; the underline on hover is the affordance. */
.card__title-link[href],
.card__meta-item--route[href] {
  text-decoration: none;
  pointer-events: auto;
}

.card__title-link[href]:hover,
.card__meta-item--route[href]:hover {
  text-decoration: underline;
}

.like {
  pointer-events: auto;
}

.card__title:focus {
  outline: none;
}

.card__id {
  flex: 1 1 auto;
  min-width: 0;
}

.card__when {
  flex: 0 0 auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Sizes are container-relative so the hero and the grid cards stay in
   proportion. The first declaration is a fallback for engines without cqw. */
.card__title {
  margin: 0;
  overflow: hidden;
  font-size: 15px;
  font-size: clamp(13px, 3.5cqw, 27px);
  font-weight: 700;
  letter-spacing: -0.005em;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A route title ("Catania (CTA, 🇮🇹) → Wrocław (WRO)") is longer than a
   callsign, so let it wrap to two lines instead of ellipsising to a stub. */
.card__title--route {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  white-space: normal;
  text-overflow: clip;
}

.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 0.5em;
  /* Two rows are reserved so headings line up across a row of cards even
     when one of them has a short meta line. */
  min-height: 2.9em;
  margin: 0.4em 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-size: 10px;
  font-size: clamp(9px, 2.1cqw, 14px);
  letter-spacing: 0.01em;
  line-height: 1.45;
}

.card__meta-item {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card__meta-key {
  color: rgba(255, 255, 255, 0.6);
}

.card__meta-sep {
  color: rgba(255, 255, 255, 0.45);
}

.card__country {
  -webkit-text-stroke: 0;
}

.card__country--code {
  padding: 0 0.3em;
  margin-right: 0.4em;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 2px;
  font-size: 0.9em;
  letter-spacing: 0.04em;
  line-height: 1.2;
}

/* Flags replace the boxed ISO code in the meta rows. */
.card__country--flag {
  margin-right: 0.4em;
  font-size: 1.05em;
  line-height: 1;
}

.card__date {
  margin: 0;
  color: rgba(255, 255, 255, 0.85);
  font-size: 10px;
  font-size: clamp(9px, 2.1cqw, 14px);
  letter-spacing: 0.04em;
  line-height: 1.2;
}

.card__time {
  margin: 0.1em 0 0;
  font-size: 18px;
  font-size: clamp(15px, 4cqw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

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

.icon {
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
}

/* Whole card is the hit area for opening a photo. It sits beneath the scrim
   and overlay, which are pointer-transparent. */
.card__open {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  -webkit-appearance: none;
  appearance: none;
}

.card__open:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: -3px;
}

/* --- Enlarged photo ------------------------------------------------------- */

.detail__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.detail__back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-decoration: none;
  text-transform: uppercase;
}

.detail__back:hover {
  text-decoration: underline;
}

.detail__count {
  margin: 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* The vote lives in the card overlay, so it borrows the overlay palette rather
   than the light page chrome. */
.like {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  margin-top: 8px;
  padding: 4px 10px 4px 8px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  line-height: 1;
  text-shadow: none;
  -webkit-text-stroke: 0;
  cursor: pointer;
}

.like .icon {
  width: 15px;
  height: 15px;
}

.like:hover {
  border-color: #fff;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
}

.like:disabled {
  cursor: default;
  opacity: 0.6;
}

.like__count {
  font-variant-numeric: tabular-nums;
}

.like[aria-pressed="true"] {
  border-color: #fff;
  background: #fff;
  color: #16202b;
}

@media (max-width: 900px) {
  .site-header {
    grid-template-columns: 1fr;
  }

  .header-weather {
    justify-self: stretch;
    width: 100%;
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 760px) {
  .gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 520px) {
  .gallery {
    grid-template-columns: 1fr;
  }

  .footer {
    display: block;
    line-height: 1.8;
  }
}

/* --- SSR page chrome ------------------------------------------------------ */

.site-title__link {
  color: inherit;
  text-decoration: none;
}

.site-title__link:hover {
  text-decoration: underline;
}

.page-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 2px 12px;
  margin: 2px 0 10px;
}

/* The first page heading in main is the page's own header, so give it the same
   paper-card chrome as the frontpage hero (see .hero-meta): it then bites into
   the navy band exactly like the hero does. Section headings further down the
   page (.front-block, .airframes--front) are not :first-child, so they stay
   plain. The frontpage is skipped too, since its first child is .front-hero. */
.content > .page-head:first-child {
  margin: 2px 0 18px;
  padding: 12px 14px;
  border: 1px solid var(--line-light);
  background: var(--paper);
}

.page-title {
  margin: 0;
  color: var(--ink);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.page-count {
  margin: 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  line-height: 1.35;
  text-align: right;
}

/* --- Photo page actions and related sections ------------------------------ */

/* Action bar under the photo hero: the full-airframe profile link plus the
   upvote control, moved out of the image overlay so both read as page
   actions. The vote keeps its markup from the overlay but on a light field. */
.photo-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 10px 0 18px;
}

.action {
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.action:hover {
  border-color: var(--blue);
  color: var(--blue);
}

.photo-actions .like {
  margin-top: 0;
  border-color: var(--line);
  background: var(--paper);
  color: var(--ink);
  text-shadow: none;
}

.photo-actions .like:hover {
  border-color: var(--blue);
  background: var(--paper);
  color: var(--blue);
}

.photo-actions .like[aria-pressed="true"] {
  border-color: var(--blue);
  background: var(--blue);
  color: #fff;
}

/* Related sections: up to three representative photos in wide columns plus a
   narrow fourth slot for the "Zobacz więcej" tile. The template is always four
   columns so sections with and without the tile line up; empty cells stay
   empty. The tile is one third the width of a photo column. */
.related {
  margin: 18px 0;
}

.related__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 0.3333fr);
  gap: 14px;
}

.related__more {
  display: flex;
  align-items: center;
  justify-content: center;
  /* No aspect-ratio: in the desktop grid the tile is narrower than a photo, so
     it stretches to the row height set by the cards instead of shrinking. */
  background: var(--paper);
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
}

.related__more:hover {
  color: var(--blue);
}

@media (max-width: 760px) {
  .related__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Equal-width columns here, so the photo ratio matches the neighbour height
     even when the tile ends up alone on its row. */
  .related__more {
    aspect-ratio: 3 / 2;
  }
}

@media (max-width: 520px) {
  .related__grid {
    grid-template-columns: 1fr;
  }
}

/* --- Date timeline -------------------------------------------------------- */

.empty-state {
  padding: 22px 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
}

.empty-state p {
  margin: 0;
}

/* --- Date picker: rolling arrivals/departures chart + calendar ------------ */

.date-picker {
  /* Widget-local palette: the prototype's teal/purple/amber semantics, kept
     out of the rest of the site's navy/accent palette. */
  --dp-photo: #0f6e56;
  --dp-nophoto: #9fe1cb;
  --dp-departure: #7f77dd;
  --dp-special: #ba7517;
  margin: 0 0 18px;
  padding: 10px 12px 12px;
  border: 1px solid var(--line-light);
  background: var(--paper);
}

.dp-toolbar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.dp-toolbar__nav,
.dp-toolbar__actions {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.dp-toolbar__range {
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  white-space: nowrap;
}

.dp-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 28px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 12px;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.dp-button:hover {
  border-color: var(--blue);
  color: var(--blue);
}

.dp-button--arrow {
  width: 28px;
  padding: 3px 0;
  font-size: 16px;
}

.dp-button.is-disabled {
  border-color: var(--line-light);
  color: var(--line);
  cursor: default;
}

.dp-calendar {
  position: static;
}

.dp-calendar__summary {
  gap: 5px;
  list-style: none;
  cursor: pointer;
}

.dp-calendar__icon {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

.dp-calendar__summary::-webkit-details-marker {
  display: none;
}

.dp-calendar__summary::marker {
  content: "";
}

.dp-calendar__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  width: min(340px, calc(100vw - 40px));
  padding: 10px;
  border: 1px solid var(--line);
  background: var(--paper);
  box-shadow: 0 6px 18px rgba(20, 35, 48, 0.12);
}

.dp-calendar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.dp-calendar__month {
  flex: 1;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
}

.dp-calendar__grid {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
}

.dp-calendar__grid th {
  padding: 2px 0 4px;
  color: var(--faint);
  font-weight: 400;
}

.dp-calendar__cell {
  height: 30px;
  padding: 0;
  border: 1px solid transparent;
  text-align: center;
  vertical-align: middle;
}

.dp-calendar__day {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--ink);
  text-decoration: none;
}

a.dp-calendar__day:hover {
  outline: 1px solid var(--blue);
}

.dp-calendar__cell.is-empty {
  border: 0;
}

.dp-calendar__cell.is-no-data .dp-calendar__day,
.dp-calendar__cell.is-future .dp-calendar__day {
  color: var(--faint);
}

.dp-calendar__cell.is-selected {
  border-color: var(--blue);
  box-shadow: inset 0 0 0 1px var(--blue);
}

.dp-calendar__cell.is-today .dp-calendar__day {
  color: var(--blue);
  font-weight: 700;
}

.dp-heat--0 { background: transparent; }
.dp-heat--1 { background: #eef8f4; }
.dp-heat--2 { background: #d8f0e8; }
.dp-heat--3 { background: #b9e3d6; }
.dp-heat--4 { background: #8fd2bf; }
.dp-heat--5 { background: #5fbfa5; }

.dp-chart {
  margin: 0;
}

.dp-chart__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

.dp-chart__inner {
  position: relative;
  min-width: 784px;
}

.dp-chart__axis {
  position: absolute;
  top: 64px;
  left: 0;
  right: 0;
  height: 1px;
  z-index: 2;
  background: var(--line);
}

.dp-chart__cols {
  display: flex;
  align-items: stretch;
  gap: 2px;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dp-col__item {
  flex: 1 1 0;
  min-width: 0;
}

.dp-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 4px 0 6px;
  border: 1px solid transparent;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  text-decoration: none;
}

.dp-col:hover {
  background: var(--background);
}

.dp-col.is-selected {
  border-color: var(--blue);
  background: var(--paper);
}

.dp-col.is-weekend .dp-col__day,
.dp-col.is-weekend .dp-col__weekday,
.dp-col.is-no-data .dp-col__day,
.dp-col.is-no-data .dp-col__weekday {
  color: var(--faint);
}

.dp-col.is-selected .dp-col__day {
  color: var(--ink);
}

.dp-col.is-today .dp-col__day {
  color: var(--blue);
  font-weight: 700;
}

.dp-col.is-live .dp-col__top,
.dp-col.is-live .dp-col__bottom {
  opacity: 0.55;
}

.dp-col__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
  height: 60px;
}

.dp-col__special {
  width: 5px;
  height: 5px;
  margin-bottom: 2px;
  border-radius: 50%;
  background: var(--dp-special);
}

.dp-col__stack {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  width: 70%;
  max-width: 14px;
}

.dp-col__nophoto {
  flex: 1 1 auto;
  background: var(--dp-nophoto);
  border-radius: 2px 2px 0 0;
}

.dp-col__photo {
  flex: 0 0 auto;
  background: var(--dp-photo);
}

.dp-col__bottom {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 100%;
  height: 56px;
  padding-top: 1px;
}

.dp-col__departure {
  width: 70%;
  max-width: 14px;
  background: var(--dp-departure);
  border-radius: 0 0 2px 2px;
}

.dp-col__day {
  margin-top: 4px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
}

.dp-col__month {
  color: var(--muted);
  font-size: 9px;
}

.dp-col__weekday {
  color: var(--muted);
  font-size: 11px;
}

.dp-h--0 { height: 0; border: 0; }
.dp-h--1 { height: 4px; }
.dp-h--2 { height: 8px; }
.dp-h--3 { height: 12px; }
.dp-h--4 { height: 16px; }
.dp-h--5 { height: 20px; }
.dp-h--6 { height: 24px; }
.dp-h--7 { height: 28px; }
.dp-h--8 { height: 32px; }
.dp-h--9 { height: 36px; }
.dp-h--10 { height: 40px; }
.dp-h--11 { height: 44px; }
.dp-h--12 { height: 48px; }
.dp-h--13 { height: 52px; }

@media (max-width: 760px) {
  .date-picker {
    padding: 8px;
  }

  .dp-toolbar__range {
    font-size: 10px;
  }

  .dp-calendar__panel {
    width: min(340px, calc(100vw - 28px));
  }
}

/* --- Date timeline table -------------------------------------------------- */

/* One row per operation: time, direction, line, aircraft, registration. The
   table is the page body on /date/; photos hang beneath their own row. */
.timeline-table {
  width: 100%;
  border: 1px solid var(--line-light);
  border-collapse: collapse;
  background: var(--paper);
  font-family: "Courier New", Courier, monospace;
  font-size: 11pt;
  line-height: 1.35;
}

.timeline-table thead th {
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
}

.timeline-table td {
  padding: 8px 10px;
  border-top: 1px solid var(--line-light);
  color: var(--muted);
  vertical-align: top;
}

.timeline-table tbody:first-of-type td {
  border-top: 0;
}

.timeline-table__col-time {
  width: 84px;
}

.timeline-table .timeline-table__time {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.timeline-table__time time {
  font-weight: 700;
}

.timeline-table__dir-cell {
  width: 42px;
  padding-right: 0;
}

.timeline-table .timeline-table__place {
  padding-left: 2px;
  color: var(--ink);
  white-space: nowrap;
}

.timeline-table__dir {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5em;
  height: 1.5em;
  border-radius: 6px;
  font-size: 1em;
  font-weight: 700;
  line-height: 1;
}

.timeline-table__dir--arrival {
  color: #0f6e56;
  background: #d9f2e9;
}

.timeline-table__dir--departure {
  color: #5b4bc4;
  background: #e8e4fc;
}

.timeline-table__dir--circuit {
  color: #a15c00;
  background: #fbeacd;
}

.timeline-table__city {
  font-weight: 700;
}

.timeline-table__flight {
  color: var(--blue);
  font-weight: 700;
}

.timeline-table__city a {
  color: var(--blue);
  text-decoration: none;
}

.timeline-table__city a:hover {
  text-decoration: underline;
}

.timeline-table__flag {
  margin-left: 3px;
  font-size: 13px;
}

.timeline-table td a {
  color: var(--blue);
  text-decoration: none;
}

.timeline-table td a:hover {
  text-decoration: underline;
}

.timeline-table__empty {
  color: var(--faint);
}

.timeline-table__row--approximate .timeline-table__time,
.timeline-table__row--approximate .timeline-table__place {
  color: var(--faint);
}

.timeline-table__row--approximate .timeline-table__city {
  font-weight: 400;
}

/* The photo starts under kierunek and ends under rejestracja; the time cell
   above it stays empty, which keeps the left column a clean clock strip. */
.timeline-table__photo-row td {
  padding-top: 0;
  border-top: 0;
}

.timeline-table__photo-time {
  padding: 0;
}

.timeline-table td.timeline-table__photo {
  padding: 0 10px 10px;
}

.timeline-table__photos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 8px;
  align-items: start;
}

/* A lone photo must not stretch across every detail column: cap it at the
   width it would get beside a second photo on the same operation. Only a
   :only-child is capped; with two or more cards each keeps its grid track. */
.timeline-table__photos > .card:only-child {
  max-width: calc(50% - 4px);
}

/* Compact movement line outside /date/ (airframe history, frontpage strip and
   photo page). It keeps the badge + time + identity layout. */
.timeline__moves {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 0;
  padding: 0;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  line-height: 1.4;
  list-style: none;
}

.timeline__move {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 8px;
}

.timeline__move-time {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 5px;
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
}

.timeline__local {
  min-height: 1em;
  color: var(--faint);
  font-size: 9px;
}

/* Identity meta on a movement line: neutral colours, not the overlay palette. */
.timeline__move .card__meta {
  min-height: 0;
  margin: 0;
  color: var(--muted);
  font-size: 10px;
  -webkit-text-stroke: 0;
  text-shadow: none;
}

.timeline__move .card__meta-key {
  color: var(--faint);
}

.timeline__move .card__meta-item--route {
  color: var(--blue);
}

.timeline__move .card__meta-item--route[href]:hover {
  text-decoration: underline;
}

.timeline__move .card__country--code {
  border-color: var(--line);
}

.timeline__badge {
  position: absolute;
  top: 4px;
  left: 4px;
  z-index: 4;
  padding: 1px 5px;
  color: #fff;
  background: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}

/* On the compact movement line the badge flows inline, not as an overlay. */
.timeline__move .timeline__badge {
  position: static;
}

.timeline__badge--landing { background: var(--blue); }
.timeline__badge--takeoff { background: var(--muted); }
.timeline__badge--touch_and_go { background: var(--red); }
.timeline__badge--go_around { background: var(--orchid); }
.timeline__badge--photo { background: var(--faint); }

/* Mobile: each operation becomes two lines (plus a third for a photo). The
   time and arrow occupy the left side and span both text lines; the airport
   names the direction on line one, and line/aircraft/registration sit on line
   two. The desktop header stays in the DOM for screen readers, while its
   visible labels no longer match the transformed grid. */
@media (max-width: 760px) {
  .timeline-table {
    display: block;
    border: 0;
    background: transparent;
  }

  .timeline-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  .timeline-table__group {
    display: block;
    padding: 8px 0;
    border-top: 1px solid var(--line-light);
  }

  .timeline-table tbody:first-of-type {
    border-top: 0;
  }

  .timeline-table__row {
    display: grid;
    grid-template-columns: 54px 34px minmax(0, 1fr) auto auto;
    column-gap: 3px;
  }

  .timeline-table td {
    padding: 0;
    border: 0;
  }

  .timeline-table .timeline-table__time {
    grid-column: 1;
    grid-row: 1 / span 2;
    align-self: start;
    padding-top: 2px;
  }

  .timeline-table__dir-cell {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: start;
    padding-top: 1px;
  }

  .timeline-table__place {
    grid-column: 3;
    grid-row: 1;
    overflow: hidden;
    padding-left: 0;
    text-overflow: ellipsis;
  }

  .timeline-table__line {
    grid-column: 3;
    grid-row: 2;
    overflow: hidden;
    padding-top: 1px;
    font-size: 13px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .timeline-table__aircraft {
    grid-column: 4;
    grid-row: 2;
    padding-top: 1px;
    font-size: 13px;
    white-space: nowrap;
  }

  .timeline-table__registration {
    grid-column: 5;
    grid-row: 2;
    padding-top: 1px;
    font-size: 13px;
    white-space: nowrap;
  }

  .timeline-table__aircraft::before,
  .timeline-table__registration::before {
    color: var(--faint);
    content: "· ";
  }

  .timeline-table__photo-row {
    display: grid;
    grid-template-columns: 54px 34px minmax(0, 1fr);
  }

  .timeline-table__photo-time {
    display: none;
  }

  .timeline-table td.timeline-table__photo {
    grid-column: 2 / -1;
    padding: 8px 0 0;
  }

  .timeline-table__photos {
    grid-template-columns: 1fr;
  }

  /* The table is a single column on mobile, so a photo takes the full width. */
  .timeline-table__photos > .card:only-child {
    max-width: none;
  }
}

@media (max-width: 520px) {
  .timeline-table__row {
    grid-template-columns: 50px 32px minmax(0, 1fr) auto auto;
  }

  .timeline-table__photo-row {
    grid-template-columns: 50px 32px minmax(0, 1fr);
  }
}

/* --- Frontpage intro ------------------------------------------------------ */

/* Compact stats strip above the first frontpage block. A faint paper panel and
   a little more padding than the surrounding chrome group the at-a-glance data
   and top-list links into one visible summary. */
.front-hero {
  margin: 2px 0 18px;
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 0;
  padding: 12px 14px;
  border: 1px solid var(--line-light);
  background: var(--paper);
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  line-height: 1.5;
}

.hero-meta p {
  margin: 0;
}

.hero-stats {
  flex: 1 1 100%;
}

.hero-stats strong {
  color: var(--ink);
  font-weight: 700;
}

.hero-stats__sep {
  margin: 0 8px;
  color: var(--line);
}

/* Label/value grid shared by the top lists (operators, models, countries) and
   the day lines: the label with its colon sits in the first column and every
   value starts flush under the text that follows the colon. */
.hero-row {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline;
  column-gap: 8px;
  flex: 1 1 100%;
  min-width: 0;
}

.hero-row__label,
.hero-links__label,
.hero-day__label {
  color: var(--faint);
}

.hero-row__value {
  min-width: 0;
}

/* Top-list navigation reused for operators, models and countries. Each list
   takes its own row and links are separated by a faint middot. */
.hero-links__list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hero-links__item {
  display: inline-flex;
  align-items: baseline;
}

.hero-links__item:not(:last-child)::after {
  content: "·";
  margin: 0 8px;
  color: var(--line);
}

.hero-links__item a {
  text-decoration: none;
  white-space: nowrap;
}

.hero-day a {
  text-decoration: none;
}

.hero-links__item a:hover,
.hero-day a:hover {
  text-decoration: underline;
}

/* A titled frontpage block ("Ostatnie manewry", "Zdjęcie dnia"). */
.front-block {
  margin: 2px 0 18px;
}

/* Frontpage 30-day traffic charts, the last paper panel above the footer. */
.front-charts {
  margin: 14px 0 0;
  padding: 12px 14px 6px;
  border: 1px solid var(--line-light);
  background: var(--paper);
}

.front-charts__title {
  margin: 0 0 10px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Frontpage photo showcase: the featured photo of the day in the wide (2/3)
   left column, with the two newest photos stacked in the narrow (1/3) right
   column. */
.front-photos {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 14px;
  align-items: stretch;
  margin: 2px 0 18px;
}

.front-photos--single {
  grid-template-columns: minmax(0, 1fr);
}

.front-photos__feature,
.front-photos__aside {
  min-width: 0;
}

.front-photos__feature .front-block {
  margin-bottom: 0;
}

/* The two thumbnails fill the exact height of the 3:2 hero beside them. They
   may lose a few pixels to the crop; object-fit: cover keeps them undistorted. */
.front-photos__aside {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.front-photos__stack {
  display: grid;
  grid-auto-rows: minmax(0, 1fr);
  gap: 14px;
  flex: 1;
  min-height: 0;
}

.front-photos__stack .card {
  height: 100%;
  aspect-ratio: auto;
  min-height: 0;
}

@media (max-width: 760px) {
  .front-photos {
    grid-template-columns: minmax(0, 1fr);
  }

  .front-photos__aside {
    display: block;
  }

  .front-photos__stack {
    grid-auto-rows: auto;
    flex: none;
  }

  .front-photos__stack .card {
    height: auto;
    aspect-ratio: 3 / 2;
  }
}

/* The featured photo of the day: a 3:2 hero card. */
.photo-of-day {
  border: 1px solid var(--line);
}

.photo-of-day .card {
  border: 0;
}

@media (max-width: 520px) {
  .hero-meta {
    padding: 10px 11px;
    font-size: 10px;
  }

  .hero-stats__sep {
    display: none;
  }
}

/* --- Aircraft page: facts + flight history -------------------------------- */

.aircraft {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px 26px;
  margin: 2px 0 16px;
  padding: 12px 0 6px;
  border-top: 1px solid var(--line-light);
  border-bottom: 1px solid var(--line-light);
}

/* dt/dd pairs laid out as a two-column grid via display:contents rows. */
.aircraft-facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: start;
  gap: 3px 14px;
  margin: 0;
}

.aircraft-facts__item {
  display: contents;
}

.aircraft-facts__key {
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.aircraft-facts__value {
  margin: 0;
  color: var(--ink);
  font-size: 13px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.aircraft-facts__value a {
  text-decoration: none;
}

.aircraft-facts__value a:hover {
  text-decoration: underline;
}

.aircraft-facts__code {
  padding: 0 0.35em;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--blue);
  font-size: 0.92em;
  letter-spacing: 0.03em;
}

.aircraft-facts__detail {
  display: block;
  color: var(--faint);
  font-size: 11px;
}

.aircraft-facts__country {
  text-decoration: none;
}

.aircraft-facts__country:hover {
  text-decoration: underline;
}

.aircraft-facts__country .card__country--code {
  border-color: var(--line);
  color: var(--blue);
}

/* "Zobacz wszystkie loty z … do …" call-to-action inside the facts panel.
   Spans both grid columns so it sits under the dt/dd rows. */
.aircraft-facts__cta {
  grid-column: 1 / -1;
  margin-top: 6px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.aircraft-facts__cta a {
  color: var(--blue);
  text-decoration: none;
}

.aircraft-facts__cta a:hover {
  text-decoration: underline;
}

/* The flights panel is a flex column so its title stays put while the list
   scrolls. Inside .aircraft the list is tied to the facts column height (see
   below); standalone (operator page) and narrow screens fall back to a
   viewport cap. */
.aircraft-flights {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* The flights heading is a .section-title (see flightList); keep it fixed while
   the list scrolls. */
.aircraft-flights > .section-title {
  flex: 0 0 auto;
}

.aircraft-flights__list {
  flex: 1 1 auto;
  min-height: 0;
  max-height: min(60vh, 34rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* On the airframe pages the facts panel defines the row height; size
   containment stops the flights column from stretching it, so the list
   scrolls once it grows past the neighbouring facts. The `+` guard keeps a
   facts-less summary from collapsing to zero height. */
.aircraft .aircraft-facts + .aircraft-flights {
  contain: size;
}

.aircraft-flights__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 12px;
  padding: 3px 0;
  border-top: 1px solid var(--line-light);
}

.aircraft-flights__item:first-child {
  border-top: 0;
}

.aircraft-flights__callsign {
  font-weight: 700;
  text-decoration: none;
}

.aircraft-flights__callsign[href]:hover {
  text-decoration: underline;
}

.aircraft-flights__meta {
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* "Other flights on this relation": one block per operator, each a run of
   callsign links. Sits at the bottom of the /flight/ page. */
.related-flights {
  margin-top: 20px;
}

.related-flights__group {
  margin-bottom: 12px;
}

.related-flights__group:last-child {
  margin-bottom: 0;
}

.related-flights__operator {
  margin: 0 0 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.related-flights__operator a {
  color: var(--blue);
  text-decoration: none;
}

.related-flights__operator a:hover {
  text-decoration: underline;
}

.related-flights__list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.related-flights__callsign {
  font-weight: 700;
  text-decoration: none;
}

.related-flights__callsign:hover {
  text-decoration: underline;
}

@media (max-width: 760px) {
  .aircraft {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Single column: no sibling to match, so let the panel keep its natural
     height instead of collapsing under size containment. */
  .aircraft .aircraft-flights {
    contain: none;
  }
}

/* --- Airframe hero: most-voted photo + recent movements ------------------- */

/* The airframe's featured photo beside its movement history. The photo column
   is twice the width of the movements column; on narrow screens they stack. */
.airframe-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  margin: 18px 0;
}

.airframe-hero--split {
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

.airframe-hero__photo {
  min-width: 0;
}

/* Shown when the airframe has never been photographed: same 3:2 footprint as
   the hero card so the movements column still has a definite height to match. */
.airframe-hero__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  padding: 16px;
  border: 1px dashed var(--line);
  background: var(--paper);
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  text-align: center;
}

.airframe-hero__placeholder p {
  margin: 0;
}

.airframe-hero__movements {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* The photo fixes the row height; size containment stops the movements column
   from stretching it, so the list scrolls once it outgrows the photo. */
.airframe-hero--split .airframe-hero__movements {
  contain: size;
}

.airframe-hero__movements > .movements {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
}

.airframe-hero__movements .section-title {
  flex: 0 0 auto;
}

.airframe-hero__movements .movements__scroll {
  flex: 1 1 auto;
  min-height: 0;
  max-height: min(60vh, 34rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
}

@media (max-width: 760px) {
  .airframe-hero--split {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked: no sibling to match, so let the list keep its natural height. */
  .airframe-hero--split .airframe-hero__movements {
    contain: none;
  }
}

/* --- Airframe movement history ------------------------------------------- */

.movements {
  margin: 0 0 18px;
}

.movements__day {
  margin: 0 0 10px;
}

.movements__day:last-child {
  margin-bottom: 0;
}

.movements__day-title {
  margin: 0 0 4px;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  letter-spacing: 0.05em;
}

.movements__day-title a {
  text-decoration: none;
}

.movements__day-title a:hover {
  text-decoration: underline;
}

/* The compact movement line is tuned for the /date/ ruler; nudge it up a touch
   for the denser airframe history. */
.movements .timeline__moves {
  font-size: 11px;
}

.movements__more {
  margin: 4px 0 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
}

/* The single movement under a photo hero, next to the action bar. */
.photo-movement {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  margin: 8px 0 0;
}

.photo-movement__link {
  color: var(--blue);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  text-decoration: none;
}

.photo-movement__link:hover {
  text-decoration: underline;
}

/* --- Operator page: summary, charts and airframe tiles -------------------- */

.section-title {
  margin: 0 0 12px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.section-title__count {
  color: var(--faint);
  font-size: 13px;
  font-weight: 400;
}

.operator-intro {
  margin: 2px 0 18px;
  padding: 10px 0 4px;
  border-top: 1px solid var(--line-light);
  border-bottom: 1px solid var(--line-light);
}

.operator-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 0;
  margin: 0 0 12px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
}

.operator-stats strong {
  color: var(--ink);
}

.operator-stats .card__meta-sep {
  margin: 0 10px;
  color: var(--line);
}

.operator-charts {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 8px 26px;
  margin-bottom: 12px;
}

.operator-chart {
  min-width: 0;
}

.chart__title {
  margin: 0 0 8px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.chart__list {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chart__col {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 0;
}

/* Diverging column: takeoffs rise above the zero axis, landings drop below
   it. Both directions share one scale, so the two halves are equal height and
   the bar hugs the axis. */
.chart__stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.chart__half {
  display: flex;
  justify-content: center;
  width: 100%;
  height: 42px;
}

.chart__half--up { align-items: flex-end; }
.chart__half--down { align-items: flex-start; }

.chart__axis {
  width: 100%;
  height: 1px;
  background: var(--line);
}

.chart__bar {
  display: block;
  flex: 0 0 auto;
  width: 10px;
  max-width: 10px;
  border: 1px solid var(--line);
  background: var(--line-light);
}

.chart__half--up .chart__bar { border-bottom: 0; }
.chart__half--down .chart__bar { border-top: 0; }

.chart__bar--l0 { height: 1px; }
.chart__bar--l1 { height: 5px; }
.chart__bar--l2 { height: 10px; }
.chart__bar--l3 { height: 16px; }
.chart__bar--l4 { height: 23px; }
.chart__bar--l5 { height: 31px; }
.chart__bar--l6 { height: 40px; }

.chart__bar--landing { background: var(--blue); border-color: var(--blue); }
.chart__bar--takeoff { background: var(--line); border-color: var(--line); }

/* Current local hour / weekday, set by charts.js on the client so the cached
   HTML stays timezone-agnostic. */
.chart__col.is-now .chart__label {
  color: var(--ink);
  font-weight: 700;
}

.chart__col.is-now .chart__axis {
  background: var(--ink);
}

.chart__label {
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 8px;
  font-variant-numeric: tabular-nums;
}

.chart__legend {
  display: flex;
  gap: 12px;
  margin: 8px 0 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 9px;
}

.chart__key::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 4px;
  vertical-align: -1px;
  border: 1px solid var(--line);
}

.chart__key--landing::before { background: var(--blue); border-color: var(--blue); }
.chart__key--takeoff::before { background: var(--line); }

.chart__note {
  margin: 8px 0 0;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
}

.operator-days {
  margin: 0 0 12px;
}

.operator-days__list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.operator-days__item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
}

.operator-days__item a {
  text-decoration: none;
}

.operator-days__item a:hover {
  text-decoration: underline;
}

.operator-days__count {
  color: var(--faint);
  font-size: 10px;
}

.airframes {
  margin: 0 0 18px;
}

/* Frontpage variant: the section follows the photo grid, so give it the same
   top spacing the other frontpage blocks use. */
.airframes--front {
  margin-top: 18px;
}

/* "Statki powietrzne EPWR" renders one .airframes__list per aircraft kind, so
   space the group heading that follows a preceding list. */
.airframes__list + .section-title {
  margin-top: 16px;
}

/* A type the receiver never photographed is not a link: keep the tile static. */
.airframe__link--static {
  cursor: default;
}

.airframe__link--static:hover {
  border-color: var(--line-light);
}

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

.airframe {
  min-width: 0;
}

.airframe__link {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 100%;
  padding: 6px;
  border: 1px solid var(--line-light);
  background: var(--paper);
  color: inherit;
  text-decoration: none;
}

.airframe__link:hover {
  border-color: var(--line);
}

.airframe__media {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 76px;
  height: 56px;
  overflow: hidden;
  background: var(--background);
}

.airframe__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.airframe__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--line);
}

.airframe__plane {
  width: 34px;
  height: 34px;
  fill: currentColor;
}

.airframe__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.airframe__title {
  color: var(--ink);
  font-family: "Courier New", Courier, monospace;
  font-size: 13px;
  font-weight: 700;
}

.airframe__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 6px;
  min-height: 0;
  margin: 0;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0;
}

/* The card__meta* classes are photo-overlay styles (white text, reserved
   height); neutralise them for the paper airframe tiles. */
.airframe__meta .card__meta-key {
  color: var(--faint);
}

.airframe__meta .card__meta-sep {
  color: var(--line);
}

.airframe__meta .card__meta-item {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

.aircraft-flights__more {
  padding: 3px 0;
  border-top: 1px solid var(--line-light);
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
}

@media (max-width: 760px) {
  .operator-charts {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- FAQ ------------------------------------------------------------------ */

.faq {
  max-width: 760px;
}

.faq__toc {
  margin: 0 0 28px;
}

.faq__toc-title {
  margin: 0 0 6px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.faq__toc-list {
  margin: 0;
  padding-left: 18px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  line-height: 1.7;
}

.faq__toc-item {
  margin: 0;
}

.faq__toc a {
  color: inherit;
  text-decoration: none;
}

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

.faq__item {
  margin: 0 0 28px;
}

.faq__item:last-child {
  margin-bottom: 0;
}

.faq__question {
  margin: 0 0 10px;
  color: var(--ink);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.faq__answer {
  color: var(--ink);
  font-size: 14px;
  line-height: 1.65;
}

.faq__answer p {
  margin: 0 0 8px;
}

.faq__answer > :last-child {
  margin-bottom: 0;
}

.faq__answer > ul:not(.faq__sources) {
  margin: 0 0 8px;
  padding-left: 20px;
}

.faq__answer > ul:not(.faq__sources) > li {
  margin: 0 0 4px;
}

.faq__answer a {
  color: inherit;
}

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

.faq__sources h3 {
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 700;
}

.faq__sources p {
  margin: 0 0 6px;
}

.faq__answer code {
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
}

/* Route and approach-track map on the /flight/<CALLSIGN> and /relation/ pages
   (MapLibre + OpenFreeMap). The map container is rendered server-side and stays
   empty until flightmap.js builds the map, so the :empty rule is the no-JS /
   failed-load fallback. */
.flight-map {
  position: relative;
  height: 360px;
  margin-top: 14px;
  border: 1px solid var(--line-light);
  border-radius: 10px;
  overflow: hidden;
  background: #dde5ee;
}

.flight-map:empty::after {
  content: "Mapa jest niedostępna.";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 13px;
}

@media (max-width: 760px) {
  .flight-map {
    height: 280px;
  }
}

/* Recent manoeuvre tracks on the /hex/ and /registration/ pages. The section
   reuses the /flight/ map island in tracks-only mode. */
.airframe-map {
  margin: 0 0 18px;
}

/* Connection globe on the /relation hub page (MapLibre + OpenFreeMap). The
   container is rendered server-side and stays empty until globemap.js injects
   MapLibre and builds the globe, so the :empty rule is the no-JS /
   failed-load fallback. */
.globe-map {
  position: relative;
  height: 420px;
  border: 1px solid var(--line-light);
  border-radius: 10px;
  overflow: hidden;
  background: #0b1622;
}

/* The /relation hub: the globe beside the relation list. On desktop the globe
   column sticks to the top so it stays in view while the list scrolls; on
   narrow screens the two collapse to one column and the globe stops sticking. */
.relation-hub {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 20px;
  align-items: start;
}

.relation-hub__map {
  position: sticky;
  top: 8px;
  z-index: 2;
}

@media (max-width: 760px) {
  .relation-hub {
    grid-template-columns: minmax(0, 1fr);
  }

  .relation-hub__map {
    position: static;
  }
}

.globe-map:empty::after {
  content: "Mapa połączeń jest niedostępna.";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #8ea3b8;
  font-size: 13px;
}

/* The Wrocław hub: a CSS-only radar ping, so the page runs no animation loop
   of its own. */
.globe-hub {
  position: relative;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ffb04d;
  box-shadow: 0 0 0 2px rgba(11, 22, 34, 0.9);
}

.globe-hub::before,
.globe-hub::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid rgba(255, 176, 77, 0.7);
  animation: globe-ping 2.6s ease-out infinite;
}

.globe-hub::after {
  animation-delay: 1.3s;
}

@keyframes globe-ping {
  from {
    transform: scale(1);
    opacity: 0.8;
  }
  to {
    transform: scale(4.2);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .globe-hub::before,
  .globe-hub::after {
    animation: none;
    opacity: 0.5;
  }
}

.globe-popup {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  color: var(--ink);
}

.globe-popup__counts {
  color: var(--muted);
}

@media (max-width: 760px) {
  .globe-map {
    height: 300px;
  }
}

/* Hub / directory pages (/operator, /model, /country, /relation, /type). The
   list is dense on purpose: it is the crawl surface that keeps every group page
   one hop from the frontpage. */
.hub-intro {
  max-width: 62ch;
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
}

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

.directory__item {
  position: relative;
  min-width: 0;
  border-bottom: 1px solid var(--line-light);
}

/* Hover detail on the /relation hub rows: operators and types seen on the leg,
   revealed as an overlay so the list never reflows. `pointer-events: none`
   keeps it from swallowing the cursor as it follows the row. Pure CSS, so it
   is present in the DOM (and crawlable) even with JavaScript off. */
.directory__detail {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 5;
  margin-top: -1px;
  padding: 8px 10px;
  border: 1px solid var(--line-light);
  background: var(--paper);
  box-shadow: 0 8px 20px rgba(32, 35, 38, 0.14);
  font-size: 12px;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease;
}

.directory__item:hover .directory__detail,
.directory__item:focus-within .directory__detail {
  opacity: 1;
  visibility: visible;
}

.directory__detail-line {
  display: flex;
  gap: 8px;
  margin: 0;
}

.directory__detail-line + .directory__detail-line {
  margin-top: 4px;
}

.directory__detail-label {
  flex: 0 0 42px;
  color: var(--faint);
}

.directory__detail-items {
  min-width: 0;
}

.directory__detail-more {
  color: var(--faint);
}

.directory__detail a {
  text-decoration: none;
}

.directory__detail a:hover {
  text-decoration: underline;
}

.directory__link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 2px;
  color: inherit;
  text-decoration: none;
}

.directory__link:hover .directory__name {
  text-decoration: underline;
}

.directory__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.directory__meta {
  flex: none;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 11px;
}

/* Numbered gallery pager (?page=n). Every page number is a real link, so a
   crawler reaches all N pages of a gallery from page 1. */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 20px 0 4px;
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
}

.pager__list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pager__page,
.pager__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--line-light);
  color: inherit;
  text-decoration: none;
}

a.pager__page:hover,
a.pager__step:hover {
  border-color: var(--line);
  text-decoration: underline;
}

.pager__page.is-current {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
}

.pager__step.is-disabled {
  color: var(--faint);
  opacity: 0.5;
}

.pager__gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 30px;
  color: var(--faint);
}

/* The trailing "wszystkie" link on a frontpage top-list. */
.hero-links__all a {
  color: var(--muted);
}


/* --- Support: night-camera fundraiser ------------------------------------- */

/* Footer support block: a soft translucent panel over the range. It shares the
   footer's top rule, body type and blue accent, so the directory links and the
   fundraiser still read as one composition. Only the CTA is filled. */
.support-board {
  align-self: end;
  position: relative;
  width: 100%;
  margin: 0;
  padding: 16px 18px 18px;
  border-radius: 12px;
  background: rgba(239, 239, 240, 0.82);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  box-shadow: 0 10px 28px rgba(20, 38, 59, 0.08);
  color: var(--muted);
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  line-height: 1.45;
}

.support-board__label {
  margin: 0 0 4px;
  color: var(--faint);
  font-family: "Courier New", Courier, monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.support-board__lead {
  max-width: 560px;
  margin: 0 0 8px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.45;
}

.support-board__goals {
  margin: 0 0 10px;
  padding: 0;
  border-top: 1px solid var(--line-light);
  list-style: none;
}

.support-board__goal {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  border-bottom: 1px solid var(--line-light);
  color: var(--muted);
  font-size: 10px;
  line-height: 1.4;
}

.support-board__goal--active {
  color: var(--ink);
  font-weight: 700;
}

.support-board__status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.support-board__goal--active .support-board__status {
  color: var(--blue);
}

.support-board__check {
  font-size: 10px;
}

.support-board__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--blue);
  animation: support-blink 1.5s steps(1, end) infinite;
}

@keyframes support-blink {
  0%,
  55% {
    opacity: 1;
  }
  56%,
  100% {
    opacity: 0.2;
  }
}

.support-board__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.support-board__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--blue);
  color: #fff;
  font-family: "Courier New", Courier, monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

/* The footer's generic `.footer a:hover` rule would underline the button
   label; the extra `.footer` scope outranks it. */
.footer .support-board__cta:hover {
  background: var(--cobalt);
  color: #fff;
  text-decoration: none;
}

.support-board__cta:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

.support-board__note {
  margin: 0 0 6px;
  color: var(--faint);
  font-size: 9px;
  line-height: 1.4;
}

/* Compact contextual strip: the last row of a night /date/ table and the note
   under a night photo's action bar. */
.support-strip {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 14px;
  border: 2px solid #151515;
  background: #eef2f6;
  color: #1e3a5a;
  font-family: "Courier New", Courier, monospace;
  font-size: 12px;
  line-height: 1.45;
}

.support-strip__badge {
  flex: 0 0 auto;
  align-self: flex-start;
  padding: 3px 7px;
  background: #1e3a5a;
  color: #fff;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-decoration: none;
  text-transform: uppercase;
}

.support-strip__badge:hover {
  background: var(--blue);
  text-decoration: none;
}

.support-strip__badge:focus-visible {
  outline: 2px solid #1e3a5a;
  outline-offset: 2px;
}

.support-strip__text {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}

.support-strip__link {
  flex: 0 0 auto;
  color: #1e3a5a;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}

.support-strip__link:hover {
  color: var(--blue);
}

.support-strip__link:focus-visible {
  outline: 2px solid #1e3a5a;
  outline-offset: 2px;
}

/* /date/: the strip lives in its own tbody at the end of the operations table,
   so it reads as the last list item rather than a banner above the table. */
.timeline-table__group--support td {
  padding: 12px 10px;
  border-top: 1px solid var(--line);
  background: var(--paper);
}

/* The table's generic `td a` rule is more specific than the base strip links;
   restate both the navy CTA and the white badge inside the operations table. */
.timeline-table .support-strip__link {
  color: #1e3a5a;
  text-decoration: underline;
}

.timeline-table .support-strip__link:hover {
  color: var(--blue);
  text-decoration: underline;
}

.timeline-table .support-strip__badge,
.timeline-table .support-strip__badge:hover {
  color: #fff;
  text-decoration: none;
}

/* Empty day: the strip follows the "Brak zdarzeń." state directly. */
.timeline-wrap > .support-strip {
  margin-top: 12px;
}

/* /photo/: directly under the action bar (profile link + vote). */
.photo-actions + .support-strip {
  margin: -8px 0 18px;
}

@media (max-width: 1000px) {
  .footer__scene {
    --footer-mountains: 110px;
    padding: 28px clamp(20px, 8vw, 30px) 20px;
  }

  .footer__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    padding-top: 12px;
  }

  .support-board {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
}

@media (max-width: 760px) {
  .timeline-table__group--support {
    display: block;
    padding: 10px 0 0;
    border-top: 1px solid var(--line-light);
  }

  .timeline-table__support-row {
    display: block;
  }

  .timeline-table__group--support td {
    display: block;
    padding: 0;
    border: 0;
  }
}

@media (max-width: 520px) {
  .support-board {
    padding: 16px 16px 18px;
  }

  .support-board__lead {
    font-size: 11px;
  }

  .support-board__goal {
    font-size: 9px;
  }

  .support-board__status {
    font-size: 8px;
  }

  .support-board__cta {
    padding: 7px 10px;
    font-size: 9px;
  }

  .support-strip {
    flex-wrap: wrap;
    gap: 8px 12px;
  }

  .support-strip__text {
    flex-basis: 100%;
    order: 3;
  }

  .support-strip__link {
    margin-left: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .support-board__dot {
    animation: none;
  }
}
