/* ==========================================================================
   Förde F1 — location & time aware ferry board
   Palette shifts with the user's local time of day (html[data-daypart]).
   ========================================================================== */

/* --- tokens ------------------------------------------------------------- */
:root {
  --font: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --ink: #f2f7fa;
  --ink-soft: rgba(242, 247, 250, 0.72);
  /* 0.5 measured 4.38:1 against the day palette — under WCAG AA's 4.5:1 for
     normal text. 0.7 clears it against every daypart background (min 4.95). */
  --ink-faint: rgba(242, 247, 250, 0.7);

  --glass: rgba(6, 22, 33, 0.55);
  --glass-strong: rgba(5, 18, 28, 0.72);
  --glass-line: rgba(255, 255, 255, 0.13);
  --glass-line-soft: rgba(255, 255, 255, 0.07);

  --ok: #34d399;
  --warn: #fbbf24;
  --bad: #fb7185;

  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 26px;

  --shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.2), 0 12px 32px -12px rgba(0, 0, 0, 0.55);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, 0.25), 0 28px 60px -22px rgba(0, 0, 0, 0.7);

  --ease: cubic-bezier(0.22, 0.9, 0.3, 1);
  --dur: 240ms;

  --sp-1: 6px;  --sp-2: 10px; --sp-3: 16px;
  --sp-4: 24px; --sp-5: 36px; --sp-6: 56px;
}

/* --- daypart palettes --------------------------------------------------- */
html[data-daypart='dawn'] {
  --sky-1: #12102b; --sky-2: #4a2a52; --sky-3: #b55a5a; --sky-4: #e79a63;
  --sea-1: rgba(70, 46, 82, 0.55); --sea-2: rgba(24, 20, 48, 0.85);
  --accent: #ffb27a; --accent-2: #7ec8e3; --sun: #ffd2a1; --sun-y: 74%;
}
html[data-daypart='day'] {
  --sky-1: #062c50; --sky-2: #0b4d78; --sky-3: #12799f; --sky-4: #4fb3c4;
  --sea-1: rgba(11, 77, 120, 0.6); --sea-2: rgba(4, 32, 56, 0.9);
  --accent: #7fe3d4; --accent-2: #ffd166; --sun: #ffe9b8; --sun-y: 24%;
}
html[data-daypart='dusk'] {
  --sky-1: #17123a; --sky-2: #4b2359; --sky-3: #a33b62; --sky-4: #f08a4b;
  --sea-1: rgba(75, 35, 89, 0.6); --sea-2: rgba(14, 12, 40, 0.9);
  --accent: #ffb457; --accent-2: #ff8fa3; --sun: #ffc06b; --sun-y: 68%;
}
html[data-daypart='night'] {
  --sky-1: #03070f; --sky-2: #071b2c; --sky-3: #0b3040; --sky-4: #12545c;
  --sea-1: rgba(7, 27, 44, 0.7); --sea-2: rgba(2, 6, 14, 0.95);
  --accent: #6ee7f5; --accent-2: #a5b4fc; --sun: #cfe9ff; --sun-y: 86%;
}

/* --- base --------------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { min-height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--sky-1);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { list-style: none; padding: 0; }
a { color: var(--accent); text-underline-offset: 3px; }
button, select { font: inherit; color: inherit; }
button { cursor: pointer; }
/* Class-based display rules outrank the UA [hidden] rule — restore it. */
[hidden] { display: none !important; }

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

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* --- ambient sky -------------------------------------------------------- */
.sky {
  position: fixed; inset: 0; z-index: -1; overflow: hidden;
  background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 42%, var(--sky-3) 74%, var(--sky-4) 100%);
  transition: background 900ms var(--ease);
}
.glow {
  position: absolute; border-radius: 50%; filter: blur(90px); opacity: 0.5;
  transition: background 900ms var(--ease);
  will-change: transform;
}
.glow--a {
  width: 46vmax; height: 46vmax; top: -14vmax; left: -10vmax;
  background: radial-gradient(circle, var(--accent) 0%, transparent 68%);
  animation: drift-a 28s ease-in-out infinite alternate;
}
.glow--b {
  width: 38vmax; height: 38vmax; top: 18vmax; right: -12vmax;
  background: radial-gradient(circle, var(--accent-2) 0%, transparent 68%);
  animation: drift-b 34s ease-in-out infinite alternate;
}
.sun {
  position: absolute; left: 50%; top: var(--sun-y);
  width: 190px; height: 190px; margin-left: -95px; border-radius: 50%;
  background: radial-gradient(circle, var(--sun) 0%, rgba(255, 255, 255, 0) 62%);
  opacity: 0.65; filter: blur(6px);
  transition: top 900ms var(--ease), background 900ms var(--ease);
}
@keyframes drift-a { to { transform: translate3d(8vmax, 5vmax, 0) scale(1.12); } }
@keyframes drift-b { to { transform: translate3d(-7vmax, -4vmax, 0) scale(1.08); } }

.sea { position: absolute; left: 0; right: 0; bottom: 0; height: 34vh; min-height: 190px; }
.wave { position: absolute; bottom: 0; left: 0; width: 220%; height: 100%; }
.wave path { fill: var(--sea-1); transition: fill 900ms var(--ease); }
.wave--front path { fill: var(--sea-2); }
.wave--back { animation: swell 19s linear infinite; opacity: 0.85; }
.wave--front { animation: swell 13s linear infinite reverse; }
@keyframes swell { from { transform: translateX(0); } to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  .glow--a, .glow--b, .wave--back, .wave--front { animation: none !important; }
  * { transition-duration: 1ms !important; }
}

/* --- layout ------------------------------------------------------------- */
.wrap {
  width: min(680px, 100%);
  margin: 0 auto;
  padding: 0 var(--sp-3) calc(var(--sp-6) + env(safe-area-inset-bottom));
  display: grid;
  gap: var(--sp-4);
}
/* Grid items default to min-width:auto, which lets the horizontally scrollable
   route strip and timetable stretch the whole page. Pin them to the track. */
.wrap > * { min-width: 0; }
.section-h {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: var(--sp-2);
}

/* --- topbar ------------------------------------------------------------- */
.topbar {
  width: min(680px, 100%);
  margin: 0 auto;
  padding: calc(var(--sp-4) + env(safe-area-inset-top)) var(--sp-3) var(--sp-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
}
.brand { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.brand__mark {
  display: grid; place-items: center; width: 42px; height: 42px; flex: none;
  border-radius: 14px; color: var(--accent);
  background: var(--glass); border: 1px solid var(--glass-line);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.brand__mark svg { width: 24px; height: 24px; }
.brand__text { display: grid; line-height: 1.2; min-width: 0; }
.brand__text strong {
  font-size: 1.02rem; font-weight: 600; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand__line {
  display: inline-block; padding: 1px 7px; margin-left: 2px; border-radius: 7px;
  background: var(--accent); color: #06202c; font-size: 0.8rem; font-weight: 700;
}
.brand__text small {
  font-size: 0.74rem; color: var(--ink-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.topbar__right { display: flex; align-items: center; gap: var(--sp-2); }
.clock { display: grid; justify-items: end; line-height: 1.2; }
.clock__time { font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; }
/* reserve: empty in the markup, one line once the date is rendered.
   nowrap keeps it to that one line — wrapping it squeezed the brand. */
.clock__date {
  font-size: 0.72rem; color: var(--ink-faint);
  min-height: 1.2em; white-space: nowrap;
}

.langswitch {
  display: flex; padding: 3px; border-radius: 999px;
  background: var(--glass); border: 1px solid var(--glass-line);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.langswitch button {
  min-width: 40px; min-height: 32px; padding: 0 var(--sp-2);
  border: 0; border-radius: 999px; background: transparent;
  font-size: 0.74rem; font-weight: 600; color: var(--ink-faint);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.langswitch button:hover { color: var(--ink); }
.langswitch button.is-active { background: rgba(255, 255, 255, 0.16); color: var(--ink); }

/* --- notices ------------------------------------------------------------ */
.notices { display: grid; gap: var(--sp-2); }
.notice {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  font-size: 0.82rem; line-height: 1.5;
  background: rgba(251, 191, 36, 0.12);
  border: 1px solid rgba(251, 191, 36, 0.34);
  color: #ffe9b8;
}
.notice svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }
.notice a { color: inherit; }

/* --- locate ------------------------------------------------------------- */
.locate {
  padding: var(--sp-3);
  border-radius: var(--r-md);
  background: var(--glass); border: 1px solid var(--glass-line);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-soft);
  display: grid; gap: var(--sp-3);
}
.locate__status { display: flex; align-items: center; gap: var(--sp-2); min-height: 24px; }
.locate__icon { display: grid; place-items: center; color: var(--accent); flex: none; }
.locate__icon svg { width: 19px; height: 19px; }
/* reserve: "Standort noch nicht bestimmt" is one line, but every message that
   replaces it ("Du bist 400 m von … entfernt · ca. 5 Min zu Fuß") runs to two,
   which pushed the whole board down on first render. */
.locate__text { font-size: 0.9rem; line-height: 1.45; color: var(--ink-soft); min-height: 2.9em; }
.locate__text b { color: var(--ink); font-weight: 600; }
.locate.is-busy .locate__icon { animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: 0.35; } }

.locate__actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: flex-end; }
.btn {
  min-height: 44px; padding: 0 var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--glass-line);
  background: rgba(255, 255, 255, 0.09); color: var(--ink);
  font-size: 0.86rem; font-weight: 600;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.btn:hover { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.25); }
.btn:active { transform: translateY(1px); }
.field { display: grid; gap: 5px; flex: 1 1 200px; min-width: 0; }
.field__label {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-faint);
}
.field__select {
  width: 100%; min-height: 44px; padding: 0 34px 0 var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--glass-line);
  background-color: rgba(255, 255, 255, 0.09);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f2f7fa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 17px;
  appearance: none; -webkit-appearance: none;
  font-size: 0.9rem; font-weight: 500; cursor: pointer;
}
.field__select option { background: #08202e; color: #f2f7fa; }

/* --- direction segmented control --------------------------------------- */
.segmented {
  position: relative; display: grid; grid-template-columns: 1fr 1fr;
  padding: 4px; border-radius: 999px;
  background: var(--glass); border: 1px solid var(--glass-line);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
}
.segmented__btn {
  position: relative; z-index: 1;
  min-height: 42px; border: 0; border-radius: 999px; background: transparent;
  font-size: 0.86rem; font-weight: 600; color: var(--ink-faint);
  transition: color var(--dur) var(--ease);
  padding: 0 var(--sp-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.segmented__btn.is-active { color: #06202c; }
.segmented__thumb {
  position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 4px;
  width: calc(50% - 4px); border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 6px 18px -6px rgba(0, 0, 0, 0.6);
  transition: transform var(--dur) var(--ease), background 900ms var(--ease);
}
.segmented[data-direction='cityward'] .segmented__thumb { transform: translateX(100%); }

/* Nothing sails from this pier in this direction: the countdown, clock and
   progress rail have nothing to say, so the verdict line carries the message
   alone rather than sitting under empty placeholders. */
.hero.is-empty .hero__body,
.hero.is-empty .hero__rail { display: none; }
.hero.is-empty .hero__verdict { margin-top: 0; }

/* --- hero --------------------------------------------------------------- */
.hero {
  position: relative; overflow: hidden;
  padding: var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--glass-strong);
  border: 1px solid var(--glass-line);
  backdrop-filter: blur(26px) saturate(1.3); -webkit-backdrop-filter: blur(26px) saturate(1.3);
  box-shadow: var(--shadow-lift);
  display: grid; gap: var(--sp-3);
}
.hero::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 12% 0%, rgba(255, 255, 255, 0.14), transparent 58%);
}
/* The hero is empty markup until app.js fills it, which used to move every
   section below it once the script ran — a single 0.37 layout shift, the whole
   of the page's CLS. The three rules marked "reserve" below hold the space the
   filled hero will need, so first paint and populated paint are the same size.
   Heights measured at 320–768px against the longest verdict string. */
.hero__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  min-height: 1.45rem; /* reserve: the service chip arrives with the first render */
}
.hero__eyebrow {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--ink-faint);
}
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: 999px;
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.02em;
}
.chip svg { width: 13px; height: 13px; }
.chip--service {
  background: rgba(255, 255, 255, 0.08); color: var(--ink-soft);
  border: 1px solid var(--glass-line);
}

.hero__body { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
/* Narrow screens wrapped the countdown and the meta block onto separate rows
   only once real text replaced the "—" placeholders, so the row count itself
   changed under the user. Stack them unconditionally instead: same height
   before and after. */
@media (max-width: 400px) {
  .brand__text strong { font-size: 0.94rem; }
  .brand__text small { font-size: 0.68rem; }
  .hero__body { flex-direction: column; align-items: flex-start; }
  /* reserve: below this width the eyebrow and the service chip cannot sit on
     one row once the chip has text, so the head becomes two rows. */
  .hero__head { min-height: 2.25rem; }
}
.hero__countdown { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.hero__value {
  font-size: clamp(3.4rem, 16vw, 5.2rem); font-weight: 700; line-height: 0.9;
  letter-spacing: -0.045em; font-variant-numeric: tabular-nums;
  background: linear-gradient(160deg, #fff 10%, var(--accent) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* "9:55 Std" is far wider than "17 Min" — shrink it so the card stays one row. */
.hero.is-hours .hero__value { font-size: clamp(2.5rem, 11vw, 3.6rem); }
.hero__unit { font-size: 1rem; font-weight: 600; color: var(--ink-faint); }
.hero__meta { text-align: right; margin-left: auto; }
.hero__time { font-size: 1.75rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.hero__from, .hero__to { font-size: 0.84rem; color: var(--ink-soft); line-height: 1.5; }
.hero__to { color: var(--ink-faint); }

.hero__rail { height: 5px; border-radius: 999px; background: rgba(255, 255, 255, 0.11); overflow: hidden; }
.hero__railfill {
  display: block; height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  transition: width 900ms var(--ease);
}

.hero__verdict {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.88rem; font-weight: 500; line-height: 1.45;
  min-height: 2.9em; /* reserve: two lines, the common length once filled */
}
.hero__verdict svg { width: 17px; height: 17px; flex: none; }
.hero__verdict[data-tone='ok'] { color: var(--ok); }
.hero__verdict[data-tone='warn'] { color: var(--warn); }
.hero__verdict[data-tone='bad'] { color: var(--bad); }
.hero__verdict[data-tone='none'] { color: var(--ink-faint); }
.hero.is-imminent .hero__value { animation: beat 1.6s ease-in-out infinite; }
@keyframes beat { 50% { opacity: 0.62; } }

/* --- route strip -------------------------------------------------------- */
/* reserve: the strip is an empty <ol> until app.js renders the call list, and
   growing to one row of stops shifted everything below it. One stop row is
   58px plus the scroll padding. */
.route__list {
  min-height: 68px;
  display: flex; gap: 0; overflow-x: auto; padding-bottom: var(--sp-2);
  scrollbar-width: none; scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  /* Soften the cut-off stops at either edge so the strip reads as scrollable. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
}
.route__list::-webkit-scrollbar { display: none; }
.stop {
  position: relative; flex: 0 0 auto; width: 96px;
  padding-top: 26px; text-align: center; scroll-snap-align: center;
}
.stop::before {
  content: ''; position: absolute; top: 9px; left: 0; right: 0; height: 2px;
  background: rgba(255, 255, 255, 0.16);
}
.stop:first-child::before { left: 50%; }
.stop:last-child::before { right: 50%; }
.stop__dot {
  position: absolute; top: 4px; left: 50%; width: 12px; height: 12px; margin-left: -6px;
  border-radius: 50%; background: var(--sky-2); border: 2px solid rgba(255, 255, 255, 0.4);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.stop__name {
  display: block; font-size: 0.72rem; font-weight: 500; color: var(--ink-faint);
  line-height: 1.3; padding: 0 4px;
}
.stop__time {
  display: block; font-size: 0.82rem; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--ink-soft); margin-top: 2px;
}
.stop.is-past .stop__name, .stop.is-past .stop__time { opacity: 0.42; }
.stop.is-you .stop__dot {
  background: var(--accent); border-color: var(--accent); transform: scale(1.5);
  box-shadow: 0 0 0 5px rgba(255, 255, 255, 0.1);
}
.stop.is-you .stop__name { color: var(--ink); font-weight: 700; }
.stop.is-you .stop__time { color: var(--accent); }
.stop.is-seasonal .stop__name::after { content: ' *'; color: var(--warn); }

/* --- upcoming list ------------------------------------------------------ */
.upcoming__list { display: grid; gap: var(--sp-2); }
.dep {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-md);
  background: var(--glass); border: 1px solid var(--glass-line-soft);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
  animation: rise var(--dur) var(--ease) both;
}
.dep:hover { background: rgba(255, 255, 255, 0.09); border-color: var(--glass-line); }
@keyframes rise { from { opacity: 0; transform: translateY(9px); } }
.dep__time {
  font-size: 1.22rem; font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em; flex: none; min-width: 62px;
}
.dep__info { display: grid; gap: 2px; min-width: 0; flex: 1; }
.dep__dest { font-size: 0.86rem; font-weight: 500; }
.dep__via { font-size: 0.74rem; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep__in {
  flex: none; text-align: right; white-space: nowrap;
  font-size: 0.82rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--accent);
}
.dep__in small { font-size: 0.72rem; font-weight: 500; color: var(--ink-faint); margin-right: 3px; }

.empty {
  padding: var(--sp-4) var(--sp-3); text-align: center;
  font-size: 0.88rem; line-height: 1.6; color: var(--ink-faint);
  border-radius: var(--r-md);
  border: 1px dashed var(--glass-line);
}

/* --- timetable ---------------------------------------------------------- */
.timetable > details {
  border-radius: var(--r-md);
  background: var(--glass); border: 1px solid var(--glass-line-soft);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  overflow: hidden;
}
.timetable__summary {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3); cursor: pointer; list-style: none; min-height: 52px;
}
.timetable__summary::-webkit-details-marker { display: none; }
.timetable__summary .section-h { margin: 0; }
.timetable__chev { display: grid; place-items: center; color: var(--ink-faint); transition: transform var(--dur) var(--ease); }
.timetable__chev svg { width: 19px; height: 19px; }
details[open] .timetable__chev { transform: rotate(180deg); }
.timetable__body { padding-bottom: var(--sp-2); }
.timetable__caption {
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent); padding: 0 var(--sp-3) var(--sp-1);
}
.timetable__block + .timetable__block { margin-top: var(--sp-3); }
.timetable__scroll { overflow-x: auto; padding: 0 var(--sp-3) var(--sp-3); -webkit-overflow-scrolling: touch; }
.timetable__table { border-collapse: collapse; width: 100%; font-size: 0.78rem; }
.timetable__table th, .timetable__table td {
  padding: 7px 9px; text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  border-bottom: 1px solid var(--glass-line-soft);
}
.timetable__table th:first-child, .timetable__table td:first-child {
  text-align: left; position: sticky; left: 0;
  background: linear-gradient(90deg, rgba(5, 18, 28, 0.96) 78%, rgba(5, 18, 28, 0));
  font-weight: 500; padding-right: var(--sp-3);
}
.timetable__table thead th {
  color: var(--ink-faint); font-weight: 600; font-size: 0.68rem;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.timetable__table td.is-past { color: var(--ink-faint); opacity: 0.5; }
.timetable__table td.is-skip { color: var(--ink-faint); opacity: 0.3; }
.timetable__table td.is-next { color: var(--accent); font-weight: 700; }
.timetable__table tr.is-yours td:first-child { color: var(--accent); font-weight: 700; }

/* --- footer ------------------------------------------------------------- */
.notes__list { display: grid; gap: 7px; }
.notes__list li {
  position: relative; padding-left: 16px;
  font-size: 0.79rem; line-height: 1.55; color: var(--ink-faint);
}
.notes__list li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent); opacity: 0.7;
}

.foot { display: grid; gap: 5px; text-align: center; padding-top: var(--sp-2); }
.foot__line { font-size: 0.78rem; color: var(--ink-faint); }
.foot__note { font-size: 0.72rem; color: var(--ink-faint); line-height: 1.5; }
.foot__brand {
  margin-top: var(--sp-2); font-size: 0.72rem; color: var(--ink-faint);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.foot__zerolve {
  font-weight: 700; letter-spacing: 0.14em; text-transform: lowercase;
  color: var(--ink-soft);
}

/* --- larger screens ----------------------------------------------------- */
@media (min-width: 720px) {
  .wrap { gap: var(--sp-5); }
  .hero { padding: var(--sp-5); }
  .stop { width: 108px; }
}
