/* ── Transport board — the tasks/057 Timeline Spine ───────────────────────
   Restored from 33ae7f10 (claude/hotelos-transport-pages-17e3e3) and ported to
   os-ds v1.3.0. Merge f9ad6414 deleted _spine / _spine_row / spine_now_controller
   and this stylesheet's ancestor while resolving an unrelated front-office
   branch, which dropped all four board tabs back to the flat row list the spine
   had replaced.

   The board is a single rail: a time gutter, a type node on the rail, and a run
   card whose 4px left anchor is the ONLY place status colour lives (the pill
   carries the word). A server-rendered Now marker sits between the two runs that
   bracket resort-now. */

/* Transport's tab band. Seven tabs are 855px wide, so the gem's `flex-wrap: wrap`
   + `.os-page-tools > .page-tabs { flex-shrink: 0 }` dropped Auto-assign onto a
   second row at every viewport below 1440 (band 57px -> 69px). A dispatch board's
   chrome must not change height as the window moves. Hold ONE line and let the tab
   row scroll instead: the tabs already carry `overflow-x: auto` from the gem, they
   just need permission to shrink. Scoped to this band, never the bare component. */
.os-page-tools.hos-boardband {
  flex-wrap: nowrap;
  /* The gem's tabs bleed over the band's 12px padding (margin-block: -12px), so
     with no sibling control the band collapses to the bare tab height — 25px on
     the five tabs that never show Auto-assign, 57px on the two that do, and the
     whole page jumped as you moved between them. Pin the control height (32px)
     plus the band's own padding (2 x 12px) so the chrome is the same on every
     tab, action or not. */
  min-height: calc(var(--space-8) + var(--space-6));
}
/* The tabs render as `.os-page-tabs`; this rule once named only the bare `.page-tabs` alias,
   so the gem's `.os-page-tools > .os-page-tabs { flex-shrink: 0 }` still won and the 690px
   tab row + Auto-assign pushed the page to ~890px at 768 (sideways scroll). */
.hos-boardband > :is(.page-tabs, .os-page-tabs) { flex-shrink: 1; min-width: 0; }
.hos-boardband > .os-btn { flex: none; }

/* The status anchor bar (.hos-runanchor + tones) lives in hotelos_ds/components.css since
   #485 — the run card, the duty sheet and the crew/certificate lists share it. */

/* Board = spine + right rail. */
.hos-spine-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-6); align-items: start;
}
@media (max-width: 1100px) { .hos-spine-layout { grid-template-columns: minmax(0, 1fr); } }

/* The rail itself. 132px of left padding is the time gutter; the 2px rule sits
   at 104px so the 40px nodes centre on it. */
.hos-spine { position: relative; padding-left: 132px; }
.hos-spine::before {
  content: ""; position: absolute; left: 104px; top: var(--space-4); bottom: var(--space-4);
  width: 2px; background: var(--hairline); border-radius: var(--radius-pill);
}

/* Group header (period, or kind on the Excursions tab) — pulled back over the
   gutter so its label starts at the page's left edge, not the cards'. */
.hos-spine__grp {
  position: relative; margin: 0 0 var(--space-4) -132px; padding-left: 132px;
  display: flex; align-items: center; gap: var(--space-3);
}
.hos-spine__grp:not(:first-child) { margin-top: var(--space-8); }
.hos-spine__grp-c { font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }

/* Now marker — accent dot on the rail + fading line + mono label. */
.hos-spine__now {
  position: relative; margin: var(--space-1) 0 var(--space-5) -132px; padding-left: 132px;
  display: flex; align-items: center; gap: var(--space-3); height: 8px;
}
.hos-spine__now::before {
  content: ""; position: absolute; left: 104px; top: 50%;
  transform: translate(-50%, -50%); width: 13px; height: 13px;
  border-radius: var(--radius-pill); background: var(--accent);
  box-shadow: 0 0 0 4px var(--surface), 0 0 0 6px var(--accent-soft); z-index: 2;
}
.hos-spine__now-l {
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); white-space: nowrap;
}
.hos-spine__now-line {
  flex: 1; height: 2px; border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-border), transparent);
}

/* One movement: time gutter + node + card, with a 8px tick joining card to rail. */
.hos-spine__mv { position: relative; margin-bottom: var(--space-4); }
.hos-spine__mv::after {
  content: ""; position: absolute; left: -8px; top: 34px; width: 8px; height: 2px;
  background: var(--hairline); z-index: 1;
}
.hos-spine__time { position: absolute; left: -132px; top: 22px; width: 66px; text-align: right; }
.hos-spine__hh { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 600; line-height: 1; color: var(--ink); }

/* Type node on the rail. */
.hos-node {
  position: absolute; left: -48px; top: 14px; width: 40px; height: 40px;
  border-radius: var(--radius-pill); display: flex; align-items: center;
  justify-content: center; background: var(--surface); border: 1px solid var(--hairline); z-index: 3;
}
.hos-node--transfer  { background: var(--slate-100); border-color: var(--hairline-strong); }
.hos-node--excursion { background: var(--slate-100); border-color: var(--hairline-strong); }
.hos-node--dive      { background: var(--success-bg); border-color: var(--success-border); }
.hos-node--done      { background: var(--success-bg); border-color: var(--success-border); }

/* Run card — single hairline, status via the LEFT ANCHOR bar only. */
.hos-runcard {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-4);
  align-items: center; background: var(--surface); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); padding: var(--space-4) var(--space-5) var(--space-4) var(--space-5);
  overflow: hidden; text-decoration: none;
}
.hos-runcard--done { opacity: 0.66; }
.hos-runcard__k {
  display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted-2);
}
.hos-runcard__title {
  font-size: var(--text-md); font-weight: 700; color: var(--ink);
  margin-top: 5px; display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
}
.hos-runcard__meta {
  display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2);
  color: var(--text-muted); flex-wrap: wrap; font-size: var(--text-sm);
}
.hos-runcard__meta .hos-sep { width: 3px; height: 3px; border-radius: var(--radius-pill); background: var(--muted-2); flex: none; }
.hos-runcard__boat { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--slate-700); }
.hos-runcard__crew { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text-muted); }
.hos-runcard__end { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-2); flex: none; }

/* MT-2 — "Manifest" action rail: the run-board entry fused to the card's right
   edge. The ROW carries the one surface/radius/shadow; the card and the rail are
   sibling links inside it (no nested <a>), split by a hairline. The card's own
   hover lift moves to the row so the two halves never separate. */
.hos-spine__mv--rail {
  display: grid; grid-template-columns: minmax(0, 1fr) 1px auto;
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
}
.hos-spine__mv--rail .hos-runcard { border-radius: var(--radius-lg) 0 0 var(--radius-lg); box-shadow: none; }
.hos-spine__mv--rail .hos-runcard.hos-card--interactive:hover { box-shadow: none; transform: none; }
.hos-spine__mv--rail:has(.hos-runcard:hover, .hos-runrail:hover) { box-shadow: var(--shadow-md); }
.hos-runrail__sep { background: var(--hairline); }

/* tasks/342 — a run whose slot has gone by (done, cancelled, or overdue and never left)
   steps back: the DiveOS past-row treatment (trip-row--completed: dimmed, same layout),
   applied to the whole row — card, Manifest rail, time — so live/upcoming runs lead.
   Hover restores full strength so a past run is still easy to open. */
.hos-spine__mv--past > .hos-runcard,
.hos-spine__mv--past > .hos-runrail,
.hos-spine__mv--past > .hos-runrail__sep { opacity: .65; transition: opacity var(--t-quick); }
.hos-spine__mv--past:hover > * { opacity: 1; }
.hos-spine__mv--past .hos-spine__hh { color: var(--muted); }
.hos-spine__mv--past .hos-runcard,
.hos-spine__mv--past.hos-spine__mv--rail { box-shadow: none; }
.hos-spine__mv--rail .hos-runrail {
  flex-direction: column; height: auto; gap: var(--space-1);
  padding: 0 var(--space-4); min-width: 76px; border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}

/* tasks/062 — a form inside the DS side drawer: scrolling body, pinned footer.
   .hos-odrawer / -panel / -scrim / -head / -body already ship in
   hotelos_ds/components.css; only the form shell and footer were lost with
   _drawer_disclosure, so they land here beside the surface that uses them. */
.hos-odrawer-form { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.hos-odrawer-foot {
  flex: none; display: flex; align-items: center; justify-content: flex-end;
  /* tasks/073 A1 — matches the gem's `.os-side-panel__action-bar` (12px/24px)
     so the light and full drawer vocabularies pin their actions identically. */
  gap: var(--space-2); padding: var(--space-3) var(--hos-drawer-gutter, 24px);
  background: var(--surface); border-top: 1px solid var(--hairline-2);
}
/* --split — a destructive action pinned left, the confirm pair still right. */
.hos-odrawer-foot--split { justify-content: space-between; }

/* Fleet card grid. --gutter is the SHELL inset (48px, or the gem's responsive
   clamp to 64px) — using it as a card gap blew the cards apart into six islands.
   tasks/057 fixed this once (0ca60a4f); merge f9ad6414 reverted it. Columns are
   tighter than rows on purpose: 16px ties a row of cards into one set, 24px
   between rows keeps the grid scanning row by row. */
.hos-fleetgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  column-gap: var(--space-4);
  row-gap: var(--space-6);
}

/* Fleet tab body: KPI strip, then the card grid. The section gap used to come
   from the floated "New vessel" strip between them — once that moved into the
   page-tools band the two grids sat flush against each other. */
.hos-fleet { display: flex; flex-direction: column; gap: var(--space-6); }

/* tasks/075 — Spine mobile treatment (shared: transport board + excursion Board
   A). Desktop is unchanged; at ≤640px the whole gutter system scales together
   (padding, rail, node, time all move as one so nothing collides — the failure
   mode of moving a single offset), and the runcard stacks its status/cap below
   the title. This lives here, not in a per-page sheet, because .hos-spine is a
   shared component. os-page-head (the action band above) is an os-ds gem
   concern — flagged separately, not patched here. */
@media (max-width: 640px) {
  .hos-spine { padding-left: 88px; }
  .hos-spine::before { left: 66px; }
  .hos-spine__grp { margin-left: -88px; padding-left: 88px; }
  .hos-spine__now { margin-left: -88px; padding-left: 88px; }
  .hos-spine__now::before { left: 66px; }
  .hos-spine__time { left: -88px; width: 48px; }
  .hos-spine__hh { font-size: var(--text-sm); white-space: nowrap; }
  .hos-node { left: -37px; width: 30px; height: 30px; top: 16px; }
  .hos-node svg { width: 15px; height: 15px; }

  .hos-runcard { grid-template-columns: 1fr; gap: var(--space-2); padding: var(--space-3) var(--space-4); }
  .hos-runcard__end { flex-direction: row; align-items: center; justify-content: space-between; width: 100%; }

  /* --stack (Transport only; the excursion board keeps the gutter above): the
     time leaves the gutter and becomes a HEADER line above its card, big enough to
     outrank the card title (text-xl vs text-md), anchored by a small node on a slim
     rail. The card gets the full width back; the Manifest rail folds into the
     card's status row as a labelled button instead of a separate strip. */
  .hos-spine--stack { padding-left: 28px; }
  .hos-spine--stack::before { left: 7px; }
  .hos-spine--stack .hos-spine__grp,
  .hos-spine--stack .hos-spine__now { margin-left: -28px; padding-left: 28px; }
  .hos-spine--stack .hos-spine__now::before { left: 7px; }
  .hos-spine--stack .hos-spine__time { position: static; width: auto; text-align: left; margin-bottom: var(--space-2); }
  .hos-spine--stack .hos-spine__hh { font-size: var(--text-xl); line-height: 28px; }
  .hos-spine--stack .hos-node { left: -28px; top: 7px; width: 14px; height: 14px; border-width: 2px; }
  .hos-spine--stack .hos-node svg { display: none; }
  .hos-spine--stack .hos-spine__mv::after { display: none; }

  .hos-spine--stack .hos-spine__mv--rail {
    grid-template-columns: minmax(0, 1fr) auto; background: none; box-shadow: none; border-radius: 0;
  }
  .hos-spine--stack .hos-spine__mv--rail:has(.hos-runcard:hover, .hos-runrail:hover) { box-shadow: none; }
  .hos-spine--stack .hos-spine__mv--rail .hos-spine__time { grid-column: 1 / -1; }
  .hos-spine--stack .hos-spine__mv--rail .hos-runcard {
    grid-column: 1 / -1; grid-row: 2; border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
  }
  /* leave room at the end of the status row for the Manifest button */
  /* wrap, don't overlap: a long pill ("Needs a boat") + the seat meter overflow the
     reserved width at 370 and slid 30px under the button — the meter drops a line. */
  .hos-spine--stack .hos-spine__mv--rail .hos-runcard__end {
    padding-right: 112px; flex-wrap: wrap; justify-content: flex-start; gap: var(--space-2) var(--space-3);
  }
  /* the 70px bar is what doesn't fit beside the button; "0/24" carries the number */
  .hos-spine--stack .hos-spine__mv--rail .hos-cap__track { display: none; }
  .hos-spine--stack .hos-runrail__sep { display: none; }
  /* rail rows are always airport transfers — the "Airport transfer" eyebrow is
     redundant there on a phone; charters/dives keep theirs (the node glyph that
     would otherwise tell them apart is hidden at this size). */
  .hos-spine--stack .hos-spine__mv--rail .hos-runcard__k { display: none; }
  /* boat · crew · ~45 min: with a long boat name the row wrapped and orphaned the dot
     at line end + "~45 min" alone below. Tighter gap, no dot → fits at 370. */
  .hos-spine--stack .hos-runcard__meta { gap: var(--space-2); flex-wrap: nowrap; min-width: 0; }
  .hos-spine--stack .hos-runcard__meta .hos-sep { display: none; }
  /* a long boat name ("Manta Express") still wrapped "~45 min" — keep ONE line: the eta
     never shrinks, boat + crew give way with an ellipsis (regression QA, tasks/342) */
  .hos-spine--stack .hos-runcard__meta > span:last-child { flex: none; white-space: nowrap; }
  .hos-spine--stack .hos-runcard > div:first-of-type { min-width: 0; } /* grid item may shrink */
  .hos-spine--stack .hos-runcard__boat {
    display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .hos-spine--stack .hos-runcard__boat > svg { display: inline-block; vertical-align: -2px; margin-right: 6px; }
  .hos-spine--stack .hos-runcard__crew { min-width: 0; overflow: hidden; white-space: nowrap; flex-shrink: 1; }
  .hos-spine--stack .hos-spine__mv--rail .hos-runcard__title { margin-top: 0; }
  .hos-spine--stack .hos-spine__mv--rail .hos-runrail {
    grid-column: 2; grid-row: 2; align-self: end; z-index: 2;
    flex-direction: row; gap: var(--space-2); min-width: 0; min-height: 36px;
    margin: 0 var(--space-3) var(--space-1) 0; padding: 0 var(--space-3); border-radius: var(--radius-md);
  }
}
