/* Flights page: the seatback screen and the reel of stubs that drives it.
   Without JS the screen is hidden and the reel is a plain list by trip. */

.flights {
  --scr-sea: #0f1a22;
  --scr-land: #223440;
  --scr-coast: #3b4f59;
  --scr-grat: #18262f;
  --scr-trail: #9fb0b7;
  --scr-route: #e8694d;
  --scr-gold: #e3bd5e;
  --scr-gold-trail: #c9a650;
  --scr-dot: #647a86;
  --scr-text: #d7e3e3;
  --gold: #c9a650;
}

.no-js .js-only { display: none; }

.fl { padding-top: clamp(40px, 6vw, 72px); }
.fl__label { margin-bottom: 14px; text-align: center; }

/* ---------- the screen ---------- */

.screen-fig { width: min(100%, calc(62svh * 2)); margin: 0 auto; }
.screen {
  position: relative;
  padding: 10px;
  background: var(--slate-4);
  border-radius: 14px;
  box-shadow: var(--shadow-3);
}
.screen__glass {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 8px;
  background: var(--scr-sea);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .6), inset 0 2px 6px rgba(0, 0, 0, .5);
}
.screen__glass::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(135deg, rgba(255, 255, 255, .07), transparent 40%);
  border-radius: inherit;
}
.screen__map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  --u: 1;
}

.screen__map .sea { fill: var(--scr-sea); }
.screen__map .grat { fill: none; stroke: var(--scr-grat); stroke-width: .5px; vector-effect: non-scaling-stroke; }
.screen__map .land { fill: var(--scr-land); stroke: var(--scr-coast); stroke-width: .75px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.screen__map .dots circle { fill: var(--scr-dot); r: calc(var(--u) * 1.6px); }

.rt {
  display: none;
  fill: none;
  stroke: var(--scr-trail);
  stroke-width: 1.25px;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: .32;
  transition: opacity .25s;
}
.rt.is-past, .is-intro .rt { display: inline; }
.is-intro .rt--gold { stroke: var(--scr-gold-trail); opacity: .6; }
.is-intro .ends, .is-intro .plane, .is-intro .glow { display: none; }
.rt--gold.is-past { stroke: var(--scr-gold-trail); stroke-width: 1.5px; opacity: .55; }
/* The current route scales its own stroke with the zoom (--u, map units per
   pixel) rather than using non-scaling-stroke, so its dash length is in map
   units and the draw ends exactly at the destination. */
.rt.is-cur { display: inline; stroke: var(--scr-route); stroke-width: calc(var(--u) * 2px); vector-effect: none; opacity: 1; }
.rt--gold.is-cur { stroke: var(--scr-gold); }

.glow {
  fill: none;
  stroke: var(--scr-route);
  stroke-width: calc(var(--u) * 6px);
  stroke-linecap: round;
  opacity: .18;
}
.is-gold .glow { stroke: var(--scr-gold); }

.end {
  fill: #fbfbf8;
  stroke: var(--scr-route);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
  r: calc(var(--u) * 3px);
}
.is-gold .end { stroke: var(--scr-gold); }
.code {
  font-family: var(--mono);
  font-weight: 500;
  font-size: calc(var(--u) * 11px);
  letter-spacing: .06em;
  fill: var(--scr-text);
  paint-order: stroke;
  stroke: var(--scr-sea);
  stroke-width: calc(var(--u) * 3px);
  stroke-linejoin: round;
}
.plane { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); }

/* the readout bar along the bottom of the screen */
.readout {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "route route" "count date";
  align-items: end;
  gap: 4px 12px;
  padding: 9px 12px 10px;
  background: rgba(15, 26, 34, .82);
  border-top: 1px solid rgba(215, 227, 227, .14);
  color: var(--scr-text);
}
.readout p { margin: 0; }
.readout__count { grid-area: count; font-size: .64rem; color: var(--slate-1); }
.readout__season { margin-left: 10px; color: var(--scr-route); }
.readout__season:empty { display: none; }
.readout__route { grid-area: route; min-width: 0; }
.readout__codes { font-size: 1.05rem; font-weight: 560; color: #f4f5f1; line-height: 1.2; }
.readout__meta {
  margin-top: 2px !important;
  font-size: .62rem;
  color: var(--slate-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.readout__date { grid-area: date; font-size: .64rem; color: var(--slate-1); text-align: right; }

.screen__caption {
  margin: 14px 0 0;
  text-align: center;
  font-style: italic;
  font-size: .95rem;
  color: var(--ink-2);
}
.screen__caption:empty::before { content: "\00a0"; }

@media (min-width: 760px) {
  .screen__glass { aspect-ratio: 2 / 1; }
  .readout {
    grid-template-columns: 1fr 2fr 1fr;
    grid-template-areas: "count route date";
    align-items: center;
    gap: 16px;
    padding: 10px 14px;
  }
  .readout__route { text-align: center; }
  .readout__codes { font-size: 1.15rem; }
  .readout__meta { font-size: .68rem; }
  .readout__count, .readout__date { font-size: .7rem; }
  .screen__caption { font-size: 1.02rem; }
}

/* ---------- the stubs ---------- */

.fl__list-title { margin: clamp(40px, 6vw, 64px) 0 20px; font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.1rem); font-weight: 450; }

.trip { margin-bottom: 26px; }
.trip__name { margin: 0 0 12px; font-size: 1.1rem; font-weight: 500; }
.trip__when { margin-left: 8px; font-family: var(--mono); font-size: .7rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.trip__legs { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; padding: 0; list-style: none; }
.trip__end { display: none; }

.leg {
  --bar: var(--slate-2);
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 156px;
  height: 92px;
  padding: 9px 42px 9px 12px;
  background: var(--card);
  border-left: 5px solid var(--bar);
  border-radius: 8px;
  filter: drop-shadow(0 1px 1px rgba(27, 37, 40, .12)) drop-shadow(0 6px 8px rgba(27, 37, 40, .16));
  color: var(--ink);
}
.leg--season { --bar: var(--ver); }
.leg--gold { --bar: var(--gold); }
/* perforation and the stub number */
.leg::after {
  content: "";
  position: absolute;
  top: 8px; bottom: 8px; right: 34px;
  border-right: 1.5px dashed var(--slate-1);
}
.leg__n {
  position: absolute;
  top: 50%; right: 0;
  width: 34px;
  transform: translateY(-50%) rotate(90deg);
  font-family: var(--mono);
  font-size: .66rem;
  font-weight: 500;
  text-align: center;
  color: var(--ink-2);
}
.leg__top {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  font-family: var(--mono);
  font-size: .6rem;
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--ink-2);
  white-space: nowrap;
}
.leg__top span:last-child { overflow: hidden; text-overflow: ellipsis; }
.leg__codes { font-size: 1.18rem; font-weight: 560; line-height: 1.1; white-space: nowrap; }
.leg__codes [aria-hidden] { color: var(--ink-2); font-weight: 400; }
.leg__cities, .leg__meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.leg__cities { font-size: .76rem; color: var(--ink-2); line-height: 1.2; }
.leg__meta { font-family: var(--mono); font-size: .58rem; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); }

/* ---------- with JS: one reel under the screen ---------- */

.js .fl__list-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.js .reel {
  --leg: 156px;
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 8px calc(var(--gutter) * -1) 0;
  padding: 22px calc(50% + var(--gutter) - var(--leg) / 2) 26px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none; /* the belt underneath shows it scrolls */
  outline: none;
  /* flights.js drives sideways drags and flings; the page keeps vertical scrolling */
  touch-action: pan-y pinch-zoom;
  overflow-x: hidden; /* no native momentum to fight the flywheel; scrollLeft still moves it */
  cursor: grab;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.js .reel.is-dragging { cursor: grabbing; }
.js .reel.is-dragging .leg { pointer-events: none; }
.js .trip, .js .trip__legs { display: contents; }
.js .trip__name {
  flex: none;
  align-self: stretch;
  width: 14px;
  margin: 10px 0;
  font-size: 0;
  border-left: 1.5px dashed var(--slate-1);
  margin-left: 6px;
}
.js .trip__name .trip__when { display: none; }
.js .trip--start .trip__name, .js .trip__end {
  position: relative;
  display: block;
  flex: none;
  align-self: stretch;
  width: 58px;
  margin: 10px 0;
  border-left: 1.5px dashed var(--ver);
  font-size: 0;
}
.js .trip--start .trip__name::after, .js .trip__end::after {
  position: absolute;
  top: 50%; left: 8px;
  width: 44px;
  padding: 3px 4px;
  transform: translateY(-50%) rotate(-8deg);
  border: 1.5px solid currentColor;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: .5rem;
  font-weight: 500;
  letter-spacing: .08em;
  line-height: 1.25;
  text-transform: uppercase;
  text-align: center;
  color: var(--ver);
  opacity: .88;
}
.js .trip--start .trip__name::after { content: "45 weeks start"; }
.js .trip__end::after { content: "45 weeks end"; }

/* box-shadow, not drop-shadow filters: 76 filtered stubs were too slow to repaint mid-fling */
.js .leg {
  filter: none;
  box-shadow: 0 1px 1px rgba(27, 37, 40, .12), 0 6px 8px rgba(27, 37, 40, .14);
  cursor: pointer;
  opacity: .74;
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.js .leg:hover { transform: translateY(-3px); opacity: .9; }
.js .leg.is-active {
  transform: translateY(-6px);
  opacity: 1;
  box-shadow: 0 2px 4px rgba(27, 37, 40, .12), 0 16px 22px rgba(27, 37, 40, .26);
}
.leg:focus-visible { outline: 3px solid var(--ver); outline-offset: 3px; }

/* The belt under the reel says "this moves sideways" without words: its ticks
   bob left and right while idle and run with the reel like a conveyor once it
   moves. The notch marks the centre, where the selected stub sits. */
.belt {
  position: relative;
  width: min(100%, 560px);
  height: 16px;
  margin: 0 auto;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent);
}
.belt::before {
  content: "";
  position: absolute;
  top: 3px; bottom: 3px; left: -60px; right: -60px;
  background:
    repeating-linear-gradient(90deg, var(--slate-2) 0 2px, transparent 2px 60px),
    repeating-linear-gradient(90deg, var(--slate-2) 0 1.5px, transparent 1.5px 12px) 0 50% / 100% 50% repeat-x;
  translate: var(--bx, 0px) 0; /* set by flights.js as the reel moves; the bob uses transform */
  animation: belt-bob 2.8s ease-in-out infinite;
}
.belt.is-live::before { animation-play-state: paused; }
.belt__notch {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 2px;
  margin-left: -1px;
  background: var(--ver);
  border-radius: 1px;
}
@keyframes belt-bob {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-14px); }
  75% { transform: translateX(14px); }
}

/* the reel shows it scrolls by giving a little shove the first time it comes into view */
.js .reel.is-nudge { animation: reel-nudge 1.5s var(--ease) .3s both; }
@keyframes reel-nudge {
  0%, 100% { transform: translateX(0); }
  28% { transform: translateX(-34px); }
  52% { transform: translateX(0); }
  72% { transform: translateX(-12px); }
}

@media (min-width: 760px) {
  .leg { width: 188px; height: 100px; padding: 10px 44px 10px 14px; }
  .leg__codes { font-size: 1.3rem; }
  .js .reel { --leg: 188px; gap: 16px; }
}

/* the hero line on the main page links here; see a.hl in site.css */

/* ---------- the passport: one stamp per country ---------- */

.passport { margin-top: clamp(64px, 9vw, 104px); }
.passport__head { max-width: 40rem; margin-bottom: clamp(24px, 4vw, 36px); }
.passport__head .label { margin-bottom: 10px; color: var(--slate-3); }
.passport__title { font-size: clamp(1.8rem, 1.3rem + 2.2vw, 2.8rem); font-weight: 450; }
.passport__lead { margin-top: 12px; color: var(--ink-2); }

.passport__page {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 26px 6px;
  margin: 0;
  padding: clamp(34px, 5vw, 48px) clamp(16px, 4vw, 40px) clamp(24px, 4vw, 40px);
  list-style: none;
  background:
    repeating-linear-gradient(0deg, transparent 0 27px, rgba(100, 122, 134, .07) 27px 28px),
    radial-gradient(ellipse at 50% 40%, rgba(201, 214, 194, .35), transparent 70%),
    var(--card);
  border-radius: 10px;
  box-shadow: var(--shadow-2);
}
.passport__page::before {
  content: "Visas \00b7  Visas \00b7  Visas";
  position: absolute;
  top: 12px; left: 0; right: 0;
  font-family: var(--mono);
  font-size: .58rem;
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  text-align: center;
  color: var(--slate-1);
}

/* every stamp sits in the same size slot so the tallies line up */
.visa {
  display: grid;
  grid-template-rows: 100px auto;
  justify-items: center;
  align-items: center;
  gap: 8px;
  --c: var(--slate-3);
}
.visa--ver { --c: var(--ver); }
.visa--sage { --c: var(--sage-4); }

.visa__ink {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 96px;
  max-width: 100%;
  position: relative;
  border: 2.5px solid var(--c);
  color: var(--c);
  font-family: var(--mono);
  font-weight: 500;
  text-transform: uppercase;
  text-align: center;
  transform: rotate(var(--tilt, -4deg));
  mix-blend-mode: multiply;
  opacity: .88;
  transition: opacity .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
/* the inner ring, drawn as its own box so older Safari keeps it round */
.visa__ink::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid var(--c);
  border-radius: inherit;
  pointer-events: none;
}
.visa--round .visa__ink { aspect-ratio: 1; border-radius: 50%; }
.visa--oval .visa__ink { width: 104px; aspect-ratio: 1.45; border-radius: 50%; }
.visa--box .visa__ink { padding: 10px 6px 9px; border-radius: 6px; }
.visa__country { max-width: 82%; font-size: .5rem; letter-spacing: .1em; line-height: 1.2; }
.visa__code { font-size: 1.22rem; letter-spacing: .08em; line-height: 1.15; }
.visa__date { font-size: .52rem; letter-spacing: .1em; }

.visa__tally {
  font-family: var(--mono);
  font-size: .6rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}
.visa__flag { font-size: .9rem; letter-spacing: 0; vertical-align: -2px; }
.visa__n { color: var(--ink); }

/* with JS the passport follows the reel */
.js .visa.is-blank .visa__ink { opacity: .16; color: var(--slate-1); border-color: var(--slate-1); }
.js .visa.is-blank .visa__ink::before { border-color: transparent; }
.js .visa.is-blank .visa__ink > * { visibility: hidden; }
.js .visa.is-blank .visa__tally { visibility: hidden; }
.js .visa.is-here .visa__ink { opacity: 1; }
.js .visa.is-here .visa__tally { color: var(--c); }
.js .visa.is-new .visa__ink { animation: stamp .5s var(--ease) both; }

@keyframes stamp {
  0% { transform: rotate(var(--tilt)) scale(1.5); opacity: 0; }
  55% { transform: rotate(var(--tilt)) scale(.93); opacity: 1; }
  100% { transform: rotate(var(--tilt)) scale(1); opacity: .88; }
}

@media (min-width: 760px) {
  .passport__page { grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); gap: 36px 18px; }
  .visa { grid-template-rows: 118px auto; }
  .visa__ink { width: 112px; }
  .visa--oval .visa__ink { width: 124px; }
  .visa__country { font-size: .56rem; }
  .visa__code { font-size: 1.4rem; }
  .visa__date { font-size: .58rem; }
}

/* ---------- stats for nerds: a native details drawer, dark like the screen ---------- */

.nerd { max-width: 980px; margin: 22px auto 0; }
.nerd__tab { display: flex; justify-content: center; list-style: none; cursor: pointer; }
.nerd__tab::-webkit-details-marker { display: none; }
.nerd__tab .mono {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--slate-4);
  color: #edf2ec;
  border-radius: 999px;
  box-shadow: var(--shadow-1);
  transition: background .25s var(--ease);
}
/* the +/– sits in an aria-hidden span, so screen readers hear only the name and its state */
.nerd__sign::after { content: "+"; font-size: .9rem; line-height: 1; color: var(--scr-route); }
.nerd[open] .nerd__sign::after { content: "\2013"; }
.nerd__tab:hover .mono { background: var(--slate-3); }
.nerd__tab:focus-visible { outline: none; }
.nerd__tab:focus-visible .mono { outline: 3px solid var(--ver); outline-offset: 3px; }

.nerd__body {
  margin-top: 16px;
  padding: clamp(18px, 4vw, 32px);
  background: var(--slate-4);
  color: var(--scr-text);
  border-radius: 12px;
  box-shadow: var(--shadow-3);
}
.nerd__head {
  margin: 26px 0 10px;
  font-family: var(--mono);
  font-size: .66rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--slate-1);
}
.nerd__head:first-child { margin-top: 0; }

.nerd__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 1px;
  margin: 0;
  background: rgba(215, 227, 227, .12);
  border-radius: 8px;
  overflow: hidden;
}
.nerd__stat { padding: 12px 14px; background: #1f2c33; }
.nerd dt { font-family: var(--mono); font-size: .6rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--slate-1); }
.nerd__stat dd { margin: 4px 0 0; }
.nerd__stat strong { display: block; font-size: clamp(1.15rem, .95rem + 1vw, 1.45rem); font-weight: 500; line-height: 1.15; white-space: nowrap; color: #f4f5f1; }
.nerd__stat span { display: block; margin-top: 3px; font-family: var(--mono); font-size: .58rem; letter-spacing: .06em; color: var(--slate-1); }
.nerd__grid--season strong { color: var(--scr-route); }

.nerd__records { margin: 0; }
.nerd__records > div { display: grid; gap: 2px; padding: 9px 0; border-top: 1px dashed rgba(215, 227, 227, .16); }
.nerd__records dd { margin: 0; font-size: .92rem; color: #f4f5f1; }

.nerd__years { margin: 0; padding: 0; list-style: none; }
.nerd__years li { display: grid; grid-template-columns: 3rem 1fr 2rem; align-items: center; gap: 10px; padding: 4px 0; }
.nerd__year, .nerd__count { font-family: var(--mono); font-size: .7rem; color: var(--slate-1); }
.nerd__count { text-align: right; color: #f4f5f1; }
.nerd__bar { height: 10px; width: calc(var(--w) * 100%); background: var(--scr-route); border-radius: 2px; }

@media (min-width: 760px) {
  .nerd__records > div { grid-template-columns: 12rem 1fr; gap: 16px; align-items: baseline; }
}
.js .reel::-webkit-scrollbar { display: none; }
