/* DiveOS — M1 Today Dashboard (T9)
   Visual system locked in DESIGN.md. Status palette + spacing scale + typography
   are project-wide; this file scopes them to `.dashboard` to avoid bleeding into
   other Bullet Train surfaces during the v1 fork. */

/* Fonts loaded by tokens.css — no import needed here. */

/* ════════════════════════════════════════════════════════════════════
   WL "Today (open)" benchmark — open-row layout (synced 2026-06-02)
   Mirrors White-label project/pages/index.html `.dv-open-row` family.
   Replaces the boxed-card trip row + KPI cards with the inline stat
   strip + full-bleed status-railed open rows. DM class names kept where
   they already existed (.status-pill); new structural primitives below.
   ════════════════════════════════════════════════════════════════════ */

/* Inline-text stat strip (replaces boxed KPI cards). WL §6. */
.stat-strip {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px 56px;
  margin: 0;
}
.stat-strip__item { display: flex; align-items: baseline; gap: 10px; }
.stat-strip__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-3xl);
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--accent);
}
.stat-strip__num--briefing { color: var(--status-briefing-fg); }
.stat-strip__label { font-size: var(--text-sm); color: var(--muted); }

/* Section label — MORNING / AFTERNOON. WL §2 (no trip count). WL uses
   px-14 pt-8 pb-4 = 56px L/R, 32px top, 16px bottom. */
.day-section {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 32px 56px 16px;
}
.day-section__label {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

/* Open-row grid — WL §5. rail | time | body | divers | chevron. */
.dv-open-row {
  display: grid;
  grid-template-columns: 16px 124px 1fr 168px 24px;
  gap: 28px;
  align-items: start;
  padding: 22px 56px 22px 40px;
  border-top: 1px solid var(--hairline);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--t-med) ease;
}
/* The last row closes the list with a bottom hairline. Each .dv-open-row now
   sits in its own [role=listitem] wrapper (#144), so :last-of-type on the <a>
   would match every row — target the last wrapper instead. */
[role="listitem"]:last-child > .dv-open-row { border-bottom: 1px solid var(--hairline); }
/* Kill Bullet Train's global a:hover underline on the whole clickable row. */
.dv-open-row:hover { background: var(--hover-warm); text-decoration: none; }
.dv-open-row:hover, .dv-open-row:hover * { text-decoration: none; }

/* Full-bleed band: extends a section's background to the .diveos-main edges
   (past the centered .diveos-content gutters), then re-insets its content to
   the centered column so it still aligns with the body. Encodes the shell
   constants: sidebar 240px, content max-width 1280px, content padding 48px
   → 712 = 1280/2 + 240/2 - 48. Used for the white Today header band. */
.dv-full-bleed {
  margin-left:  min(-48px, calc(712px - 50vw));
  margin-right: min(-48px, calc(712px - 50vw));
  padding-left:  max(48px, calc(50vw - 712px));
  padding-right: max(48px, calc(50vw - 712px));
}
.dv-open-row:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: -2px;
}

.dv-open-row__rail {
  width: 3px;
  height: 52px;
  background: var(--bar-pending);
  border-radius: 3px;
  margin-top: 8px;
  transition: background var(--t-med) ease;
}
.dv-open-row[data-status="briefing"]  .dv-open-row__rail { background: var(--bar-briefing); }
.dv-open-row[data-status="in_water"]   .dv-open-row__rail { background: var(--bar-inwater); }
.dv-open-row[data-status="confirmed"] .dv-open-row__rail { background: var(--bar-confirmed); }
.dv-open-row[data-status="cancelled"] .dv-open-row__rail { background: var(--bar-cancelled); }
.dv-open-row[data-status="briefing"]:hover  .dv-open-row__rail { background: var(--status-briefing-fg); }
.dv-open-row[data-status="in_water"]:hover   .dv-open-row__rail { background: var(--status-in-water-fg); }
.dv-open-row[data-status="confirmed"]:hover .dv-open-row__rail { background: var(--status-confirmed-fg); }
.dv-open-row[data-status="cancelled"]:hover .dv-open-row__rail { background: var(--status-cancelled-fg); }

/* Time column */
.dv-open-row__time {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.dv-open-row__time-sep { color: var(--muted-2); margin: 0 1px; }
.dv-open-row__time-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Body: title + route + guide/vessel */
.dv-open-row__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  color: var(--ink);
}
.dv-open-row__stops {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  font-size: var(--text-sm);
  color: var(--muted);
}
.dv-open-row__stops .sep { color: var(--muted-2); }
.dv-open-row__crew {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  font-size: var(--text-xs);
  color: var(--muted);
}
.dv-open-row__crew b { font-weight: 600; color: var(--ink); }
.dv-open-row__vessel {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-2);
  padding-left: 14px;
  border-left: 1px solid var(--hairline);
}

/* Divers count column */
.dv-open-row__count {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.dv-open-row__count--confirmed { color: var(--status-confirmed-fg); }
.dv-open-row__count--briefing  { color: var(--status-briefing-fg); }
.dv-open-row__count-max { color: var(--muted-2); font-size: var(--text-md); font-weight: 400; }
.dv-open-row__count-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* Progress underline (track + status-colored fill). DM had no equivalent
   primitive — the old row used an inline Tailwind bar. GAP-001 flagged. */
.progress-underline {
  position: relative;
  width: 100%;
  height: 3px;
  background: var(--hairline);
  border-radius: 999px;
  overflow: hidden;
  margin: 10px 0 6px;
}
.progress-underline__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width var(--t-med) ease;
}
.progress-underline__fill--confirmed { background: var(--status-confirmed-fg); }
.progress-underline__fill--briefing  { background: var(--status-briefing-fg); }
.progress-underline__fill--in_water  { background: var(--status-in-water-fg); }
.progress-underline__fill--cancelled { background: var(--status-cancelled-fg); }

/* Chevron — revealed on row hover */
.dv-open-row__chev {
  align-self: center;
  width: 18px;
  height: 18px;
  color: var(--muted-2);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity var(--t-fast) ease, transform var(--t-med) var(--ease-out-quart);
}
.dv-open-row:hover .dv-open-row__chev { opacity: 1; transform: translateX(0); }

/* Cancelled-state row styling (WL page-local <style>, promoted here) */
.dv-open-row[data-status="cancelled"] .dv-open-row__title,
.dv-open-row[data-status="cancelled"] .dv-open-row__time { color: var(--muted); }
.dv-open-row[data-status="cancelled"] .dv-open-row__stops {
  text-decoration: line-through;
  text-decoration-color: var(--hairline);
}

@media (max-width: 720px) {
  .dv-open-row {
    grid-template-columns: 12px 88px 1fr;
    gap: 16px;
    padding: 18px 16px;
  }
  .dv-open-row__count-col { display: none; }
  .dv-open-row__chev { display: none; }
  .stat-strip { gap: 10px 28px; }
  .day-section { padding: 24px 16px 12px; }
}


.dashboard {
  font-family: var(--font-sans);
  color: var(--text-primary);
  background: var(--bg);
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 16px 96px;
}

@media (min-width: 768px) {
  .dashboard { padding: 32px 24px 96px; }
}

/* Offline banner — sticky at top */
.dashboard__offline-banner {
  position: sticky;
  top: 0;
  margin: -24px -16px 16px;
  padding: 8px 16px;
  background: #FEF3C7;
  color: #92400E;
  font-size: var(--text-sm);
  font-weight: 500;
  z-index: 10;
}

/* T-M2 Service-Due dashboard widget. Briefing palette (amber) per
   DESIGN.md — recoverable, not destructive. Sits between header + trips. */
.dashboard__service-due {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: #FEF3C7;
  color: #92400E;
  border: 1px solid #FBBF24;
  border-radius: var(--radius-md);
}
.dashboard__service-due-icon { flex-shrink: 0; padding-top: 1px; }
.dashboard__service-due-body { flex: 1; }
.dashboard__service-due-label {
  margin: 0 0 2px 0;
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.dashboard__service-due-meta {
  margin: 0;
  font-size: var(--text-sm);
}
.dashboard__service-due-link {
  color: inherit;
  text-decoration: underline;
  font-weight: 500;
}
.dashboard__service-due-link:hover { text-decoration: none; }

/* Header */
.dashboard__header {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.dashboard__header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
.dashboard__logo {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
}
.dashboard__title {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
}
@media (min-width: 768px) {
  .dashboard__title { font-size: var(--text-3xl); }
}
.dashboard__summary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.dashboard__summary-stat {
  font-variant-numeric: tabular-nums;
}
.dashboard__summary-sep { color: var(--text-muted); margin: 0 6px; }

/* Trip list */
.dashboard__trips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Trip row */
.trip-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.trip-row__link {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 16px;
  min-height: 88px;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
@media (min-width: 768px) {
  .trip-row__link { grid-template-columns: 80px 1fr auto; }
}
/* QA-002: at narrow viewports the BT account sidebar leaves ~300px for the
   dashboard column; the auto-width meta column was eating into the body
   (site + boat + guide) and hiding it via overflow:hidden. Hide the chevron
   (the whole row is already a link — chevron is redundant) and tighten the
   capacity chip to give the body room. */
@media (max-width: 640px) {
  .trip-row__chevron { display: none; }
  .trip-row__meta { gap: 6px; }
  .trip-row__capacity { padding: 2px 6px; font-size: var(--text-xs); }
}
.trip-row__link:hover { background: var(--surface-alt); }
.trip-row__link:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: -2px;
  border-radius: var(--radius-md);
}

.trip-row__time {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  letter-spacing: -0.02em;
}
@media (min-width: 768px) {
  .trip-row__time { font-size: var(--text-3xl); }
}

.trip-row__body { min-width: 0; }
.trip-row__primary {
  font-size: var(--text-md);
  font-weight: 500;
  margin: 0 0 2px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trip-row__secondary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trip-row__sep { color: var(--text-muted); margin: 0 6px; }
.trip-row__missing { color: var(--text-muted); font-style: italic; }

/* OBS-002: +N badge for multi-site / multi-guide trips. Small, neutral,
   tucked inline. font-variant-numeric: tabular-nums keeps "+12" and "+1"
   aligned on the same row. */
.trip-row__extra {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  background: var(--surface-alt);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  vertical-align: 1px;
}

.trip-row__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.trip-row__capacity {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  padding: 2px 8px;
  background: var(--surface-alt);
  border-radius: var(--radius-pill);
}
.trip-row__chevron {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

/* Row state modifiers — kept light per DESIGN.md visual restraint. The
   status pill chip carries the meaning. --now adds a slim accent edge
   indicator on the left; no full-row background tint (that competed
   with the status pill colors and made the page feel busy). */
.trip-row--now {
  border-left: 3px solid var(--accent);
}
.trip-row--completed { opacity: 0.65; }
.trip-row--cancelled { opacity: 0.65; }
.trip-row--cancelled .trip-row__time {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
}

/* Signature pulse — fires when a Turbo Stream replaces the row */
@keyframes dashboard-pulse {
  0%   { background-color: var(--accent-tint); }
  100% { background-color: var(--surface); }
}
.trip-row--pulse { animation: dashboard-pulse 200ms cubic-bezier(0, 0, 0.2, 1); }

/* Status pills */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.status-icon { width: 12px; height: 12px; flex-shrink: 0; }

/* Size modifier (mirrors WL .dv-badge--sm) */
.status-pill--sm { font-size: var(--text-2xs); padding: 2px 8px; }
/* Shape modifier: square uppercase tag (mirrors WL .dv-badge--square) */
.status-pill--square {
  border-radius: 5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--text-2xs);
  padding: 3px 8px;
}
/* Leading dot child (mirrors WL .dv-badge-dot) */
.status-pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* Status pill backgrounds + foregrounds resolve through tokens.css.
   Palette pivot 2026-05-23: Confirmed=green (was blue), In Water=sky
   (was emerald). Dark mode handled by media query inside tokens.css —
   these rules just consume the resolved value, so no @media branch
   needed here. */
.status-pill--pending   { background: var(--status-pending-bg);   border-color: var(--status-pending-border);   color: var(--status-pending-fg); }
.status-pill--confirmed { background: var(--status-confirmed-bg); border-color: var(--status-confirmed-border); color: var(--status-confirmed-fg); }
.status-pill--briefing  { background: var(--status-briefing-bg);  border-color: var(--status-briefing-border);  color: var(--status-briefing-fg); }
.status-pill--in_water  { background: var(--status-in-water-bg);  border-color: var(--status-in-water-border);  color: var(--status-in-water-fg); }
.status-pill--returning { background: var(--status-returning-bg); border-color: var(--status-returning-border); color: var(--status-returning-fg); }
.status-pill--completed { background: var(--status-completed-bg); border-color: var(--status-completed-border); color: var(--status-completed-fg); }
.status-pill--cancelled { background: var(--status-cancelled-bg); border-color: var(--status-cancelled-border); color: var(--status-cancelled-fg); }

/* Editable status pill — the badge-dropdown trigger is a button.status-pill.
   It gets interaction affordances the static pill never does: a subtle hover
   and a token-driven focus-visible ring. The static .status-pill stays inert. */
button.status-pill {
  cursor: pointer;
  /* A whisper of resting elevation so the editable pill reads as a control,
     not a static label, even before hover (the 12px chevron alone is easy to
     miss). Status border + colors are untouched. */
  box-shadow: var(--shadow-sm);
  transition: filter 120ms ease, box-shadow 120ms ease;
}
button.status-pill:hover {
  filter: brightness(0.97);
  box-shadow: var(--shadow-card);
}
button.status-pill:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus), var(--shadow-sm);
}

/* Empty state */
.dashboard__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 96px 16px 64px;
  color: var(--text-secondary);
}
.dashboard__empty-art {
  color: var(--gray-300);
  width: 240px;
  height: 160px;
  margin-bottom: 32px;
  opacity: 0.7;
}
.dashboard__empty-art svg { width: 100%; height: 100%; }
.dashboard__empty-line {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
  margin: 0 0 8px;
}
.dashboard__empty-hint {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0 0 24px;
  max-width: 360px;
}
.dashboard__empty-photo {
  width: 100%;
  max-width: 480px;
  margin-bottom: 24px;
  border-radius: var(--radius-lg, 12px);
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.dashboard__empty-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.dashboard__empty-cta {
  display: inline-flex;
  align-items: center;
  padding: 10px 20px;
  background: var(--accent);
  color: white;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  text-decoration: none;
  min-height: 44px;
  box-sizing: border-box;
  transition: background-color 150ms ease;
}
.dashboard__empty-cta:hover { background: var(--accent-strong); }
.dashboard__empty-cta:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}

/* Skeleton loader */
@keyframes skeleton-shimmer {
  0% { opacity: 0.5; }
  50% { opacity: 0.8; }
  100% { opacity: 0.5; }
}
.trip-row--skeleton .trip-row__time,
.trip-row--skeleton .trip-row__body,
.trip-row--skeleton .trip-row__meta {
  pointer-events: none;
}
.skeleton-bar {
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
.skeleton-bar--time      { height: 28px; width: 64px; }
.skeleton-bar--primary   { height: 16px; width: 70%; margin-bottom: 6px; }
.skeleton-bar--secondary { height: 14px; width: 50%; }
.skeleton-bar--chip      { height: 20px; width: 80px; }

/* Partial-state warning icon — accompanies "— site TBD" / "— guide unassigned" */
.trip-row__missing-icon {
  display: inline-block;
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  color: var(--status-briefing-fg, #92400E);
  margin-right: 2px;
}
.trip-row__missing-text { /* hook for emphasis if needed */ }

/* Error state — design spec D4 */
.dashboard__error {
  margin: 24px auto;
  padding: 32px 24px;
  max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 8px);
  text-align: center;
}
.dashboard__error-line {
  font-size: var(--text-lg);
  font-weight: 500;
  color: var(--text);
  margin: 0 0 16px;
}
.dashboard__error-actions { margin-bottom: 16px; }
.dashboard__error-retry {
  display: inline-block;
  padding: 8px 20px;
  background: var(--accent);
  color: #FFFFFF;
  border-radius: var(--radius-pill, 999px);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
}
.dashboard__error-retry:hover { opacity: 0.9; }
.dashboard__error-details {
  margin-top: 16px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: left;
}
.dashboard__error-details summary { cursor: pointer; }
.dashboard__error-details pre {
  margin-top: 8px;
  padding: 8px;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  white-space: pre-wrap;
  overflow-x: auto;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .trip-row--pulse { animation: none; }
  .skeleton-bar { animation: none; }
  .trip-row, .dashboard__empty-cta { transition-duration: 1ms !important; }
}
