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

:root {
  --app-width:             480px;
  --color-hairline:        #e0e0e0; /* dividers */
  --color-hover-bg:        rgba(0, 0, 0, 0.07);
  --color-muted:           #888; /* secondary text + control borders */
  --color-page-bg:         #e0e0e0; /* same value as hairline, different semantics */
  --color-panel:           #f5f5f5;
  --color-bus:             #ffc72c;
  --color-green-line:      #00843d;
  --color-red-line:        #da291c;
  --color-orange-line:     #ed8b00;
  --color-blue-line:       #003da5;
  --color-silver-line:     #7c878e;
  --color-commuter-rail:   #80276c;
  --color-mattapan:        #da291c;
  --color-ferry:           #008eaa;
  --chip-opacity-min:      0.6;
  --radius:                4px;
}

#progress-bar {
  height: 2px;
  left: 50%;
  max-width: var(--app-width);
  overflow: hidden;
  position: fixed;
  top: 0;
  transform: translateX(-50%);
  width: 100%;
  z-index: 1000;
}

#progress-bar.loading::after {
  animation: progress-slide 1.2s ease-in-out infinite;
  background: var(--color-bus);
  content: "";
  height: 100%;
  position: absolute;
  top: 0;
  width: 40%;
}

@keyframes progress-slide {
  0%   { left: -40%; }
  100% { left: 100%; }
}

.overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  backdrop-filter: blur(6px) grayscale(80%);
  -webkit-backdrop-filter: blur(6px) grayscale(80%);
  background: rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
}

body {
  font-family: 'Inter', system-ui, sans-serif;
  margin: 0;
  background: var(--color-page-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.panel {
  background: var(--color-panel);
  display: flex;
  flex-direction: column;
  max-width: var(--app-width);
  min-height: 100dvh;
  width: 100%;
}

.app-footer {
  color: #aaa;
  font-size: 0.7rem;
  margin-top: auto;
  padding: 1rem 0.75rem;
  text-align: center;
}

.app-footer a {
  border-bottom: 1px solid var(--color-hairline);
  color: #999;
  text-decoration: none;
}

.app-footer a:hover {
  color: #777;
}

#toast {
  width: 100%;
  max-width: var(--app-width);
  background: #fde8e8;
  color: #7f1d1d;
  border-bottom: 1px solid #fca5a5;
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

#toast[hidden] { display: none; }

#dismiss-toast {
  align-items: center;
  color: #991b1b;
  display: flex;
  height: 1rem;
  flex-shrink: 0;
  padding-left: 1rem;
}

.error { color: red; margin: 1rem; }

.app-header {
  align-items: center;
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem 0.75rem 0.5rem;
}

.app-title {
  flex-shrink: 0;
  margin: 0;
}

.app-title, .overlay-label {
  background: white;
  border-radius: 8px;
  border: 1px solid black;
  cursor: pointer;
  font-size: 1.2rem;
  font-weight: 800;
  padding: 0 0.35rem;
}

.app-info {
  font-size: 0.7rem;
  color: var(--color-muted);
}

.icon {
  height: 1em;
  width: 1em;
}

.routes-page {
  display: flex;
  flex-direction: column;
  margin-bottom: 4rem;
}

.route-cards {
  display: flex;
  flex-direction: column;
  transition: opacity 0.2s ease;

  &.stale {
    opacity: 0.5;
  }
}

.destination-control {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.25rem 0.75rem;
}

.destination-input-row {
  align-items: center;
  border: 1px solid var(--color-muted);
  border-radius: var(--radius);
  display: flex;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;

  /* Lift to white while the user is actually typing; quiet panel grey otherwise */
  &:focus-within {
    background: white;
  }
}

.destination-input {
  background: transparent;
  border: none;
  flex-grow: 1;
  font-size: 16px; /* anything smaller and iOS Safari zooms on focus */
  outline: none;
  padding: 0;
}

.destination-input-spinner {
  animation: spinner-rotate 0.8s linear infinite;
  border: 2px solid var(--color-muted);
  border-radius: 50%;
  border-top-color: transparent;
  flex-shrink: 0;
  height: 0.7rem;
  width: 0.7rem;

  &[data-hidden] {
    visibility: hidden;
  }
}

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

.destination-input-clear {
  color: var(--color-muted);
  cursor: pointer;
  line-height: 1;

  &[data-hidden] {
    visibility: hidden;
  }
}

.destination-suggestions {
  background: white;
  border: 1px solid var(--color-muted);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.destination-suggestion {
  cursor: pointer;
  padding: 0.25rem 0.5rem;

  & + .destination-suggestion {
    border-top: 1px solid var(--color-hairline);
  }
}

.destination-suggestion-name {
  font-size: 0.8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.destination-suggestion-detail {
  color: var(--color-muted);
  font-size: 0.7rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.destination-chip {
  align-items: center;
  border: 1px solid var(--color-muted);
  border-radius: var(--radius);
  cursor: pointer;
  display: flex;
  font-size: 0.8rem;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
}

.destination-chip::after {
  color: var(--color-muted);
  content: "×";
}

.destination-chip-label {
  flex-grow: 1;
  /* let the name/detail lines inside ellipsize */
  min-width: 0;
}

.bucket-header {
  align-items: center;
  color: var(--color-muted);
  display: flex;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 0.2rem 0.75rem;
}

.route-card + .bucket-header {
  margin-top: 0.5rem;
}

.route-card + .route-card {
  margin-top: 0.5rem;
}

.route-card {
  border: 1px solid black;
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  margin: 0 0.75rem;
  overflow: hidden;
}

.route-card-cols {
  background: color-mix(in srgb, var(--line-bg-color) 20%, white);
  display: flex;
}

.route-card-col {
  display: flex;
  flex-basis: 0;
  flex-direction: column;
  flex-grow: 1;
  min-width: 0;

  & + .route-card-col {
    border-left: 1px solid var(--line-bg-color);
  }
}

.route-card-id {
  align-items: center;
  background: var(--line-bg-color);
  color: var(--line-fg-color);
  display: flex;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0.05rem 0.25rem;
}

/* data-class carries the transit-line color wherever it appears (route cards, destination rows) */
[data-class="blue-line"]        { --line-bg-color: var(--color-blue-line);     --line-fg-color: #ffffff; }
[data-class="bus"]              { --line-bg-color: var(--color-bus);           --line-fg-color: #000000; }
[data-class="commuter-rail"]    { --line-bg-color: var(--color-commuter-rail); --line-fg-color: #ffffff; }
[data-class="ferry"]            { --line-bg-color: var(--color-ferry);         --line-fg-color: #ffffff; }
[data-class="green-line"]       { --line-bg-color: var(--color-green-line);    --line-fg-color: #ffffff; }
[data-class="mattapan-trolley"] { --line-bg-color: var(--color-mattapan);      --line-fg-color: #ffffff; }
[data-class="orange-line"]      { --line-bg-color: var(--color-orange-line);   --line-fg-color: #ffffff; }
[data-class="red-line"]         { --line-bg-color: var(--color-red-line);      --line-fg-color: #ffffff; }
[data-class="silver-line"]      { --line-bg-color: var(--color-silver-line);   --line-fg-color: #ffffff; }

/* A single button showing the current sort's icon (walking man = least walking, clock = arrive soonest); tapping
   switches modes. First child of .route-cards in destination mode; its margins keep the page's 0.5rem rhythm
   against the control above and the table below. */
.destination-sort {
  display: flex;
  margin: 0.25rem 0.75rem 0.5rem 0.75rem;
}

.destination-sort-button {
  align-items: center;
  border: 1px solid var(--color-muted);
  border-radius: var(--radius);
  color: var(--color-muted);
  cursor: pointer;
  display: inline-flex;
  font-size: 0.9rem;
  gap: 0.25rem;
  padding: 0.15rem 0.5rem;
}

.destination-sort-button:hover {
  background: var(--color-hover-bg);
  color: #111;
}

.destination-sort-label {
  font-size: 0.8rem;
}

/* One shared grid for the whole table, so the metric columns size to content and line up down the page (even
   across the separated cards). The two metric columns are auto (sized to their widest value); identity grows.
   row-gap matches the 0.5rem spacing between route cards on the non-destination page. */
.destination-table {
  column-gap: 0.4rem;
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  margin: 0 0.75rem;
  row-gap: 0.5rem;
}

/* Each row is its own card - 1px black border + radius, like a route card - washed the same light shade of its
   route color as .route-row. It's a subgrid spanning all three columns, so its cells align with every other
   row's. */
.destination-row {
  align-items: center;
  background: color-mix(in srgb, var(--line-bg-color) 20%, white);
  border: 1px solid black;
  border-radius: var(--radius);
  cursor: pointer;
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  /* The card's left/right edge inset. Inter-column spacing is the grid's column-gap; cells carry only vertical
     padding - so edges and all column gaps are one uniform 0.4rem instead of paddings that sum into gaps. */
  padding-inline: 0.4rem;
}

/* Metric cells take only their column's width, content centered */
.destination-cell {
  color: var(--color-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  padding-block: 0.3rem;
  text-align: center;
  white-space: nowrap;
}

/* The first cell is the active sort key (the Elm orders it first) - normal text color so it reads as primary */
.destination-cell:first-child {
  color: inherit;
}

.destination-metric-walk {
  align-items: center;
  display: inline-flex;
  justify-content: center;
}

/* Route identity: a strong route-colored id badge, the headsign (which ellipsizes), then the chip right after it -
   like a .route-row, not right-aligned */
.destination-route {
  align-items: center;
  display: flex;
  gap: 0.3rem;
  min-width: 0;
  padding-block: 0.3rem;
}

.destination-route-id {
  background: var(--line-bg-color);
  border-radius: var(--radius);
  color: var(--line-fg-color);
  font-size: 0.8rem;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  padding: 0 0.25rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Expanded trip flow. Spans the full row under the cells; only shown when expanded. A vertical list alternating
   leg durations (walk/ride) with stop and destination names. Two columns: a clock-time gutter (blank on duration
   rows) and the main content. */
.destination-timeline {
  display: none;
  grid-column: 1 / -1;
}

.destination-row[data-expanded] .destination-timeline {
  align-items: center;
  border-top: 1px solid var(--color-muted);
  color: var(--color-muted);
  column-gap: 1rem;
  display: grid;
  /* The main column sizes to its widest row (a name), not 1fr, so the centered spine sits as a compact block
     hugging the time gutter rather than floating in the middle; justify-content: start keeps it left, leftover
     space to the right. minmax min of 0 still lets a pathologically long name ellipsize. */
  grid-template-columns: auto minmax(0, max-content);
  justify-content: start;
  padding: 0.35rem 0;
  row-gap: 0.05rem;
}

.tl-time {
  color: var(--color-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.tl-main {
  display: flex;
  font-size: 0.8rem;
  justify-content: center;
  min-width: 0;
}

.tl-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The ride row centers just its icon+minutes on the spine (like the walk legs); the stop count is pulled out of
   flow so it hangs to the right without widening the centered part. */
.tl-ride {
  position: relative;
}

.tl-stops {
  font-size: 0.7rem;
  left: 100%;
  padding-left: 0.3rem;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
}

/* Connector bars on the spine: route-colored around the ride, muted around the walk legs */
.tl-bar {
  border-radius: 1px;
  height: 1rem;
  width: 2px;
}

.tl-bar--route {
  background: var(--line-bg-color);
}

.tl-bar--muted {
  background: radial-gradient(var(--color-muted) 60%, transparent 65%);
  background-size: 100% 0.2rem; /* one dot every 0.2rem of height */
  background-repeat: repeat-y;
}

.route-row {
  align-items: center;
  background: color-mix(in srgb, var(--line-bg-color) 20%, white);
  cursor: pointer;
  display: flex;
  flex-direction: row;
  flex-grow: 0;
  gap: 0.3rem;
  padding: 0.25rem;

  &[data-expanded] {
    align-items: stretch;
    flex-direction: column;

    & .headsign {
      white-space: normal;
    }
  }

  & + .route-row {
    border-top: 1px solid var(--line-bg-color);
  }
}

.headsign {
  /* same height as chip */
  border-bottom-color: transparent;
  border-bottom-style: solid;
  border-bottom-width: 1px;
  border-top-color: transparent;
  border-top-style: solid;
  border-top-width: 1px;
  font-size: 0.8rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-stop {
  color: var(--color-muted);
  display: none;
  font-size: 0.8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-row[data-expanded] .route-stop {
  display: block;
  white-space: normal;

  & .route-stop-name {
    vertical-align: middle;
  }

  & .walk-time {
    vertical-align: middle;
  }
}

.route-alight {
  color: var(--color-muted);
  display: none;
  font-size: 0.8rem;

  & .route-alight-name {
    vertical-align: middle;
  }

  & .walk-time {
    vertical-align: middle;
  }
}

.route-row[data-expanded] .route-alight {
  display: block;
}

.route-times {
  display: contents;
}

.route-times > .chip {
  order: 1;
}

.chips-extra {
  display: flex;
  flex: 1 0 0;
  gap: 0.3rem;
  mask-image: linear-gradient(to right, black calc(100% - 2rem), transparent 100%);
  order: 2;
  overflow: hidden;
}

.route-row[data-expanded] .route-times {
  display: flex;
  flex-wrap: wrap;
  flex: 0 0 auto;
  gap: 0.3rem;
  margin-top: 0.15rem;
  overflow: visible;
}

.route-row[data-expanded] .route-times > .chip {
  order: 0;
}

.route-row[data-expanded] .chips-extra {
  display: contents;
}

.chip {
  align-items: center;
  background: color-mix(in srgb, var(--line-bg-color) 10%, white);
  border-radius: var(--radius);
  border: 1px solid var(--color-muted);
  display: inline-flex;
  flex-shrink: 0;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  justify-content: center;
  min-width: 3ch;
  padding: 0 0.15rem;
  white-space: nowrap;

  &[data-state="urgent"] .chip-relative {
    font-weight: 300;
  }
}

.chip-absolute {
  display: none;
}

.route-row[data-expanded] .chip-absolute {
  display: inline;
}

.route-row[data-expanded] .chip-absolute,
.trip-stop-time {
  color: #999;
  font-size: 0.8em;
}

.route-row[data-expanded] .chip {
  gap: 0.25rem;
}

.trip-stops {
  display: grid;
  grid-template-columns: 1fr auto auto;
  margin: 0.5rem 0.75rem 4rem 0.75rem;
}

.trip-stop {
  align-items: center;
  border-bottom: 1px solid var(--color-hairline);
  column-gap: 0.5rem;
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  padding: 0.25rem;
}

.trip-stop--past {
  opacity: 0.35;
}

.trip-stop--mine {
  & .trip-stop-name, & .trip-stop-wait {
    font-weight: 600;
  }
}

.trip-stop-left {
  align-items: center;
  display: flex;
  gap: 0.25rem;
  min-width: 0;
}

.trip-stop-name {
  flex: 0 1 auto;
  font-size: 0.9rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.trip-stop-expander {
  border-bottom: 1px solid var(--color-hairline);
  color: #aaa;
  cursor: pointer;
  font-size: 0.8rem;
  grid-column: 1 / -1;
  padding: 0.35rem 0.25rem;
  text-align: center;
}

.trip-stop-expander:hover {
  background: var(--color-hover-bg);
  color: #111;
}

.trip-stop-wait {
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.trip-stop-time {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.walk-speed-control {
  align-items: center;
  color: var(--color-muted);
  display: flex;
  font-size: 0.7rem;
  gap: 0.25rem;
  margin-left: auto;
}

.walk-speed-btn {
  cursor: pointer;
  display: flex;
  font-size: 1rem;
  user-select: none;
  border: 1px solid var(--color-muted);
  width: 1.4rem;
  height: 1.4rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
}

.walk-speed-btn:hover:not(.walk-speed-btn--disabled) {
  background: var(--color-hover-bg);
  color: #111;
}

.walk-speed-btn--disabled {
  color: #ccc;
  cursor: default;
}

.walk-speed-value {
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.walk-time {
  align-items: center;
  color: var(--color-muted);
  display: inline-flex;
  font-size: 0.8rem;
  vertical-align: middle;
  white-space: nowrap;
}

.cursor-pointer {
  cursor: pointer;
}

.display-none {
  display: none;
}

.invisible {
  visibility: hidden;
}
