/*!
 * the-yachtclub-purser.css
 * ---------------------------------------------------------------
 * The YachtClub · Purser — Bootstrap v5.3 theme
 * Look/feel: "Seventies Regatta" — nautical white/royal-blue with
 * the chevron-vest palette (red #d64424 / amber #f0a12b) and a
 * mono-first, console-label type system.
 *
 * ⚠️ PROVENANCE — this is a verbatim copy of the-yachtclub-sentinel.css
 * plus section 6 at the foot of the file, taken 2026-07-31 at the
 * Pilot's direction so the shell renders on a proven base instead of
 * re-debugging the same visuals twice. Sections 1–4 are the shared
 * design system and ARE intentionally identical between the two apps.
 *
 * NOT YET PRESENT: Purser's own money layer — the register, the walk
 * band, the tape, severity, the variance/claim/observation registers
 * (.yc-claim / .yc-obs / .yc-variance). Those live in the authored
 * file on the Pilot's Desktop and land when it does. Nothing built so
 * far depends on them; the first screen that shows a figure will.
 *
 * Type:  body    IBM Plex Mono (.875rem base — mono runs wide)
 *        display Chakra Petch (headings, brands, console labels)
 *
 * Load order: AFTER bootstrap.min.css (and bootstrap-icons).
 * Strategy, in file order:
 *   1. Brand tokens            (--yc-*)
 *   2. Bootstrap theme vars    (:root --bs-* remapping — most of the
 *                               theme happens here with zero markup)
 *   3. Component vars          (only where 5.3 compiles literals:
 *                               .btn-*, .nav-pills, .table-light, forms)
 *   4. Custom layer            (what Sass alone controls: heading
 *                               face, claim register, chevron stripe,
 *                               logo, selection)
 *   5. Application layout      (shell: navbar+sidebar+main,
 *                               activity streams, auth screens)
 *   6. Purser additions        (rail collapse, figure labels — the
 *                               classes Purser's shell uses that
 *                               Sentinel's has no equivalent for)
 *
 * Reporting doctrine hooks (requirements §6):
 *   .badge-claim  — sender-STATED values (declared interval_s,
 *                   reported status). Dashed border = asserted,
 *                   unverified. Derived observations use the solid
 *                   text-bg-{success|warning|danger|secondary} badges.
 *
 * Dark mode: not shipped. Extension point is a [data-bs-theme="dark"]
 * block remapping section 2; sections 3–5 reference variables only.
 * Charts: read tokens at runtime (see the Chart.js adapter in the
 * portal JS: --bs-primary-rgb, --bs-border-color, --bs-font-monospace).
 * ---------------------------------------------------------------
 */

@import url("https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@300;500;600;700&family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap");


/* ---------- 1. Brand tokens ---------- */
:root {
  --yc-ink:   #0f1c30;   /* logo navy — text emphasis, headings */
  --yc-navy:  #2b5cbf;   /* seventies royal blue — primary CTA, links */
  --yc-navy-deep: #1f478f;
  --yc-navbar: #182f5c;  /* navbar navy, chroma pushed to match */
  --yc-red:   #d64424;   /* vest chevron red — danger */
  --yc-amber: #f0a12b;   /* vest chevron amber — warning */
  --yc-green: #2f7d54;   /* spruce — success */
  --yc-slate: #5b6b85;   /* muted text */
  --yc-claim: #8a97ad;   /* the CLAIM register (sender-stated values) */
  --yc-surface: #f3f5f8;
  --yc-border:  #dbe1ea;
}

/* ---------- 2. Bootstrap theme-variable overrides ---------- */
:root, [data-bs-theme="light"] {
  --bs-primary: var(--yc-navy);        --bs-primary-rgb: 43,92,191;
  --bs-primary-text-emphasis: var(--yc-navy-deep);
  --bs-primary-bg-subtle: #e7edfa;     --bs-primary-border-subtle: #b9cbf0;
  --bs-success: var(--yc-green);       --bs-success-rgb: 47,125,84;
  --bs-success-text-emphasis: #24603f;
  --bs-success-bg-subtle: #e7f2ec;     --bs-success-border-subtle: #bcd9c9;
  --bs-warning: var(--yc-amber);       --bs-warning-rgb: 240,161,43;
  --bs-warning-text-emphasis: #7a4e0a;
  --bs-warning-bg-subtle: #fdf3e0;     --bs-warning-border-subtle: #f7d9a4;
  --bs-danger: var(--yc-red);          --bs-danger-rgb: 214,68,36;
  --bs-danger-text-emphasis: #8f2c15;
  --bs-danger-bg-subtle: #fbe9e4;      --bs-danger-border-subtle: #f2c4b6;
  --bs-secondary: var(--yc-slate);     --bs-secondary-rgb: 91,107,133;
  --bs-light: var(--yc-surface);       --bs-light-rgb: 243,245,248;
  --bs-dark: var(--yc-navbar);         --bs-dark-rgb: 24,47,92;

  --bs-body-bg: #ffffff;               --bs-body-bg-rgb: 255,255,255;
  --bs-body-color: #1c2b44;            --bs-body-color-rgb: 28,43,68;
  --bs-secondary-color: var(--yc-slate);
  --bs-tertiary-bg: #f6f8fa;           /* app canvas: near-white cool */
  --bs-border-color: var(--yc-border);
  --bs-heading-color: var(--yc-ink);
  --bs-link-color: var(--yc-navy);     --bs-link-color-rgb: 43,92,191;
  --bs-link-hover-color: var(--yc-navy-deep); --bs-link-hover-color-rgb: 31,71,143;
  --bs-code-color: #b83a1d;
  --bs-focus-ring-color: rgba(43,92,191,.25);

  --bs-font-monospace: "IBM Plex Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --bs-body-font-family: var(--bs-font-monospace);
  --bs-body-font-size: .875rem;        /* mono runs wide; NOC density */

  --bs-border-radius: .3rem;           /* squarish, C64-adjacent */
  --bs-border-radius-sm: .2rem;
  --bs-border-radius-lg: .4rem;
}

/* ---------- 3. Component-variable overrides (compiled literals) ---------- */
.btn { --bs-btn-font-weight: 500; }
.btn-primary {
  --bs-btn-bg: var(--yc-navy);              --bs-btn-border-color: var(--yc-navy);
  --bs-btn-hover-bg: var(--yc-navy-deep);   --bs-btn-hover-border-color: var(--yc-navy-deep);
  --bs-btn-active-bg: var(--yc-navy-deep);  --bs-btn-active-border-color: var(--yc-ink);
  --bs-btn-disabled-bg: var(--yc-navy);     --bs-btn-disabled-border-color: var(--yc-navy);
  --bs-btn-focus-shadow-rgb: 43,92,191;
}
.btn-outline-primary {
  --bs-btn-color: var(--yc-navy);           --bs-btn-border-color: var(--yc-navy);
  --bs-btn-hover-bg: var(--yc-navy);        --bs-btn-hover-border-color: var(--yc-navy);
  --bs-btn-active-bg: var(--yc-navy-deep);  --bs-btn-active-border-color: var(--yc-navy-deep);
  --bs-btn-focus-shadow-rgb: 43,92,191;
}
.btn-outline-secondary {
  --bs-btn-color: #44536d;                  --bs-btn-border-color: #c3cbd9;
  --bs-btn-hover-color: var(--yc-ink);      --bs-btn-hover-bg: #eef1f6;
  --bs-btn-hover-border-color: #b2bccd;
  --bs-btn-active-color: var(--yc-ink);     --bs-btn-active-bg: #e3e8ef;
  --bs-btn-active-border-color: #b2bccd;
  --bs-btn-focus-shadow-rgb: 91,107,133;
}
.btn-outline-danger  { --bs-btn-color: var(--yc-red); --bs-btn-border-color: var(--yc-red);
                       --bs-btn-hover-bg: var(--yc-red); --bs-btn-hover-border-color: var(--yc-red);
                       --bs-btn-focus-shadow-rgb: 214,68,36; }
.btn-dark { --bs-btn-bg: var(--yc-navbar); --bs-btn-border-color: var(--yc-navbar);
            --bs-btn-hover-bg: #0f1c30; --bs-btn-hover-border-color: #0f1c30; }
.nav-pills { --bs-nav-pills-link-active-bg: var(--yc-navy);
             --bs-nav-pills-border-radius: var(--bs-border-radius); }
.table-light { --bs-table-bg: var(--yc-surface); --bs-table-color: #44536d; }
.card { --bs-card-border-color: var(--yc-border); --bs-card-cap-bg: #f8fafc; }
.badge { --bs-badge-font-weight: 600; --bs-badge-border-radius: var(--bs-border-radius-sm); }
.dropdown-menu { --bs-dropdown-link-active-bg: var(--yc-navy); }
.breadcrumb { --bs-breadcrumb-divider: "›"; }
/* Button groups: gapped, not fused — each button keeps its own corners.
   (!important needed to beat Bootstrap's corner-flattening :not() rules) */
.btn-group { gap: .35rem; }
.btn-group > .btn { border-radius: var(--bs-border-radius) !important; margin-left: 0 !important; }
.btn-group-sm > .btn { border-radius: var(--bs-border-radius-sm) !important; }
.progress { --bs-progress-bar-bg: var(--yc-navy); }
.form-control:focus, .form-select:focus {
  border-color: #9cb4e8;
  box-shadow: 0 0 0 .25rem rgba(43,92,191,.18);
}
.form-check-input:checked { background-color: var(--yc-navy); border-color: var(--yc-navy); }
.form-check-input:focus { border-color: #9cb4e8; box-shadow: 0 0 0 .25rem rgba(43,92,191,.18); }

/* ---------- 4. Custom layer (no Bootstrap hook exists) ---------- */
/* Headings: Chakra Petch — squared terminals, C64-adjacent but contemporary */
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, .navbar-brand {
  font-family: "Chakra Petch", var(--bs-font-monospace);
  letter-spacing: .01em;
}
/* Console-label card headers */
.card-header {
  font-family: "Chakra Petch", var(--bs-font-monospace);
  font-size: .72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--yc-ink);
}
.card-header .badge { letter-spacing: .02em; }
/* Console table heads */
.table thead th {
  font-family: "Chakra Petch", var(--bs-font-monospace);
  font-size: .68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--yc-slate);
}
/* CLAIM register: sender-stated values (declared interval, reported
   status). Dashed border = asserted, unverified. Derived observations
   keep the solid text-bg-* treatment. */
.badge-claim {
  color: var(--yc-slate);
  background: #fbfcfe;
  border: 1px dashed #a6b1c4;
  font-weight: 500;
}
/* Chevron stripe — the vest, as a signature. Red over amber under
   every top bar (border supplies the red band, shadow the amber). */
.navbar.sticky-top, .yc-authbar {
  border-bottom: 3px solid var(--yc-red);
  box-shadow: 0 3px 0 var(--yc-amber);
}
.yc-authbar { background: var(--bs-body-bg); }
.yc-logo { width: 28px; height: 28px; color: var(--yc-ink); }
.yc-hero-sub { font-family: "Chakra Petch", var(--bs-font-monospace); letter-spacing: .01em; }
/* Peripheral history strips (instance show): one cell = one heartbeat's
   reported status. ok is muted so warning/error carry the signal;
   cells without a snapshot fall back to the surface gray. */
.peri-strip { display: flex; gap: 1px; }
.peri-strip .peri-cell { flex: 1 1 0; height: 18px; min-width: 2px; border-radius: 1px; background: var(--yc-surface); }
.peri-cell[data-s="ok"] { background: rgba(var(--bs-success-rgb), .45); }
.peri-cell[data-s="warning"] { background: var(--yc-amber); }
.peri-cell[data-s="error"] { background: var(--yc-red); }
.peri-legend { display: flex; flex-wrap: wrap; gap: .35rem 1.25rem; align-items: center; }
.peri-legend .peri-cell { display: inline-block; width: 14px; height: 10px; border-radius: 2px; background: var(--yc-surface); }
/* Medallion timeline (activity streams): icon medallions on a rail.
   Event type reads from the medallion before the text does. Anchor
   items keep list-group-style hover affordance. */
.yc-timeline { margin: 0; padding: .25rem 0; }
.yc-tl-item { position: relative; display: block; padding: .55rem 1rem .55rem 3.1rem;
  color: inherit; text-decoration: none; }
a.yc-tl-item:hover { background: var(--yc-surface); }
.yc-tl-item::before { content: ""; position: absolute; left: 1.45rem; top: 0; bottom: 0;
  width: 2px; background: var(--yc-border); }
.yc-tl-item:first-child::before { top: 1.4rem; }
.yc-tl-item:last-child::before { bottom: auto; height: 1.4rem; }
.yc-tl-item:only-child::before { display: none; }
.yc-medal { position: absolute; left: .55rem; top: .55rem; width: 1.85rem; height: 1.85rem;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--yc-surface); border: 1px solid var(--yc-border);
  color: var(--yc-slate); font-size: .85rem; box-shadow: 0 0 0 3px var(--bs-body-bg); }
.yc-medal.m-success { background: var(--bs-success-bg-subtle); border-color: var(--bs-success-border-subtle); color: var(--bs-success-text-emphasis); }
.yc-medal.m-warning { background: var(--bs-warning-bg-subtle); border-color: var(--bs-warning-border-subtle); color: var(--bs-warning-text-emphasis); }
.yc-medal.m-danger  { background: var(--bs-danger-bg-subtle);  border-color: var(--bs-danger-border-subtle);  color: var(--bs-danger-text-emphasis); }
.yc-medal.m-info    { background: var(--bs-primary-bg-subtle); border-color: var(--bs-primary-border-subtle); color: var(--bs-primary-text-emphasis); }
.yc-timeline .timeline-current { background: var(--bs-primary-bg-subtle); }
/* Status dot: instant health read next to an entity name.
   online green / degraded amber / offline red / pending slate. */
.yc-status-dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%;
  background: var(--yc-slate); vertical-align: middle; }
.yc-status-dot[data-health="online"]   { background: var(--yc-green); }
.yc-status-dot[data-health="degraded"] { background: var(--yc-amber); }
.yc-status-dot[data-health="offline"]  { background: var(--yc-red); }
/* Maps (Leaflet): fleet + instance location, flush inside cards.
   Marker colors come from the health tokens at runtime. Reported
   positions are sender claims (§6) — headers carry the claim chip. */
.yc-map { height: 320px; position: relative; z-index: 0; }
.yc-map-sm { height: 220px; }
.card > .yc-map:last-child { border-bottom-left-radius: calc(var(--bs-border-radius) - 1px);
  border-bottom-right-radius: calc(var(--bs-border-radius) - 1px); }
.leaflet-container { font-family: var(--bs-body-font-family); font-size: .78rem; }
.leaflet-popup-content-wrapper { border-radius: var(--bs-border-radius); }
.leaflet-popup-content a { color: var(--yc-navy); }
/* Full-screen fleet view: the map escapes app-main's p-4 padding and
   fills the working area; the filter panel floats above Leaflet. */
.yc-fleet-wrap { position: relative; margin: -1.5rem; }
.yc-map-full { height: calc(100vh - 66px); position: relative; z-index: 0; }
.yc-fleet-panel { position: absolute; top: 1rem; right: 1rem; z-index: 1001; width: 300px; }
/* Compact variant for dense single-line streams (per-beat timelines):
   small medallions centered on the line so the rail stays visible.
   Full-size medallions are for two-line, mixed-event streams only. */
.yc-timeline-compact .yc-tl-item { padding: .4rem 1rem .4rem 2.45rem; }
.yc-timeline-compact .yc-tl-item::before { left: 1.12rem; }
.yc-timeline-compact .yc-tl-item:first-child::before { top: 50%; }
.yc-timeline-compact .yc-tl-item:last-child::before { bottom: auto; height: 50%; }
.yc-timeline-compact .yc-medal { width: 1.3rem; height: 1.3rem; font-size: .68rem;
  left: .5rem; top: 50%; transform: translateY(-50%);
  box-shadow: 0 0 0 2px var(--bs-body-bg); }
::selection { background: var(--yc-navy); color: #fff; }

/* ---------- 5. Application layout ---------- */
body { min-height: 100vh; }
.app-shell { display: flex; min-height: calc(100vh - 65px); }
.app-sidebar { width: 220px; flex-shrink: 0; }
.app-main { flex-grow: 1; min-width: 0; }
.activity-stream { max-height: calc(100vh - 180px); overflow-y: auto; }
.avatar { width: 32px; height: 32px; object-fit: cover; }
.auth-wrap { min-height: calc(100vh - 65px); display: flex; align-items: center; }
.timeline-current { border-left: 3px solid var(--bs-primary); }
@media (min-width: 768px) {
  .border-end-md { border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color); }
}
@media (max-width: 991.98px) { .app-sidebar { display: none; } }


/* ===============================================================
   6 · PURSER ADDITIONS
   ---------------------------------------------------------------
   The classes Purser's shell uses that Sentinel's theme has no
   equivalent for. Lifted verbatim from the purser.html v27
   prototype's inlined theme, so they match the design exactly.

   Not in this section (and not needed yet): .yc-nights, the audit
   sublist under the Audits nav item — there are no audits to list,
   so the shell does not render it.
   =============================================================== */

/* Console label above a figure — the small mono all-caps key. */
.yc-fig-label { font-family: var(--bs-font-monospace); font-size: .6rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--yc-slate); }

/* The dashboard's date lockup. */
.yc-hero-date { font-family: "Chakra Petch", var(--bs-font-monospace);
  font-size: 1.5rem; font-weight: 600; line-height: 1.2; color: var(--yc-ink); }

/* Rail collapse. The nav is a width, not a drawer: items keep their order and their
   dividers, only the labels go. Toggled by #rail-toggle, which flips body.is-rail. */
body.is-rail .app-sidebar { width: 58px; padding-left: .5rem !important;
  padding-right: .5rem !important; }
body.is-rail .app-sidebar .nav-link { text-align: center; padding: .5rem 0; }
body.is-rail .app-sidebar .nav-link i { margin-right: 0 !important; font-size: 1.05rem; }
body.is-rail .app-sidebar .rail-hide { display: none; }
body.is-rail .app-sidebar hr { margin-left: .1rem; margin-right: .1rem; }
body.is-rail #rail-toggle .bi { transform: rotate(180deg); }
