/* ============================================================
   M/Y Netto II — Crew Portal styles
   Brand palette: deep navy / signal red / cream
   ============================================================ */

/* ============================================================
   HOUSE STYLE — read before adding new module CSS (R129).
   ------------------------------------------------------------
   The codebase has accreted ~13 module-specific button systems,
   14 input systems, and 160+ card/modal selectors because new
   modules invented their own classes instead of using these
   canonical primitives. New CSS should compose from these:

   COLOR / SURFACE
     var(--navy-900..600), var(--red-500), var(--cream),
     var(--ink), var(--ink-soft), var(--ink-muted),
     var(--danger), var(--warn), var(--success)
     var(--navy-overlay-04..24)  for borders / hovers / dividers
     var(--hairline) / --hairline-strong  for card edges

   RADIUS
     var(--radius)     4px — buttons, inputs
     var(--radius-md)  6px — chips, small cards
     var(--radius-lg)  8px — standard cards, modals (small)
     var(--radius-xl) 12px — large cards, sheets
     var(--radius-pill) 999px — pills, badges, FABs

   ELEVATION
     var(--shadow-card)        — flat cards on the canvas
     var(--shadow-card-hover)  — interactive card hover state
     var(--shadow-pop)         — popovers, dropdowns
     var(--shadow-modal)       — modals, sheets

   TYPOGRAPHY
     var(--sans) / var(--display) / var(--mono)
     font: var(--type-caption | --type-body | --type-h3..h1)
     letter-spacing: var(--track-tight | --normal | --wide | --wider | --eyebrow)

   BUTTONS — use .btn + variant. Do not invent .module-btn.
     .btn + .btn-primary  → navy fill, cream text (primary action)
     .btn + .btn-secondary → white fill, navy text (secondary)
     .btn + .btn-ghost     → transparent, danger text (destructive)
     .btn + .btn-link      → text-only with underline
     .btn-sm   → tighter padding + 13px text
     .btn-icon → square icon-only button (44×44 tap target)

   INPUTS — use .field wrapper. Do not invent .module-input.
     <label class="field">
       <span>Label</span>
       <input type="…" />
     </label>
     Handles label, input padding, border, focus ring uniformly.

   MODALS — use .modal + .modal-card. Do not invent .module-modal.
     <div class="modal hidden" onclick="…closeModal(event)">
       <div class="modal-card" onclick="event.stopPropagation()">
         <div class="modal-header">
           <h3>Title</h3>
           <button class="modal-close" onclick="close()">×</button>
         </div>
         …
         <div class="modal-actions">…</div>
       </div>
     </div>
     Variants: .modal-card-wide, .modal-card-xwide, .modal-side.

   RESPONSIVE
     Mobile = 640px and below. Tablet ≈ 720. Desktop ≥ 960.
     Use minmax(min(Xpx, 100%), 1fr) for card grids — prevents
     the Xpx floor from forcing horizontal overflow.
     Use 100dvh (with 100vh fallback) for full-height shells —
     plain 100vh causes iOS Safari address-bar jank.
     Wrap module containers in env(safe-area-inset-*) padding
     when they sit at the viewport edge (header / footer / modal).

   ICONS
     <svg class="ic"><use href="#ic-name"/></svg>
     Do not use emoji (🔒 🚨 ⚙) as chrome — renders differently
     per OS. Sprite lives at top of index.html <body>.
   ============================================================ */

:root {
  /* R145 — Dolphin Blue depth pass (2026-05-28). R144 used the literal
     Alex Seal "Dolphine Blue" M5927 paint swatch (#6F92A2) as the
     midtone, which read flat + pale on screen — the hull in real life
     is deeper and more saturated because of how light wraps a curved
     surface. Scale below is darker, more saturated, and adds a full
     9-stop range so chrome can carry real gradients (lit top →
     shadowed bottom) instead of single-value fills. navy-600 stays in
     the same hue family as the paint but darker; the paint swatch
     itself shows through as navy-500 (the highlight reading on a
     sunlit panel). */
  --navy-950: #1E3645;  /* Deep waterline shadow — darkest chrome */
  --navy-900: #284558;  /* Body text on white (~10.5:1) */
  --navy-800: #38617A;  /* Primary chrome (header, drawer, theme-color) */
  --navy-700: #4A7791;  /* Hover / active */
  --navy-600: #5C8AA4;  /* Hull midtone (lit), primary fills */
  --navy-500: #7AA3BB;  /* Accents, links, hairline highlight */
  --navy-100: #DCE7ED;  /* Tints, soft backgrounds */
  --navy-50:  #EEF3F6;  /* Surface wash */

  /* R145 — gradient tokens. Used by chrome, primary buttons, badges
     and the public auth canvas. Apply via background-image so the
     solid background-color fallback still resolves for older UAs
     and reduced-data contexts. */
  --grad-chrome:        linear-gradient(180deg, var(--navy-800) 0%, var(--navy-900) 100%);
  --grad-button:        linear-gradient(180deg, var(--navy-700) 0%, var(--navy-800) 100%);
  --grad-button-hover:  linear-gradient(180deg, var(--navy-600) 0%, var(--navy-700) 100%);
  --grad-badge:         linear-gradient(135deg, var(--navy-800), var(--navy-900));
  --grad-canvas:        radial-gradient(ellipse at 50% 22%, var(--navy-700) 0%, var(--navy-900) 70%, var(--navy-950) 100%);

  --red-500: #E11D2E;     /* Brand red — matches NETTO II wordmark */
  --red-600: #C41626;
  --red-700: #9F1220;
  --red-100: #FCE7E9;

  --cream: #FAF7F2;
  --cream-dark: #F1ECE3;
  --ink: #1A1A1A;
  --ink-soft: #4A5568;
  --ink-muted: #8A94A6;
  --line: #E5E0D5;

  --danger: #B91C1C;
  --warn: #B45309;
  --success: #166534;

  --radius: 4px;
  --radius-md: 6px;     /* R129 — 6px is heavily used (~120 places); tokenize */
  --radius-lg: 8px;
  --radius-xl: 12px;    /* R129 — used by larger cards / modals */
  --radius-pill: 999px; /* R129 — was hardcoded 123 times as `999px` or 50% */

  /* R129 — Navy-on-light overlay scale. The codebase had ~90 hardcoded
     `rgba(40, 69, 88, 0.0X)` overlays for borders / hovers / dividers /
     subtle backgrounds. New tokens here, but the existing rgba()
     values are LEFT IN PLACE on purpose — mass-rewriting without
     visual verification across every module would risk regressions.
     New CSS should use these tokens; old rgba()s are flagged for
     gradual migration. */
  --navy-overlay-04: rgba(40, 69, 88, 0.04);
  --navy-overlay-06: rgba(40, 69, 88, 0.06);
  --navy-overlay-08: rgba(40, 69, 88, 0.08);
  --navy-overlay-12: rgba(40, 69, 88, 0.12);
  --navy-overlay-18: rgba(40, 69, 88, 0.18);
  --navy-overlay-24: rgba(40, 69, 88, 0.24);

  --shadow-sm: 0 1px 2px rgba(40, 69, 88, 0.06);
  --shadow-md: 0 4px 12px rgba(40, 69, 88, 0.08);
  --shadow-lg: 0 10px 30px rgba(40, 69, 88, 0.12);

  /* R43 — Engineered Precision pass (2026-05-10).
     Two-tier elevation. Cards lift from the canvas with a hairline
     border + a near-imperceptible shadow (Linear/Stripe pattern), so
     they read as "drawn on the surface" rather than floating. Modals
     and popovers earn a real shadow because they actually sit above.
     The hairline tokens are reused everywhere a card meets the canvas
     so the drawing is consistent at every scale. */
  --hairline:        rgba(40, 69, 88, 0.08);
  --hairline-strong: rgba(40, 69, 88, 0.14);
  --shadow-card:     0 0 0 1px var(--hairline), 0 1px 2px rgba(40, 69, 88, 0.04);
  --shadow-card-hover: 0 0 0 1px var(--hairline-strong), 0 2px 6px rgba(40, 69, 88, 0.06);
  --shadow-pop:      0 8px 24px -8px rgba(40, 69, 88, 0.12), 0 0 0 1px var(--hairline);
  --shadow-modal:    0 24px 48px -12px rgba(40, 69, 88, 0.18), 0 0 0 1px var(--hairline);

  /* Eyebrow tracking — uppercase nav labels and section eyebrows pick
     up an ~8% letter-space so they read as Swiss-precision labels
     rather than small-text. */
  --track-eyebrow: 0.08em;
  /* R129 — companion tracking scale. The codebase had ~15 different
     letter-spacing values (0.02em / 0.03em / 0.04em / 0.5px / 1.5px /
     etc.). New CSS should use these four tokens. */
  --track-tight:  0.02em;  /* body text emphasis */
  --track-normal: 0.04em;  /* small uppercase chips */
  --track-wide:   0.08em;  /* alias for --track-eyebrow */
  --track-wider:  0.12em;  /* hero captions, MARSEC pill */

  /* Linear-style ease curve. Use for motion that wants to feel
     "snapped into place" rather than soft. */
  --ease-precise: cubic-bezier(0.16, 1, 0.3, 1);

  /* Mono stack for technical numerics (HUD readouts, bok-secret pills,
     anything where the digits should column-align). */
  --mono: 'SF Mono', 'JetBrains Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;

  /* Body type: Helvetica throughout, per Fraser 2026-04-29.
     `Helvetica Neue` first for macOS / iOS where it's installed; `Helvetica`
     for older systems; `Arial` as the universal Windows fallback (metric-
     compatible with Helvetica, so layouts don't shift); generic sans-serif
     last.
     Display type: Inter — a modern neutral sans used for H1/H2 headings.
     Loaded async from Google Fonts; falls back through the system sans
     stack so the layout never collapses if the webfont fails. */
  --sans:    'Helvetica Neue', Helvetica, Arial, sans-serif;
  --display: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* Type scale tokens — H1/H2 use the display serif at lighter weights
     so they read as luxury display rather than punchy SaaS sans. Use as:
     font: var(--type-body); — applies size + line-height in one shot. */
  --type-caption: 400 11px/1.4 var(--sans);
  --type-body:    400 14px/1.55 var(--sans);
  --type-h3:      500 16px/1.35 var(--display);
  --type-h2:      600 22px/1.25 var(--display);
  --type-h1:      300 32px/1.15 var(--display);

  /* Spacing scale — 4px base unit. Use these instead of arbitrary
     pixel values so vertical rhythm stays consistent across modules. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  font-family: var(--sans);
  color: var(--ink);
  /* R145 (2026-06-01): force light color-scheme so the browser doesn't
     restyle native <input>, <select>, and date/month pickers in dark
     mode (which made the selected-option text appear white-on-white in
     the cards-toolbar dropdowns on macOS Chrome + Safari). Fraser
     reported month/card dropdowns rendering blank — text was there but
     invisible because the browser was applying its dark-mode chrome to
     the native controls. Explicit color-scheme keeps them aligned with
     the page's actual light palette. */
  color-scheme: light;
  /* Dolphine-blue gradient across every authenticated page (R25 polish,
     2026-04-30, hull anchor corrected R144 2026-05-28). Same colour
     family as the login hero — Alex Seal Dolphine Blue M5927 #5C8AA4 —
     but lighter at the top so white cards + dark text still read
     cleanly. Fixed attachment so the gradient stays put while long
     pages scroll, giving the feeling of moving across a calm sea
     rather than over a flat surface. */
  background:
    radial-gradient(ellipse at 50% 100%, rgba(111, 146, 162, 0.20) 0%, rgba(111, 146, 162, 0) 65%),
    linear-gradient(180deg, #EEF3F5 0%, #D6E2E6 45%, #B5CAD1 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

button { font-family: var(--sans); cursor: pointer; }
a { color: var(--navy-700); text-decoration: none; }
a:hover { color: var(--red-500); }

.hidden { display: none !important; }

/* Filter to render colored brand assets in pure white on dark backgrounds */
.is-white { filter: brightness(0) invert(1); }

/* ============================================================
   ICON SYSTEM (R43 — 2026-05-10)
   Inline SVG sprite lives at the top of <body>; every emoji that
   was previously used as UI chrome is now <svg class="ic"><use
   href="#ic-name"/></svg>. The icons are 24×24-viewBox Lucide-style
   strokes, no fill, currentColor — so they pick up the surrounding
   text colour automatically and scale with font-size.

   Usage:
     <svg class="ic"><use href="#ic-bell"/></svg>      → 1em sized
     <svg class="ic ic-lg"><use href="#ic-..."/></svg> → 20px
     <svg class="ic ic-xl"><use href="#ic-..."/></svg> → 32px
   ============================================================ */
.ic {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
  display: inline-block;
  vertical-align: -0.15em;
  pointer-events: none;
}
.ic-sm { width: 14px; height: 14px; vertical-align: -2px; }
.ic-md { width: 16px; height: 16px; vertical-align: -3px; }
.ic-lg { width: 20px; height: 20px; vertical-align: -4px; }
.ic-xl { width: 32px; height: 32px; vertical-align: middle; }
.ic-fill { fill: currentColor; stroke: none; }
/* Slightly heavier stroke for icons used at >32px — keeps the
   optical weight consistent with the smaller sizes. */
.ic-xl, .ic-2xl { stroke-width: 1.4; }

/* Tabular numerics — apply to anything where digits should align in
   columns (HUD readouts, finance amounts, time, money). */
.tabular { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* Uppercase eyebrow / section label utility. Helvetica looks crisp
   at 11px uppercase with 8% tracking; matches the engineered-precision
   nav labels used in the portal header. */
.eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  font-weight: 600;
  font-size: 11px;
  color: var(--ink-muted);
}

/* Soft cross-fade between route changes (R23). The route() handler adds
   `.page-fading-in` on entry and removes it on the next frame so the
   opacity transition fires. ~140ms reads "instant but composed" — long
   enough to feel intentional, short enough that nobody notices the wait. */
.page { transition: opacity 140ms ease-out; }
.page.page-fading-in { opacity: 0; }

/* -------- Loading overlay --------
   R26 (2026-05-01) — match the dolphin-blue gradient used on the
   authenticated pages so the flash from the boot screen to the
   logged-in shell doesn't cross a colour boundary. Previously
   `var(--cream)` showed a peach/cream wash that read as a
   different design system. */
.loading-overlay {
  position: fixed; inset: 0;
  background:
    radial-gradient(ellipse at 50% 100%, rgba(111, 146, 162, 0.20) 0%, rgba(111, 146, 162, 0) 65%),
    linear-gradient(180deg, #EEF3F5 0%, #D6E2E6 45%, #B5CAD1 100%);
  display: flex;
  flex-direction: column;
  gap: 24px;
  align-items: center; justify-content: center;
  z-index: 1000;
}
.loading-mark {
  width: 96px;
  opacity: 0.85;
}
.loading-spinner {
  width: 32px; height: 32px;
  border: 2px solid var(--cream-dark);
  border-top-color: var(--red-500);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Compass-rose loader (R23) — replaces the bare spinner. The needle
   inside the ring rotates on a 4-second loop with a soft ease so it
   reads as nautical instrument rather than a "loading…" twirl. */
.loading-compass {
  color: var(--navy-900);
  display: inline-flex;
}
.loading-compass-needle {
  transform-origin: 32px 32px;
  animation: compass-sweep 4s ease-in-out infinite;
}
@keyframes compass-sweep {
  0%   { transform: rotate(0deg); }
  50%  { transform: rotate(195deg); }
  100% { transform: rotate(360deg); }
}

/* ============================================================
   PUBLIC (LANDING / LOGIN)
   ============================================================ */

.public-shell {
  min-height: 100vh;
  min-height: 100dvh;
  /* Day mode: Dolphine-blue gradient — pale turquoise sky deepening to
     the actual hull colour at the waterline. Hull is Alex Seal Dolphine
     Blue M5927 = #5C8AA4 (RGB 111, 146, 162); the bottom stop lands
     there exactly so the yacht silhouette sits in a sea that matches
     her hull (Fraser 2026-04-30, hex corrected R144 2026-05-28). The
     top stays light enough that the form card still reads cleanly
     without darkening. */
  background:
    radial-gradient(ellipse at 50% 110%, rgba(60, 100, 115, 0.35) 0%, rgba(60, 100, 115, 0) 60%),
    linear-gradient(180deg, #DDEEF1 0%, #B5CDD4 35%, #93B3C0 75%, #5C8AA4 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  position: relative;
  overflow: hidden;
  transition: background 600ms ease;
}
/* Night mode: deep-navy gradient with a subtle radial moonlight glow.
   App.init sets .is-night based on local hour so the login screen
   matches what the captain would see if they logged in at 22:00. */
.public-shell.is-night {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(255, 255, 255, 0.05) 0%, rgba(40, 69, 88, 0) 45%),
    radial-gradient(ellipse at 50% 110%, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 60%),
    linear-gradient(180deg, #0a1d36 0%, #08182a 60%, #050e1c 100%);
}
.public-shell.is-night::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    radial-gradient(1px 1px at 12% 18%, rgba(255,255,255,0.55), transparent 50%),
    radial-gradient(1px 1px at 28% 62%, rgba(255,255,255,0.40), transparent 50%),
    radial-gradient(1px 1px at 41% 22%, rgba(255,255,255,0.50), transparent 50%),
    radial-gradient(1px 1px at 58% 36%, rgba(255,255,255,0.30), transparent 50%),
    radial-gradient(1px 1px at 67% 11%, rgba(255,255,255,0.55), transparent 50%),
    radial-gradient(1px 1px at 79% 48%, rgba(255,255,255,0.35), transparent 50%),
    radial-gradient(1px 1px at 87% 24%, rgba(255,255,255,0.45), transparent 50%),
    radial-gradient(1px 1px at 22% 38%, rgba(255,255,255,0.30), transparent 50%);
  pointer-events: none;
  z-index: 0;
  animation: bridge-stars 6s ease-in-out infinite alternate;
}
@keyframes bridge-stars {
  from { opacity: 0.55; }
  to   { opacity: 0.95; }
}

/* Yacht silhouette watermark behind everything */
.public-watermark {
  position: absolute;
  bottom: -40px;
  left: 50%;
  transform: translateX(-50%);
  width: 1300px;
  max-width: 150vw;
  opacity: 0.18;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 6px 22px rgba(40, 69, 88, 0.25));
  transition: opacity 600ms ease, filter 600ms ease;
}
.public-shell.is-night .public-watermark {
  opacity: 0.42;
  filter: brightness(0.4) invert(0.05) drop-shadow(0 4px 24px rgba(0, 0, 0, 0.5));
}

.public-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 460px;
  background: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
  backdrop-filter: blur(14px) saturate(115%);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: var(--radius-lg);
  padding: 48px 44px 36px;
  box-shadow:
    0 30px 60px -20px rgba(40, 69, 88, 0.35),
    0 8px 22px -10px rgba(40, 69, 88, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  transition: background 600ms ease, border-color 600ms ease, box-shadow 600ms ease;
}
.public-shell.is-night .public-card {
  background: rgba(40, 69, 88, 0.55);
  border-color: rgba(255, 255, 255, 0.10);
  color: #f6f1e3;
  box-shadow:
    0 36px 80px -20px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.public-shell.is-night .public-card .form-title,
.public-shell.is-night .public-card .form-sub,
.public-shell.is-night .public-card label.field span,
.public-shell.is-night .public-card .field-hint {
  color: rgba(255, 255, 255, 0.85);
}
.public-shell.is-night .public-card input,
.public-shell.is-night .public-card select {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.18);
}
.public-shell.is-night .public-card input::placeholder { color: rgba(255, 255, 255, 0.45); }
.public-shell.is-night .public-card .brand-wordmark { filter: brightness(0) invert(1); opacity: 0.92; }
.public-shell.is-night .public-card .form-foot a { color: rgba(255, 255, 255, 0.78); }

.public-brand {
  text-align: center;
  margin-bottom: 32px;
}

/* Wordmark image — hero variant */
.brand-wordmark {
  display: block;
  width: 280px;
  height: auto;
  margin: 0 auto 6px;
}
/* Wordmark image — header variant (white-on-navy variant file) */
.header-wordmark {
  display: block;
  height: 28px;
  width: auto;
}

.brand-label {
  font-size: 10px;
  /* R142 — em-based tracking (was a hardcoded 4px which read as 40%+ at
     this font-size — way too wide for an eyebrow label). 0.12em matches
     the rest of the eyebrow/wide tracking scale. */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 14px 0 0;
  font-weight: 600;
  position: relative;
  padding-top: 16px;
}
.brand-label::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  width: 36px; height: 2px;
  background: var(--red-500);
  transform: translateX(-50%);
}

.auth-form { width: 100%; }
/* R39 — "Keep me signed in" checkbox row. Layout is its own thing
   (NOT wrapped in .field) so the inner text reads inline next to the
   checkbox instead of stacking + uppercasing like a field label. */
.remember-me-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0 10px;
  padding: 0;
  cursor: pointer;
  user-select: none;
}
.remember-me-row input[type="checkbox"] {
  flex-shrink: 0;
  width: 18px; height: 18px;
  margin: 0;
  cursor: pointer;
}
.remember-me-row span {
  font-size: 13px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink, #1f2937);
  line-height: 1.3;
}
.public-shell.is-night .remember-me-row span { color: rgba(255, 255, 255, 0.85); }
.form-title {
  font-family: var(--display);
  font-size: 26px;
  margin: 0 0 6px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-align: center;
}
.form-sub {
  color: var(--ink-soft);
  font-size: 14px;
  margin: 0 0 26px;
  text-align: center;
}

.field {
  display: block;
  margin-bottom: 16px;
}
.field > span {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 15px;
  font-family: var(--sans);
  background: #fff;
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  /* R142 — crisp doubled-border ring replaces the soft glow. Navy on
     pointer focus, red on keyboard focus-visible so screen-reader /
     keyboard users get a clearly distinct cue (and brand red doesn't
     fire on every casual click). */
  outline: none;
  border-color: var(--navy-900);
  box-shadow: 0 0 0 1px var(--navy-900);
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--red-500);
  box-shadow: 0 0 0 1px var(--red-500);
}
.field textarea { resize: vertical; }

/* R142 — frosted form fields on the login card. The card itself is
   already a frosted-glass surface; matching the inputs to it makes
   them feel inset into the glass instead of pasted on top. */
.public-card .field input,
.public-card .field select,
.public-card .field textarea {
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(40, 69, 88, 0.10);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.form-error {
  color: var(--danger);
  font-size: 13px;
  min-height: 18px;
  margin-bottom: 8px;
}
.form-warn {
  background: rgba(180, 83, 9, 0.08);
  border-left: 3px solid var(--warn);
  color: var(--warn);
  font-size: 13px;
  padding: 10px 12px;
  border-radius: var(--radius);
  margin-bottom: 12px;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  /* R142 — luxury catalogue button. Was 10/18 4px-radius 14px sentence
     case; now 12/28 with a near-square 2px radius, smaller uppercase
     text, and wide tracking. Reads as "engraved plaque" rather than
     "SaaS button" — matches the cert-plate / signage feel Fraser asked
     for on the headers. .btn-sm and .btn-icon override sizing below. */
  padding: 12px 28px;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.15s var(--ease-precise), border-color 0.15s var(--ease-precise), color 0.15s var(--ease-precise), transform 0.15s var(--ease-precise), box-shadow 0.15s var(--ease-precise);
  font-family: var(--sans);
}
/* Make sure inline icons inside buttons sit on the optical baseline */
.btn .ic { vertical-align: -2px; }
.btn-sm .ic { width: 14px; height: 14px; vertical-align: -2px; }

/* R129 — canonical icon-only button. Backs up the HOUSE STYLE
   reference. WCAG-compliant 44×44 tap target (the codebase had
   ~6 module-specific 36×36 icon buttons that fail tap-target
   guidelines on touch). Compose as `<button class="btn btn-icon">`
   for the standard navy fill, or add a variant. */
.btn-icon {
  width: 44px;
  height: 44px;
  padding: 0;
  flex: 0 0 auto;
  border-radius: var(--radius-md);
}
.btn-icon .ic { width: 18px; height: 18px; vertical-align: 0; }
.btn-icon.btn-sm { width: 36px; height: 36px; border-radius: var(--radius); }
.btn-icon.btn-sm .ic { width: 14px; height: 14px; }
.btn-primary {
  /* R145 — primary action carries a gradient (navy-700 → navy-800) so
     it reads as a forged-metal control catching light from above. The
     inset highlight is the sheen line that sells the curvature. Hover
     brightens the gradient one stop while keeping the same delta. */
  background-color: var(--navy-700);
  background-image: var(--grad-button);
  color: var(--cream);
  border-color: var(--navy-800);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.btn-primary:hover {
  background-color: var(--navy-600);
  background-image: var(--grad-button-hover);
  border-color: var(--navy-700);
}
.btn-secondary {
  background: #fff;
  color: var(--navy-800);
  border-color: var(--line);
}
.btn-secondary:hover { background: var(--cream-dark); }

/* Quiet destructive action — text-style button in the danger colour, used
   for HOD-only "Remove from roster" action on the directory expanded row. */
.crew-delete-btn {
  background: none;
  border: 0;
  color: var(--red-700);
  font: inherit;
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
  margin-left: auto;
  padding: 4px 8px;
}
.crew-delete-btn:hover { color: var(--red-700); }

/* WhatsApp-branded variants of the contact buttons. The icon stays brand
   green; the button picks up a subtle green tint on hover so it reads
   as a branded action rather than a generic secondary. */
.btn-whatsapp { display: inline-flex; align-items: center; }
.btn-whatsapp:hover { background: rgba(37, 211, 102, 0.10); border-color: rgba(37, 211, 102, 0.40); color: #128C7E; }
.hub-dir-action-wa {
  display: inline-flex; align-items: center; gap: 0;
  background: #fff;
  color: var(--navy-800);
  border: 1px solid var(--line);
}
.hub-dir-action-wa:hover { background: var(--cream-dark); color: var(--navy-800); border-color: var(--line); }
.hub-dir-action-wa svg path { transition: fill 0.12s; }
.btn-ghost {
  background: transparent;
  color: var(--danger);
  border-color: transparent;
}
.btn-ghost:hover { background: rgba(185, 28, 28, 0.06); }
.btn-block { width: 100%; }
.btn-link {
  background: none; border: none;
  color: var(--ink-soft);
  text-decoration: underline;
  cursor: pointer;
  font-size: 13px;
  font-family: var(--sans);
  padding: 4px 8px;
}
.btn-link:hover { color: var(--navy-800); }

.form-foot {
  text-align: center;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 20px;
}
.form-foot .dot { margin: 0 6px; color: var(--line); }
.form-foot a { color: var(--ink-soft); }
.form-foot a:hover { color: var(--red-500); }

.public-foot {
  text-align: center;
  font-size: 11px;
  letter-spacing: var(--track-wider);
  color: var(--ink-muted);
  text-transform: uppercase;
  margin: 32px 0 0;
}
/* R129 — exempt the guest portal link from the uppercase rule so the
   sentence "Guest aboard? Open the guest portal →" reads as a sentence
   rather than shouting on two lines on a phone. */
.public-foot a {
  text-transform: none;
  letter-spacing: 0.2px;
  font-size: 13px;
}

/* Mobile public */
@media (max-width: 540px) {
  .public-card { padding: 36px 24px 28px; }
  .form-title { font-size: 22px; }
  .brand-wordmark { width: 200px; }
}

/* R142 — responsive polish for the design overhaul. Touch-target floor
   on .btn for phones (44pt WCAG AA), and near-fullscreen modals so
   small screens get the full canvas instead of a postage-stamp card.
   Tablet bumps the .btn padding back to comfortable. */
@media (max-width: 720px) {
  .btn { min-height: 44px; padding: 12px 22px; gap: 6px; }
  .btn-sm { min-height: 36px; padding: 8px 14px; font-size: 12px; }
  .btn-icon { min-height: 44px; }
  .modal-card {
    max-width: 100%;
    max-height: calc(100dvh - 32px);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    margin-top: auto;
  }
  .modal {
    align-items: flex-end;
    padding: 0;
    padding-top: max(0px, env(safe-area-inset-top));
    padding-bottom: 0;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
}
@media (max-width: 480px) {
  .modal-card > form,
  .modal-card > p,
  .modal-card > h2,
  .modal-card > h4,
  .modal-card > div:not(.modal-header):not(.modal-actions):not(.pin-card-body):not(#pin-card-body) {
    padding-left: 20px;
    padding-right: 20px;
  }
  .modal-card > .modal-actions { padding-left: 20px; padding-right: 20px; }
  .modal-header { padding: 18px 20px 14px; }
  #booking-form { padding: 16px 20px 20px; }
}

/* ============================================================
   PORTAL (AUTHENTICATED)
   ============================================================ */

.portal-header {
  /* R145 — header chrome carries a top-lit gradient (navy-800 → navy-900)
     so the bar reads as a curved hull catching light from above rather
     than a flat fill. Solid background-color is a fallback for UAs that
     skip gradients; background-image carries the real treatment. */
  background-color: var(--navy-800);
  background-image: var(--grad-chrome);
  color: var(--cream);
  position: sticky; top: 0;
  /* Must clear Leaflet's max pane z-index (popups are 700, controls 1000)
     so the sticky header isn't punched through by the AIS map below it. */
  z-index: 1100;
  box-shadow: var(--shadow-sm);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  /* R129 — extend the navy chrome under the iOS notch / Dynamic Island
     so the status bar reads against navy (matches apple-mobile-web-app-
     status-bar-style=black-translucent). */
  padding-top: env(safe-area-inset-top);
}
/* R142 — red accent rail under the header. Tapers in at the edges so
   it reads as a brand mark rather than a hard divider. Sits below the
   navy chrome, above the page content. */
.portal-header::after {
  content: '';
  display: block;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--red-500) 18%,
    var(--red-500) 82%,
    transparent 100%);
  opacity: 0.85;
}
.portal-header-inner {
  /* R142 — widened to match portal-main 1280 so the header and main
     column align on large desktops. */
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 40px;
  /* R129 — keep horizontal content clear of side notches on landscape iPhone. */
  padding-left: max(40px, env(safe-area-inset-left));
  padding-right: max(40px, env(safe-area-inset-right));
  display: flex;
  align-items: center;
  height: 64px;
}
@media (max-width: 720px) {
  .portal-header-inner {
    padding: 0 20px;
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }
}
.portal-brand {
  display: flex; align-items: center;
  color: var(--cream);
  position: relative;
  padding-bottom: 4px;
}
.portal-brand:hover { opacity: 0.92; color: var(--cream); }
/* R145 — Removed the short red dash under the wordmark. It sat under
   just the "N" of NETTO (because left:0 anchored it to the first glyph,
   not the full mark) and read as a stray accent line rather than the
   intended brand motif. The header-wide accent rail (.portal-header::after)
   carries the red signature on its own. */

.portal-nav {
  display: flex; align-items: center;
  gap: 4px;
  margin-left: 36px;
  flex: 1;
}
.portal-nav a {
  /* R142 — small uppercase with wide tracking; matches the cert-plate
     typographic system used on page H1s. */
  color: rgba(250, 247, 242, 0.75);
  font-size: 11px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: var(--radius);
  transition: all 0.15s;
  letter-spacing: var(--track-wider);
  text-transform: uppercase;
}
.portal-nav a:hover { color: var(--cream); background: rgba(255,255,255,0.06); }
.portal-nav a.active {
  /* R142 — drop the red fill; the underline does the active-state work
     and the red wash competed with the brand-rail under the header. */
  color: var(--cream);
  background: rgba(255, 255, 255, 0.04);
  position: relative;
}
.portal-nav a.active::after {
  content: '';
  position: absolute;
  left: 14px; right: 14px; bottom: 4px;
  height: 2px;
  background: var(--red-500);
  border-radius: 1px;
}

.nav-spacer { flex: 1; }
.nav-user {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px;
  color: rgba(250, 247, 242, 0.85);
  white-space: nowrap;          /* keep "Sign out" on one line */
}
.nav-user #nav-username { white-space: nowrap; }
.nav-user .btn-link { color: rgba(250, 247, 242, 0.6); white-space: nowrap; }
.nav-user .btn-link:hover { color: var(--cream); }

.hamburger {
  display: none;
  background: none; border: none;
  /* R129 — bump 36→44 so the burger button meets WCAG AA tap-target
     guidelines (≥44pt). The bars inside are still 22×2, only the
     hit area grew. */
  width: 44px; height: 44px;
  margin-left: auto;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 4px;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.hamburger:hover { background: rgba(255,255,255,0.06); }
.hamburger span {
  display: block;
  width: 22px; height: 2px;
  background: var(--cream);
  transition: 0.2s;
}

.portal-main {
  /* R142 — wider canvas + more breathing room. Was 1200/40/24/80,
     bumped to 1280/56/40/96 to match luxury-catalogue spacing. The
     mobile @media block below tightens this on phones. */
  max-width: 1280px;
  margin: 0 auto;
  padding: 56px 40px 96px;
}
@media (max-width: 720px) {
  .portal-main { padding: 32px 20px 64px; }
}

.page-header {
  margin-bottom: 48px;
}
/* Action buttons under page-sub text need breathing room — Fraser
   flagged Crew Tracker + Watch Keeping looked cramped (2026-04-29).
   This applies to any direct-child <button>/<a class="btn"> inside a
   page-header so future pages get the spacing for free. */
.page-header > .btn,
.page-header > button {
  margin-top: 16px;
}
.page-header h1 {
  font-family: var(--display);
  /* Inter at 300 reads as modern editorial rather than chunky display.
     Clamp scales from 28→40 across phone→large desktop. */
  font-size: clamp(28px, 3.2vw, 40px);
  font-weight: 300;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.15;
  color: var(--navy-900);
  margin: 0 0 14px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--hairline-strong);
  position: relative;
}
.page-header h1::after {
  /* Short red rule under the H1 — a serif-display convention; gives the
     header a "section title" feel without an extra divider element. */
  content: '';
  position: absolute;
  left: 0; bottom: -1px;
  width: 48px; height: 1px;
  background: var(--red-500);
}
.coming-soon h1 { text-transform: uppercase; letter-spacing: 0.12em; font-weight: 300; }
.page-sub {
  color: var(--ink-soft);
  font-size: 15px;
  margin: 0;
}

/* Feature card grid */
.card-grid {
  display: grid;
  /* R142 — wider grid floor (260→280) and bigger gap (20→28) so cards
     breathe instead of feeling like a control panel. minmax with min()
     prevents the 280px floor from forcing horizontal overflow on phones. */
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 28px;
}
.feature-card {
  position: relative;
  background: #fff;
  /* R43 — hairline-on-canvas surface. The 1px border is replaced with
     box-shadow's hairline ring so the card sits exactly on a 1px grid
     (no double-border seams when adjacent to other ringed surfaces).
     R142 — padding evened out to 32/28 for a more balanced interior. */
  border: 0;
  border-radius: var(--radius-lg);
  padding: 32px 28px;
  display: block;
  color: var(--ink);
  transition: box-shadow 0.18s var(--ease-precise), transform 0.18s var(--ease-precise);
  box-shadow: var(--shadow-card);
}
.feature-card:hover {
  /* R142 — border-color hover was a no-op (the border was already removed,
     above). Promote to a red ring shadow + a slightly deeper lift, so the
     card reads as "selectable" rather than just sitting brighter. */
  transform: translateY(-2px);
  box-shadow:
    0 0 0 1px var(--red-500),
    0 12px 32px -8px rgba(225, 29, 46, 0.18),
    0 4px 12px rgba(40, 69, 88, 0.08);
  color: var(--ink);
}
.feature-icon {
  font-size: 30px;
  margin-bottom: 14px;
}
.feature-card h3 {
  font-family: var(--display);
  font-size: 22px;
  margin: 0 0 8px;
  font-weight: 600;
}
.feature-card p {
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
}
.feature-status {
  display: inline-block;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  border-radius: var(--radius-pill);
}
.feature-status.active {
  background: rgba(22, 101, 52, 0.1);
  color: var(--success);
}
.feature-status.soon {
  background: var(--cream-dark);
  color: var(--ink-soft);
}

/* R142 — canonical .pill component for the light-theme portal. The
   codebase has accreted dozens of *-pill variants (status-pill,
   crew-pill, leave-status-pill, drill-type-pill, etc.) all reinventing
   the same shape. New work should compose from this base + a variant.
   Variants follow BEM-double-dash naming (.pill--success) so they
   don't collide with the legacy .pill-on / .pill-off pair used by
   the dark watch-admin tables. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  background: var(--cream-dark);
  color: var(--ink-soft);
}
.pill--success { background: rgba(22, 101, 52, 0.10); color: var(--success); }
.pill--warn    { background: rgba(180, 83, 9, 0.10);  color: var(--warn); }
.pill--danger  { background: var(--red-100);          color: var(--red-700); }

/* Cars page */
.cars-toolbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

/* List/Calendar view toggle */
.view-toggle-group {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: #fff;
}
.view-toggle {
  background: #fff;
  border: none;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--track-tight);
  color: var(--ink-soft);
  cursor: pointer;
  transition: all 0.15s;
  font-family: var(--sans);
}
.view-toggle + .view-toggle { border-left: 1px solid var(--line); }
.view-toggle:hover { background: var(--cream-dark); color: var(--ink); }
.view-toggle.active {
  background: var(--navy-800);
  color: var(--cream);
}

/* ============================================================
   CALENDAR VIEW
   ============================================================ */
.cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.cal-nav-group {
  display: flex;
  align-items: center;
  gap: 4px;
}
.cal-nav-group h3 {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  margin: 0 8px;
  min-width: 200px;
  text-align: center;
  letter-spacing: -0.01em;
}
.cal-nav-btn {
  background: #fff;
  border: 1px solid var(--line);
  width: 36px; height: 36px;
  border-radius: var(--radius);
  font-size: 22px;
  line-height: 1;
  color: var(--navy-800);
  cursor: pointer;
  font-family: var(--sans);
  transition: all 0.15s;
}
.cal-nav-btn:hover { background: var(--cream-dark); border-color: var(--red-500); }

.cal-grid {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  overflow: hidden;
}
.cal-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--line);
}
.cal-row + .cal-row { border-top: 1px solid var(--line); margin-top: 1px; }
.cal-headers .cal-dow {
  background: #fff;
  padding: 10px 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}
.cal-day {
  background: #fff;
  min-height: 110px;
  padding: 6px 8px 8px;
  cursor: pointer;
  transition: background 0.1s;
  position: relative;
  display: flex;
  flex-direction: column;
}
.cal-day:hover { background: var(--cream); }
.cal-day.other-month { background: var(--cream); }
.cal-day.other-month .cal-daynum { color: var(--ink-muted); }
.cal-day.weekend { background: var(--cream); }
.cal-day.today {
  background: rgba(225, 29, 46, 0.04);
  box-shadow: inset 0 0 0 2px var(--red-500);
}
.cal-day.today .cal-daynum {
  color: var(--red-500);
  font-weight: 700;
}
.cal-daynum {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 4px;
}
.cal-bookings {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-height: 0;
}
.cal-pill {
  font-size: 11px;
  font-weight: 500;
  color: #fff;
  padding: 3px 6px;
  border-radius: var(--radius);
  border-left: 3px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: filter 0.1s;
}
.cal-pill:hover { filter: brightness(1.08); }
.cal-pill-time { font-weight: 700; opacity: 0.95; margin-right: 2px; }
.cal-pill-text { opacity: 0.95; }
.cal-pill.is-mine { box-shadow: 0 0 0 1px rgba(255,255,255,0.4) inset; }
.cal-more {
  font-size: 10px;
  color: var(--ink-soft);
  padding: 2px 6px;
  font-weight: 600;
}

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 16px;
  padding: 12px 4px 0;
  font-size: 12px;
  color: var(--ink-soft);
  border-top: 1px solid var(--line);
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.legend-dot {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 2px;
}
.legend-sub { color: var(--ink-muted); margin-left: 2px; font-weight: 400; }

/* ============================================================
   DAY TIMELINE VIEW
   ============================================================ */
.day-grid-wrap {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.day-grid {
  min-width: 900px;
}

/* R34 P1 — Day view zoom container. Inner grid expands to
   var(--cars-zoom)× the wrapper's width and overflows horizontally
   when zoomed. Vehicle labels stay pinned via position: sticky. */
.day-grid-wrap {
  position: relative;
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x pan-y;
}
.day-grid {
  width: calc(100% * var(--cars-zoom, 1));
  min-width: 100%;
  transition: width 80ms ease-out;
}
.day-zoom-controls {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 12px;
  padding: 2px 4px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
}
.day-zoom-controls .btn { min-width: 30px; padding: 4px 8px; }
.day-zoom-val {
  display: inline-block;
  min-width: 46px;
  text-align: center;
  font-size: 12px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.day-hours,
.day-row {
  display: grid;
  grid-template-columns: 160px 1fr;
}
.day-hours {
  background: var(--cream-dark);
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 600;
  letter-spacing: 0.5px;
}
.day-hours-label {
  padding: 10px 14px;
  border-right: 1px solid var(--line);
  text-transform: uppercase;
  letter-spacing: 1px;
  font-size: 10px;
  /* R34 P1 — pin while the timeline scrolls horizontally */
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--cream-dark);
}
.day-hours-axis {
  display: grid;
  grid-template-columns: repeat(16, 1fr);
}
.day-hour {
  padding: 9px 0 9px 8px;
  border-right: 1px solid rgba(229, 224, 213, 0.5);
  position: relative;
}
.day-hour:last-child { border-right: none; }
.day-hour span { display: inline-block; transform: translateX(-50%); position: relative; left: 0; }

.day-row {
  border-bottom: 1px solid var(--line);
}
.day-row:last-child { border-bottom: none; }
.day-car-name {
  padding: 14px 14px;
  border-right: 1px solid var(--line);
  background: var(--cream);
  font-weight: 600;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  /* R34 P1 — pin while the timeline scrolls horizontally */
  position: sticky;
  left: 0;
  z-index: 2;
}
.day-car-name .car-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--line);
}
.day-car-name-sub {
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 400;
  margin-top: 2px;
}

.day-lane {
  position: relative;
  min-height: 64px;
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(100% / 16 - 1px),
    rgba(229, 224, 213, 0.5) calc(100% / 16 - 1px),
    rgba(229, 224, 213, 0.5) calc(100% / 16)
  );
  cursor: copy;
}
.day-lane:hover { background-color: rgba(250, 247, 242, 0.5); }

.day-booking {
  position: absolute;
  top: 6px;
  bottom: 6px;
  padding: 7px 10px;
  border-radius: 4px;
  border-left: 3px solid transparent;  /* per-car colour set inline by JS */
  background: rgba(76, 115, 133, 0.9);   /* fallback only; overridden inline */
  color: #fff;
  font-size: 12px;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  transition: filter 0.12s, transform 0.12s;
  min-width: 14px;
  box-sizing: border-box;
}
.day-booking:hover { filter: brightness(1.08); }
.day-booking.is-mine { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.45); }

/* Currently-out booking: keeps the car's colour, but pulses with a white halo + OUT badge.
   The colour-agnostic glow makes "OUT NOW" read on any car colour. */
.day-booking.is-out-now {
  z-index: 5;
  filter: brightness(1.12) saturate(1.1);
  animation: outNowPulse 2.2s ease-in-out infinite;
}
@keyframes outNowPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.55), inset 0 0 0 1.5px rgba(255,255,255,0.7); }
  50%      { box-shadow: 0 0 0 6px rgba(255, 255, 255, 0),   inset 0 0 0 1.5px rgba(255,255,255,0.7); }
}
.day-booking.is-out-now::after {
  content: 'OUT';
  position: absolute;
  top: 5px; right: 6px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 1.4px;
  background: rgba(255, 255, 255, 0.32);
  color: #fff;
  padding: 1px 7px;
  border-radius: 10px;
  pointer-events: none;
}

/* Past bookings today: faded — opacity-based so the car colour is preserved */
.day-booking.is-past {
  opacity: 0.55;
  filter: saturate(0.7);
}
.day-booking-time {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  opacity: 0.9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.day-booking-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.day-now {
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: var(--ink-muted);
  opacity: 0.55;
  z-index: 4;
  pointer-events: none;
}

/* R24a — Day view layered bars.
   The booked window (`.day-booking`) becomes a faint hatched base
   when an actual sign-out exists; the actual usage (`.day-actual`)
   sits on top as the solid bright bar. OUT and IN ticks mark the
   exact sign-out / sign-in clock positions. */
.day-booking.is-planned {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.12) 0,
    rgba(255,255,255,0.12) 4px,
    transparent 4px,
    transparent 8px
  );
}
.day-booking.is-forgotten {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(184, 106, 0, 0.35) 0,
    rgba(184, 106, 0, 0.35) 4px,
    transparent 4px,
    transparent 8px
  );
  border-left-color: #b86a00 !important;
}
/* Once a booking has an actual sign-out, dim its booked-window base so
   the solid actual-usage bar reads as the foreground. The class is
   set per-booking by the JS so other bookings in the same lane stay
   at full saturation. */
.day-booking.is-with-actual {
  opacity: 0.35;
  filter: saturate(0.7);
}
/* Actual-usage solid overlay */
.day-actual {
  position: absolute;
  top: 9px;
  bottom: 9px;
  border-radius: 4px;
  border-left: 3px solid rgba(0,0,0,0.18);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 6;
  box-shadow: 0 1px 4px rgba(40, 69, 88, 0.35);
  overflow: hidden;
  transition: filter 0.12s, transform 0.12s;
  min-width: 12px;
  box-sizing: border-box;
}
.day-actual:hover { filter: brightness(1.08); }
.day-actual-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 6px;
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
}
/* OUT — currently in use, navy halo */
.day-actual.is-out {
  z-index: 7;
  animation: outNowPulse 2.4s ease-in-out infinite;
}
/* OVERDUE — currently late, red halo */
.day-actual.is-overdue {
  z-index: 8;
  box-shadow: 0 1px 4px rgba(225, 29, 46, 0.5);
  animation: outOverduePulse 1.6s ease-in-out infinite;
}
@keyframes outOverduePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(225, 29, 46, 0.55), 0 1px 4px rgba(225, 29, 46, 0.5); }
  50%      { box-shadow: 0 0 0 5px rgba(225, 29, 46, 0),    0 1px 4px rgba(225, 29, 46, 0.5); }
}
.day-actual.is-returned { opacity: 0.92; }

/* OUT / IN tick marks — vertical line spanning the lane, with a small
   chip label pinned to the top edge inside the lane. Sits above the
   booked-window base + actual-usage overlay so the captain reads the
   exact sign-out / sign-in clock positions even on a tight bar. */
.day-tick {
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: var(--navy-900, #284558);
  z-index: 9;
  pointer-events: none;
}
.day-tick-out { background: #14785a; }
.day-tick-in  { background: var(--navy-900, #284558); }
.day-tick-label {
  position: absolute;
  top: -2px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  white-space: nowrap;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--navy-900, #284558);
  color: #fff;
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
  box-shadow: 0 1px 3px rgba(40, 69, 88, 0.3);
}
.day-tick-out .day-tick-label { background: #14785a; }
.day-tick-in  .day-tick-label { background: var(--navy-900, #284558); }
.day-now::before {
  content: '';
  position: absolute;
  top: -2px; left: -2px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--ink-muted);
}

@media (max-width: 720px) {
  .day-hours,
  .day-row { grid-template-columns: 110px 1fr; }
  .day-car-name { padding: 10px; font-size: 13px; }
  .day-car-name-sub { display: none; }
  .day-hours-label { padding: 8px 10px; }
  .day-booking-title { font-size: 11px; }
}

/* Calendar mobile: simplify */
@media (max-width: 720px) {
  /* Legacy mini-calendar selectors (.cal-day, .cal-pill, etc.) used
     elsewhere — left untouched. */
  .cal-nav-group h3 { font-size: 18px; min-width: 140px; }
  .cal-day { min-height: 70px; padding: 4px 4px 6px; }
  .cal-daynum { font-size: 12px; }
  .cal-pill { font-size: 9px; padding: 2px 4px; }
  .cal-pill-text { display: none; }
  .cal-pill::after { content: '●'; margin-left: 2px; opacity: 0.8; }
  .cal-headers .cal-dow { font-size: 9px; padding: 6px 2px; }

  /* R56 — master-calendar bars on phones: shorter rows, smaller
     text, dropped padding so they still read at ~50px col width. */
  .cal-week {
    grid-template-rows: 22px repeat(var(--slot-count, 0), 16px) 1fr;
    min-height: 72px;
  }
  .cal-event-bar {
    font-size: 9.5px;
    padding: 0 5px;
    line-height: 1.5;
    margin: 0 2px;
    letter-spacing: 0;
  }
  .cal-event-bar.is-single::before {
    width: 5px; height: 5px; margin-right: 4px;
  }
  .cal-day-num { font-size: 11px; }
  .cal-cell.today .cal-day-num {
    width: 18px; height: 18px; font-size: 10px;
  }
  .cal-cell { padding: 3px 4px 4px; }
  /* Stack the day-detail panel below the grid instead of beside it. */
  .calendar-body { grid-template-columns: 1fr; }
  .calendar-day-panel { border-left: 0; border-top: 1px solid var(--navy-100, #DCE7ED); }
}
.car-filter {
  display: flex; flex-direction: column;
}
.car-filter label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.car-filter select {
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  font-size: 14px;
  min-width: 200px;
  font-family: var(--sans);
}

.cars-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 20px;
}
.tab {
  background: none; border: none;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--track-tight);
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all 0.15s;
}
.tab:hover { color: var(--ink); }
.tab.tab-active {
  color: var(--navy-800);
  border-bottom-color: var(--red-500);
}

.bookings-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.booking-card {
  background: #fff;
  border: 1px solid var(--line);
  border-left: 4px solid var(--red-500);  /* per-car colour set inline by JS */
  border-radius: var(--radius);
  padding: 16px 20px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 16px;
  align-items: center;
  cursor: pointer;
  transition: all 0.15s;
}
.booking-card:hover {
  box-shadow: var(--shadow-sm);
  filter: brightness(1.02);
}
.booking-card.is-mine { box-shadow: inset 2px 0 0 0 rgba(255,255,255,0.6); }
.booking-card.is-active { background: linear-gradient(to right, rgba(22, 101, 52, 0.04), transparent); }
.booking-card .b-car { display: inline-flex; align-items: center; gap: 6px; }
.booking-card .b-car .car-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

.booking-time {
  font-family: var(--display);
  font-weight: 600;
  text-align: center;
  min-width: 80px;
}
.booking-time .day {
  display: block;
  font-size: 26px;
  line-height: 1;
}
.booking-time .month {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ink-soft);
  margin-top: 4px;
}
.booking-time .hours {
  display: block;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 6px;
  font-family: var(--sans);
  font-weight: 500;
}

.booking-body .b-purpose {
  font-weight: 600;
  font-size: 15px;
  margin: 0 0 4px;
}
.booking-body .b-meta {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0;
}
.booking-body .b-meta span + span::before {
  content: '·';
  margin: 0 8px;
  color: var(--line);
}

.booking-tag {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--cream-dark);
  color: var(--ink-soft);
  white-space: nowrap;
}
.booking-tag.tag-active {
  background: rgba(22, 101, 52, 0.12);
  color: var(--success);
}
.booking-tag.tag-mine {
  background: var(--red-100);
  color: var(--red-700);
}
.booking-tag.tag-overdue {
  background: rgba(225, 29, 46, 0.18);
  color: var(--red-700);
  border: 1px dashed var(--red-700);
}
.booking-tag.tag-returned {
  background: rgba(0,0,0,0.05);
  color: var(--ink-muted);
}
/* FORGOTTEN — booking ran past its window without anyone signing out. */
.booking-tag.tag-forgotten {
  background: rgba(184, 106, 0, 0.14);
  color: #78501e;
  border: 1px dashed #b86a00;
}

/* Sign-out / Sign-in action button on the booking card */
.booking-action {
  white-space: nowrap;
}
/* R36 — stack the primary action + Cancel link vertically on the right
   edge of the row. On phone it'll wrap below the meta line as before. */
.booking-action-stack {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.booking-cancel {
  font-size: 11px;
  color: var(--ink-muted, #8A94A6);
  text-decoration: underline;
  padding: 2px 4px;
}
.booking-cancel:hover { color: var(--red-500, #E11D2E); }
.booking-card.state-out { border-left-width: 4px; }
.booking-card.state-overdue { background: rgba(225, 29, 46, 0.04); }
.booking-card.state-returned { opacity: 0.85; }
.booking-card.state-forgotten {
  background: rgba(220, 130, 0, 0.05);
  border-left-color: #b86a00 !important;
}

/* ============================================================
   VEHICLE STATUS BOARD (R24a) — top-of-page status strip on
   #/cars. One card per vehicle showing the live state. The
   bookings list below stays as reference.
   ============================================================ */
.cars-status-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 12px;
  margin: 0 0 20px;
}
.vehicle-card {
  position: relative;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px 14px;
  box-shadow: 0 2px 8px rgba(40, 69, 88, 0.05);
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.vehicle-card:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(40, 69, 88, 0.10); }
.vehicle-stripe {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px;
}
.vehicle-card-head {
  display: flex; flex-direction: column; gap: 4px;
}
.vehicle-status {
  font-family: var(--display, sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.vehicle-name {
  font-family: var(--display, serif);
  font-size: 17px;
  font-weight: 700;
  color: var(--navy-900, #284558);
  letter-spacing: 0.01em;
}
/* R39 — make / model / colour / plate line under the vehicle name */
.vehicle-subline {
  display: block;
  font-size: 12px;
  color: var(--ink-muted, #667085);
  margin-top: 2px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* R39 — Manage Vehicles modal list */
.cars-manage-list {
  display: flex; flex-direction: column;
  gap: 8px;
  margin: 8px 0 16px;
}
.cars-manage-row {
  display: flex; align-items: center; gap: 12px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px 14px;
}
.cars-manage-main { flex: 1; min-width: 0; }
.cars-manage-name {
  font-weight: 700;
  color: var(--navy-900);
  font-size: 14px;
}
.cars-manage-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 2px;
}
.cars-manage-badges {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 6px;
}
.cars-manage-badge {
  font-size: 11px;
  text-transform: capitalize;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--navy-50, #F2F5F8);
  color: var(--navy-700);
}
.cars-manage-notes {
  font-size: 12px;
  color: var(--ink);
  margin-top: 6px;
  font-style: italic;
}
.cars-manage-expiry {
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 4px;
}
.cars-manage-actions {
  flex-shrink: 0;
}
.vehicle-card-body {
  flex: 1;
  display: flex; flex-direction: column; gap: 2px;
}
.vehicle-line {
  margin: 0;
  font-size: 13px;
  color: var(--ink);
  line-height: 1.45;
}
.vehicle-line + .vehicle-line { color: var(--ink-muted); font-size: 12px; }
.vehicle-cta {
  margin-top: 6px;
  align-self: flex-start;
  background: var(--navy-900, #284558);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: transform 100ms ease, background 120ms ease;
}
.vehicle-cta:hover { transform: translateY(-1px); background: #163a64; }
/* AVAILABLE / BOOKED cards expose two CTAs side by side: walk-up "Take it
   now" (primary navy) and "Book later" (secondary text-button). */
.vehicle-cta-row {
  display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px;
}
.vehicle-cta-take { /* primary — same as base .vehicle-cta */ }
.vehicle-cta-secondary {
  background: transparent;
  color: var(--navy-700, #284B73);
  border: 1px solid rgba(40, 69, 88, 0.18);
  padding: 8px 14px;
}
.vehicle-cta-secondary:hover {
  background: rgba(40, 69, 88, 0.05);
  color: var(--navy-900);
}

/* Two-stamp time strip on OUT / OVERDUE cards (R24a). Reads as
   "Out 10:40 → Due back 12:10" with the OUT side bold-navy and the
   DUE side switching to red when the booking is overdue. */
.vehicle-time-strip {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 6px 0 4px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(40, 69, 88, 0.06);
  border: 1px solid rgba(40, 69, 88, 0.10);
}
.vehicle-time-strip.is-overdue {
  background: rgba(225, 29, 46, 0.08);
  border-color: rgba(225, 29, 46, 0.25);
}
.vehicle-ts {
  display: flex; flex-direction: column; gap: 1px;
  flex: 1; min-width: 0;
}
.vehicle-ts-label {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-weight: 600;
}
.vehicle-ts-value {
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
  font-size: 18px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.05;
}
.vehicle-ts-arrow {
  color: var(--ink-muted);
  font-size: 16px;
  flex-shrink: 0;
}
.vehicle-time-strip.is-overdue .vehicle-ts:last-child .vehicle-ts-label { color: #9F1220; }
.vehicle-time-strip.is-overdue .vehicle-ts:last-child .vehicle-ts-value { color: #9F1220; }

/* AVAILABLE — quiet, navy stripe, default look. */
.vehicle-card.is-available .vehicle-status { color: #14785a; }
/* BOOKED-soon — amber accent so the eye picks it up next. */
.vehicle-card.is-booked {
  background: linear-gradient(180deg, rgba(220, 130, 0, 0.04), #fff 60%);
}
.vehicle-card.is-booked .vehicle-status { color: #b86a00; }
/* READY TO COLLECT — captain (or booker) is currently inside the booking
   window and just needs to tap Sign out. */
.vehicle-card.is-ready {
  background: linear-gradient(180deg, rgba(40, 69, 88, 0.05), #fff 60%);
  border-color: rgba(40, 69, 88, 0.25);
}
.vehicle-card.is-ready .vehicle-status { color: var(--navy-900); }
.vehicle-card.is-ready .vehicle-cta { background: #14785a; }
.vehicle-card.is-ready .vehicle-cta:hover { background: #105f48; }
/* OUT — pulsing navy ring + faint background tint. */
.vehicle-card.is-out {
  background: linear-gradient(180deg, rgba(40, 69, 88, 0.06), #fff 70%);
  border-color: rgba(40, 69, 88, 0.40);
  box-shadow: 0 0 0 0 rgba(40, 69, 88, 0.45);
  animation: vehicle-pulse-navy 2.4s ease-in-out infinite;
}
.vehicle-card.is-out .vehicle-status { color: var(--navy-900); }
@keyframes vehicle-pulse-navy {
  0%, 100% { box-shadow: 0 0 0 0 rgba(40, 69, 88, 0.0); }
  50%      { box-shadow: 0 0 0 6px rgba(40, 69, 88, 0.12); }
}
/* OVERDUE — same pulse, red. */
.vehicle-card.is-overdue {
  background: linear-gradient(180deg, rgba(225, 29, 46, 0.07), #fff 70%);
  border-color: rgba(225, 29, 46, 0.45);
  animation: vehicle-pulse-red 1.6s ease-in-out infinite;
}
.vehicle-card.is-overdue .vehicle-status { color: #9F1220; }
.vehicle-card.is-overdue .vehicle-cta { background: #9F1220; }
.vehicle-card.is-overdue .vehicle-cta:hover { background: #7d0e1a; }
@keyframes vehicle-pulse-red {
  0%, 100% { box-shadow: 0 0 0 0 rgba(225, 29, 46, 0.0); }
  50%      { box-shadow: 0 0 0 6px rgba(225, 29, 46, 0.18); }
}
@media (max-width: 640px) {
  .cars-status-board { grid-template-columns: 1fr; }
}

/* Footer of a returned booking — duration / fuel / mileage / incident */
.booking-return {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-muted);
  padding-top: 8px;
  border-top: 1px dashed var(--navy-100);
}
.booking-return strong { color: var(--navy-800); }
.booking-incident { color: var(--red-700); font-weight: 700; }

/* Fuel-level radio grid in the sign-in modal — five buttons sized like
   gauge increments. The native radio is hidden; the label acts as the chip. */
.fuel-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  margin-top: 6px;
}
.fuel-opt { position: relative; cursor: pointer; }
.fuel-opt input[type="radio"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.fuel-opt span {
  display: grid;
  place-items: center;
  padding: 12px 0;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  background: #fff;
  font-weight: 700;
  font-size: 14px;
  color: var(--navy-800);
}
.fuel-opt input[type="radio"]:checked + span {
  background: var(--navy-900);
  color: #fff;
  border-color: var(--navy-900);
}
.fuel-opt:hover span { border-color: var(--navy-700); }

.empty-state {
  text-align: center;
  padding: 50px 20px;
  color: var(--ink-soft);
  font-size: 14px;
  background: #fff;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

/* Coming soon */
.coming-soon {
  text-align: center;
  padding: 70px 20px;
  max-width: 500px;
  margin: 0 auto;
}
.coming-soon-crest {
  width: 90px;
  margin-bottom: 24px;
  opacity: 0.55;
}
.coming-soon h1 {
  font-family: var(--display);
  font-size: 34px;
  margin: 0 0 14px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.coming-soon p { color: var(--ink-soft); font-size: 15px; line-height: 1.6; }
.coming-soon-note {
  margin-top: 24px;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--red-700);
  font-weight: 600;
}

/* Mobile portal */
@media (max-width: 900px) {
  /* Belt-and-braces: prevent any single overflowing child from making
     the entire page scroll horizontally. Anything that genuinely needs
     to scroll (the schedule grid, the hours grid) does it inside its
     own container with its own overflow. */
  html, body { overflow-x: hidden; max-width: 100vw; }

  .hamburger { display: flex; }
  /* R25 — mobile nav drawer slides in from the RIGHT edge with a
     backdrop. Replaces the previous "drops down from the header"
     pattern which floated awkwardly over the page H1. The drawer
     is a fixed full-height column at 88vw / max 360px, with body
     scroll locked while open so the underlying page can't scroll
     beneath the user's thumb. */
  .portal-nav {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: 88vw;
    max-width: 360px;
    height: 100vh;
    height: 100dvh;
    background: var(--navy-800);
    flex-direction: column;
    align-items: stretch;
    padding: 64px 16px 24px;     /* top room for the close X */
    gap: 2px;
    margin-left: 0;
    box-shadow: -10px 0 30px rgba(0, 0, 0, 0.35);
    transform: translateX(100%);
    transition: transform 0.25s ease-out;
    border-top: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-sizing: border-box;
    z-index: 1200;
  }
  .portal-nav.open { transform: translateX(0); }
  /* Close X inside the drawer — synthesised via ::before on the nav. */
  .portal-nav::before {
    content: '✕';
    position: absolute;
    top: 14px; right: 14px;
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.10);
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    z-index: 2;
    pointer-events: auto;
  }
  /* "Menu" eyebrow at the top-left of the drawer for orientation. */
  .portal-nav::after {
    content: 'Menu';
    position: absolute;
    top: 22px; left: 20px;
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    font-weight: 600;
    z-index: 2;
  }
  /* Backdrop — full-screen scrim that fades in when the drawer is open. */
  body.menu-open::before {
    content: '';
    position: fixed; inset: 0;
    background: rgba(8, 16, 30, 0.65);
    z-index: 1150;
    animation: nav-backdrop-in 0.2s ease-out;
  }
  @keyframes nav-backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  /* Lock the underlying page so iOS doesn't scroll behind the drawer. */
  body.menu-open { overflow: hidden; }
  /* R25 — mobile drawer contrast & layout. Using `body #portal-nav` to
     get ID + class specificity (0,1,1,0 → beats anything class-based)
     and bright fully-opaque white text + lighter row backgrounds so
     items read clearly on the navy panel. The earlier rules used
     transparent backgrounds at 4% white which were invisible on dark
     navy and made the menu look "blurry / faded" (Fraser, 2026-04-30). */
  body #portal-nav a,
  body #portal-nav .nav-trigger,
  body #portal-nav button.nav-trigger {
    padding: 16px 18px !important;
    white-space: normal !important;
    word-wrap: break-word !important;
    min-height: 56px !important;
    display: flex !important;
    align-items: center !important;
    color: #ffffff !important;
    font-size: 16px !important;
    font-weight: 700 !important;
    letter-spacing: 0.04em !important;
    border-radius: 10px !important;
    /* Visible row background so items read as discrete tap targets. */
    background: rgba(255, 255, 255, 0.10) !important;
    width: 100% !important;
    box-sizing: border-box !important;
    text-decoration: none !important;
    border: 1px solid rgba(255, 255, 255, 0.18) !important;
    margin-bottom: 6px !important;
    cursor: pointer !important;
    text-shadow: none !important;
    opacity: 1 !important;
  }
  body #portal-nav .nav-trigger {
    justify-content: space-between !important;
    text-align: left !important;
  }
  body #portal-nav .nav-trigger .caret {
    opacity: 1 !important;
    transition: transform 0.18s ease !important;
    margin-left: 10px !important;
    color: #ffffff !important;
    transform: none !important;
  }
  body #portal-nav .nav-trigger .caret .ic { width: 16px !important; height: 16px !important; }
  body #portal-nav .nav-dropdown.open .nav-trigger .caret {
    transform: rotate(180deg) !important;
  }
  body #portal-nav .nav-dropdown.open .nav-trigger {
    background: rgba(255, 255, 255, 0.18) !important;
    border-color: rgba(255, 255, 255, 0.30) !important;
  }
  body #portal-nav a:active,
  body #portal-nav .nav-trigger:active {
    background: rgba(255, 255, 255, 0.24) !important;
  }
  body #portal-nav a.active::after { display: none !important; }
  body #portal-nav a.active {
    background: rgba(225, 29, 46, 0.35) !important;
    color: #ffffff !important;
    border: 1px solid rgba(225, 29, 46, 0.75) !important;
    border-left: 4px solid var(--red-500) !important;
    padding-left: 15px !important;
  }
  /* Nested submenu — slides in below the trigger when open. */
  body #portal-nav .nav-menu {
    background: rgba(0, 0, 0, 0.35) !important;
    border-radius: 10px !important;
    padding: 6px !important;
    margin: 0 0 8px 14px !important;
    border-left: 3px solid var(--red-500) !important;
    border-top: none !important;
    border-right: none !important;
    border-bottom: none !important;
    box-shadow: none !important;
    min-width: 0 !important;
  }
  body #portal-nav .nav-menu a {
    color: #ffffff !important;
    font-size: 15px !important;
    font-weight: 500 !important;
    min-height: 48px !important;
    padding: 12px 14px !important;
    background: rgba(255, 255, 255, 0.04) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    margin-bottom: 4px !important;
    opacity: 1 !important;
  }
  body #portal-nav .nav-menu a:last-child { margin-bottom: 0 !important; }
  body #portal-nav .nav-menu a:active {
    background: rgba(255, 255, 255, 0.16) !important;
  }
  body #portal-nav .nav-menu a.active {
    color: #ffffff !important;
    background: rgba(225, 29, 46, 0.30) !important;
    border-color: rgba(225, 29, 46, 0.60) !important;
    font-weight: 700 !important;
  }
  .nav-spacer { display: none; }
  .nav-user {
    border-top: 1px solid rgba(255,255,255,0.08);
    padding-top: 12px;
    margin-top: 8px;
    justify-content: space-between;
  }
  /* Notifications bell + user dropdown: stack neatly inside the open
     vertical nav rather than trying to be inline header chips. */
  .portal-nav > div[style*="position: relative"] { width: 100%; }
  .portal-nav .notif-trigger {
    margin: 8px 0 0;
    width: 100%;
    height: 44px;
    border-radius: 8px;
    justify-content: flex-start;
    padding: 0 16px;
    gap: 10px;
    border-color: rgba(255,255,255,0.10);
  }
  .portal-nav .notif-trigger::after {
    content: 'Notifications';
    font-size: 14px;
    color: var(--cream);
    font-weight: 500;
  }
  .portal-nav .notif-badge { right: auto; left: 30px; top: 6px; }
  /* .portal-nav .notif-panel block removed — panel moved out of
     .portal-nav to body root in R27 P3d so it can render on
     mobile where .portal-nav is display:none. The standalone
     .notif-panel rules near the top of this file now own its
     responsive sizing. */
  .user-dropdown { width: 100%; margin-top: 4px; border-top: 1px solid rgba(255,255,255,0.08); padding-top: 12px; }
  .user-trigger {
    width: 100%;
    justify-content: flex-start;
    border-radius: 8px;
    padding: 8px 14px;
    height: 44px;
  }
  .user-menu {
    position: static;
    width: 100%;
    margin-top: 6px;
    border-radius: 8px;
    box-shadow: none;
  }
  /* Allow nav-menu items to wrap rather than overflow off the right edge. */
  .nav-menu a { white-space: normal; word-wrap: break-word; }

  .header-wordmark { height: 22px; }
  .page-header h1 { font-size: 28px; word-wrap: break-word; }
  .page-header { display: block; }   /* drop the cramped flex layout */
  .page-header .btn { margin-top: 10px; }
  .portal-main { padding: 24px 16px 80px; }
  .booking-card {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
  }
  .booking-tag { grid-column: 1 / -1; justify-self: start; }

  /* Vessel-tracker actions: stack each control on its own row so the AIS
     pill, range selector, and external links don't fight for space. */
  .vessel-tracker-head { padding: 14px 16px; }
  .vessel-tracker-actions {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .vessel-tracker-actions > * { width: 100%; }
  .ais-status { justify-content: flex-start; padding: 8px 12px; }
  .ais-traffic-toggle { justify-content: flex-start; }
  .ais-traffic-range { width: 100%; }
  .vessel-tracker-actions .btn-sm { text-align: center; }
}

/* ============================================================
   R25 — MOBILE DRAWER (fresh build 2026-04-30). Self-contained
   navigation drawer that replaces .portal-nav on mobile. Lives
   in its own `mn-` namespace so nothing in the rest of the
   stylesheet can override it.
   ============================================================ */
.mn-drawer {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
}
.mn-drawer.is-open { display: block; }
.mn-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(7, 14, 26, 0.65);
  animation: mn-fade-in 180ms ease-out;
}
.mn-panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 88vw;
  max-width: 360px;
  background: #0a1d36;
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  animation: mn-slide-in 220ms ease-out;
  overflow: hidden;
}
@keyframes mn-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes mn-slide-in {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.mn-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
.mn-eyebrow {
  color: rgba(255, 255, 255, 0.6);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.mn-close {
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.10);
  color: #ffffff;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.mn-close:active { background: rgba(255, 255, 255, 0.22); }
.mn-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  -webkit-overflow-scrolling: touch;
}
.mn-link,
.mn-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 56px;
  padding: 14px 16px;
  margin: 0 0 6px;
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  font-family: inherit;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-decoration: none;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  text-align: left;
  box-sizing: border-box;
}
.mn-link:active,
.mn-trigger:active {
  background: rgba(255, 255, 255, 0.20);
  border-color: rgba(255, 255, 255, 0.30);
}
.mn-link.is-active {
  background: rgba(225, 29, 46, 0.32);
  border-color: rgba(225, 29, 46, 0.70);
  border-left: 4px solid var(--red-500, #E11D2E);
  padding-left: 13px;
}
.mn-caret {
  display: inline-block;
  font-size: 14px;
  margin-left: 10px;
  transition: transform 200ms ease;
}
.mn-group.is-open .mn-caret { transform: rotate(180deg); }
.mn-group.is-open .mn-trigger {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.28);
  border-radius: 10px 10px 0 0;
  margin-bottom: 0;
}
.mn-submenu {
  display: none;
  padding: 6px;
  margin: 0 0 6px;
  background: rgba(0, 0, 0, 0.30);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-top: none;
  border-left: 3px solid var(--red-500, #E11D2E);
  border-radius: 0 0 10px 10px;
}
.mn-group.is-open .mn-submenu { display: block; }
.mn-sublink {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.04);
  color: #ffffff;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  border-radius: 8px;
  margin: 0 0 4px;
  border: 1px solid transparent;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.mn-sublink:last-child { margin-bottom: 0; }
.mn-sublink:active { background: rgba(255, 255, 255, 0.16); }
.mn-sublink.is-active {
  background: rgba(225, 29, 46, 0.28);
  border-color: rgba(225, 29, 46, 0.55);
  font-weight: 700;
}
.mn-divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.12);
  margin: 12px 0;
}
.mn-foot {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
}
/* Lock body scroll when drawer is open */
body.mn-locked { overflow: hidden; }

/* Hide the desktop .portal-nav entirely on mobile — the mobile drawer
   is the source of truth at ≤900px. */
@media (max-width: 900px) {
  .portal-nav { display: none !important; }
}

/* ============================================================
   R25 — phone-tight breakpoint (≤640px). The 900px block above
   handles tablet-ish width; this block does the further squeeze
   that a 375-430px phone needs: smaller H1, full-width primary
   CTAs, stacked toolbars, larger tap targets on inline buttons.
   ============================================================ */
@media (max-width: 640px) {
  /* Page header — drop the display H1 so it doesn't wrap or clip
     under the drawer. Subtitle stays readable. */
  .page-header h1 { font-size: 22px; line-height: 1.2; }
  .page-header { margin-bottom: 18px; }
  .page-sub { font-size: 13px; }

  /* Generic toolbar (used by Cars + others): single column with the
     primary CTA full-width at the bottom. */
  .cars-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .cars-toolbar > * { width: 100%; }
  .cars-toolbar .car-filter,
  .cars-toolbar .view-toggle-group { width: 100%; }
  .cars-toolbar .view-toggle-group { display: flex; }
  .cars-toolbar .view-toggle { flex: 1; padding: 12px 8px; }
  .cars-toolbar .btn { width: 100%; min-height: 44px; }

  /* Tap target uplift on inline buttons inside content cards
     (booking rows, vehicle cards, etc.). btn-sm is too small for
     thumb targets on phones. */
  .booking-card .btn-sm,
  .vehicle-cta {
    min-height: 44px;
    padding: 10px 16px;
    font-size: 14px;
  }
  /* Booking row layout: stack the action button below the meta line
     so the row reads top-to-bottom without crammed columns. */
  .booking-action {
    grid-column: 1 / -1 !important;
    width: 100%;
    margin-top: 8px;
  }

  /* Hub section toolbars + cert filters — ensure chips wrap rather
     than scroll horizontally. */
  .hub-section-toolbar,
  .cert-filters,
  .module-toolbar {
    flex-wrap: wrap;
    gap: 6px;
  }

  /* Form rows on phone — stack instead of side-by-side. */
  .form-row {
    grid-template-columns: 1fr !important;
    flex-direction: column;
  }
  .form-row > * { width: 100%; }

  /* Bridge HUD readouts go to 2 columns on small phones. */
  .vessel-hud-readouts { grid-template-columns: repeat(2, 1fr) !important; }
  .vessel-hud { padding: 12px; }

  /* Status board cards already collapse to 1-col via the existing
     auto-fill rule, but make sure the CTA row inside them wraps. */
  .vehicle-cta-row { flex-direction: column; }
  .vehicle-cta-row .vehicle-cta { width: 100%; text-align: center; }

  /* Notices / generic empty-state cards — tighter padding. */
  .empty-state { padding: 32px 18px; font-size: 13px; }
}

/* ============================================================
   MODAL
   ============================================================ */
.modal {
  position: fixed; inset: 0;
  background: rgba(40, 69, 88, 0.55);
  display: flex; align-items: center; justify-content: center;
  /* More breathing room around the card so it doesn't sit flush against
     the viewport edges. Subtle backdrop-blur softens the page behind. */
  padding: 36px 28px;
  /* R129 — safe-area-aware padding so the card never tucks under the
     iOS notch / Dynamic Island / home indicator when launched as a
     standalone PWA. max() keeps the 28/36px design floor on devices
     without inset. */
  padding-top:    max(36px, env(safe-area-inset-top));
  padding-bottom: max(36px, env(safe-area-inset-bottom));
  padding-left:   max(28px, env(safe-area-inset-left));
  padding-right:  max(28px, env(safe-area-inset-right));
  /* Above the sticky header (1100) and Leaflet's controls (1000). */
  z-index: 2000;
  animation: fadeIn 0.15s;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* R26 — the document preview modal is sometimes opened on top of the
   crew-docs list modal (Captain clicks "View documents" → "Preview").
   Both default to z-index 2000 and DOM order would put the docs list
   above the preview, hiding it. Bump preview to 2100 so it always
   wins, regardless of which modal opened it. */
#doc-preview-modal { z-index: 2100; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* R25 — universal mobile bottom-sheet for modals at ≤640px. Every
   modal becomes a slide-up sheet from the bottom: full width, rounded
   top corners only, max-height 92vh, swipe-to-dismiss visual cue at
   the top (the small grey handle). Avoids the cramped centred-card
   look that didn't work on phones. */
@media (max-width: 640px) {
  .modal {
    align-items: flex-end !important;
    padding: 0 !important;
  }
  .modal .modal-card {
    width: 100% !important;
    max-width: 100% !important;
    max-height: 92vh !important;
    max-height: 92dvh !important;
    border-radius: 16px 16px 0 0 !important;
    margin: 0 !important;
    padding: 22px 18px 28px !important;
    /* R129 — extend bottom padding with the iPhone home indicator
       safe-area so content / sticky CTAs don't hide under the
       indicator on standalone PWA. */
    padding-bottom: calc(28px + env(safe-area-inset-bottom)) !important;
    animation: modalSheetIn 0.22s ease-out !important;
    position: relative;
  }
  /* Drag-handle indicator */
  .modal .modal-card::before {
    content: '';
    position: absolute;
    top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 40px; height: 4px;
    border-radius: 2px;
    background: rgba(52, 85, 120, 0.18);
  }
  @keyframes modalSheetIn {
    from { transform: translateY(50px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
  }
  .modal .modal-close {
    width: 36px; height: 36px;
  }
}

/* Side-panel variant of the modal — slides in from the right. Used by the
   Itinerary Planner stop editor (R23) so the captain can edit a day in a
   focused workspace without losing the page context behind it. */
.modal.modal-side {
  align-items: stretch;
  justify-content: flex-end;
}
.modal-side .modal-side-card {
  max-width: 520px;
  width: 100%;
  max-height: 100vh;
  max-height: 100dvh;
  border-radius: 14px 0 0 14px;
  animation: modalSideIn 0.22s ease-out;
}
@keyframes modalSideIn {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@media (max-width: 640px) {
  .modal-side .modal-side-card {
    max-width: 100%;
    border-radius: 14px 14px 0 0;
    margin-top: auto;
    max-height: 92vh;
  }
  @keyframes modalSideIn {
    from { transform: translateY(40px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
  }
}

.modal-card {
  /* R142 — flat warm-white replaces the dolphin-blue gradient. The
     gradient was a holdover from when modals competed with the
     blue page background; with the new luxury-catalogue palette
     a flat warm-white reads as "fine paper" instead of "ipad screen". */
  background: #FCFBF7;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xl);
  width: 100%;
  max-width: 560px;
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: var(--shadow-modal);
  animation: modalIn 0.18s ease-out;
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.modal-header {
  padding: 22px 28px 16px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Default body padding for any form / direct content inside a modal card.
   Previously only the booking form had explicit padding; every other modal
   was rendering form fields flush against the card edge. This rule gives
   every modal the same generous interior gutter automatically. */
.modal-card > form,
.modal-card > p,
.modal-card > h2,
.modal-card > h4,
.modal-card > div:not(.modal-header):not(.modal-actions):not(.pin-card-body):not(#pin-card-body) {
  padding-left: 28px;
  padding-right: 28px;
}
.modal-card > form { padding-top: 18px; padding-bottom: 22px; }
.modal-card > .modal-actions { padding-left: 28px; padding-right: 28px; padding-bottom: 18px; }
.modal-header h3 {
  font-family: var(--display);
  font-size: 24px;
  margin: 0;
  font-weight: 600;
}
.modal-close {
  background: none; border: none;
  font-size: 28px; line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0 8px;
}
.modal-close:hover { color: var(--ink); }

/* Booking form: explicit padding kept for backwards-compat; the new default
   above also covers it, but harmless to keep. */
#booking-form { padding: 20px 28px 24px; }

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.modal-actions .btn-ghost { margin-right: auto; }

/* Toast */
.toast {
  position: fixed;
  bottom: 24px; left: 50%;
  transform: translateX(-50%);
  background: var(--navy-800);
  color: var(--cream);
  padding: 12px 20px;
  border-radius: var(--radius);
  font-size: 14px;
  box-shadow: var(--shadow-lg);
  /* Highest of the floating elements — sits above modals (2000). */
  z-index: 2500;
  animation: toastIn 0.2s;
}
.toast.error { background: var(--danger); }
@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 10px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ============================================================
   ONBOARDING WIZARD
   ============================================================ */
.onboarding-header {
  background: var(--navy-900);
  color: #fff;
  padding: 14px 24px;
  border-bottom: 3px solid var(--red-500);
}
.onboarding-header .portal-header-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
}
.onboarding-header .header-wordmark { height: 28px; }
.onboarding-header .nav-spacer { flex: 1; }
.onboarding-header .nav-user { color: #fff; display: flex; align-items: center; gap: 14px; font-size: 14px; }
.onboarding-header .btn-link { color: #fff; opacity: 0.85; }
.onboarding-header .btn-link:hover { opacity: 1; }

.onboarding-main {
  /* R146 — let the body's Dolphine-blue gradient bleed through so the
     intake form matches the rest of the portal instead of sitting in a
     standalone sand/beige wash. Captain reported the mismatch on his
     2026-05-31 sign-in test. */
  background: transparent;
  min-height: calc(100vh - 64px);
  min-height: calc(100dvh - 64px);
  padding: 32px 16px 80px;
}
.onboarding-shell {
  max-width: 880px;
  margin: 0 auto;
}
.onboarding-intro {
  margin-bottom: 28px;
}
.onboarding-intro h1 {
  font-family: var(--display);
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.5px;
  color: var(--ink);
  margin: 0 0 12px;
}
.onboarding-intro p {
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.55;
  margin: 0 0 8px;
  max-width: 680px;
}
.onboarding-intro .onboarding-privacy {
  font-size: 13px;
  color: var(--ink-muted);
  font-style: italic;
}

/* Step indicator pills */
.onboarding-steps {
  display: flex;
  gap: 6px;
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  overflow-x: auto;
  flex-wrap: wrap;
}
.onboarding-steps li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  color: var(--ink-muted);
  font-weight: 500;
  transition: all 0.15s;
  flex: 0 0 auto;
}
.onboarding-steps li.active {
  background: var(--navy-900);
  color: #fff;
  border-color: var(--navy-900);
}
.onboarding-steps li.complete {
  background: rgba(22, 101, 52, 0.08);
  color: #166534;
  border-color: rgba(22, 101, 52, 0.3);
}
.onboarding-steps .step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  background: rgba(0,0,0,0.05);
  border-radius: 50%;
  font-weight: 700;
  font-size: 12px;
}
.onboarding-steps li.active .step-num { background: rgba(255,255,255,0.18); }
.onboarding-steps li.complete .step-num { background: #166534; color: #fff; }
.onboarding-steps li.complete .step-num::before { content: '✓'; }
.onboarding-steps li.complete .step-num > * { display: none; }

/* Card holding the wizard form */
.onboarding-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 32px 36px;
  box-shadow: var(--shadow-sm);
}
.onboarding-step legend {
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  color: var(--ink);
  margin-bottom: 18px;
  padding: 0;
  letter-spacing: -0.3px;
}
.onboarding-step .step-hint {
  color: var(--ink-soft);
  font-size: 13px;
  margin: -6px 0 18px;
}
.onboarding-step .form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 14px;
}
.onboarding-step .form-row.form-row-3 {
  grid-template-columns: 1fr 1fr 1fr;
}
.onboarding-step .field {
  display: block;
  margin-bottom: 14px;
}
.onboarding-step .field span {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 6px;
  letter-spacing: 0.2px;
  /* R146 — override the global .field > span uppercase. Onboarding
     uses sentence-case labels so the form reads less like a form
     and more like a brief from the office. */
  text-transform: none;
}
.onboarding-step .field input,
.onboarding-step .field select,
.onboarding-step .field textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 14px;
  font-family: inherit;
  background: #fff;
  color: var(--ink);
}
.onboarding-step .field input:focus,
.onboarding-step .field select:focus,
.onboarding-step .field textarea:focus {
  outline: none;
  border-color: var(--navy-700);
  box-shadow: 0 0 0 3px rgba(76, 115, 133, 0.08);
}
.onboarding-step .field.file-field input[type="file"] {
  padding: 6px;
  background: #fafafa;
}

/* Doc blocks (passport, visa, license, certs) */
.doc-block {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 18px;
  margin-bottom: 16px;
  background: #fafafa;
}
.doc-block h4 {
  font-size: 14px;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--ink);
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.doc-block .optional {
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-muted);
  text-transform: none;
  letter-spacing: 0;
  margin-left: 6px;
}
.doc-block .why {
  font-size: 12px;
  color: var(--ink-muted);
  margin: -4px 0 12px;
  font-style: italic;
}
.doc-block.required-by-rules {
  border-left: 3px solid var(--red-500);
  background: rgba(225, 29, 46, 0.03);
}

/* Final note in step 6 */
/* Bank-details tab switcher (R25d) — Local US vs International. */
.bank-tabs {
  display: flex;
  gap: 4px;
  margin: 14px 0 0;
  padding: 4px;
  background: rgba(40, 69, 88, 0.06);
  border-radius: 999px;
  width: fit-content;
}
.bank-tab {
  background: transparent;
  border: none;
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted, #5d6f82);
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: background 120ms ease, color 120ms ease;
}
.bank-tab.active {
  background: var(--navy-900, #284558);
  color: #fff;
}
.bank-pane { margin-top: 12px; }
.bank-pane.hidden { display: none; }

/* Inline section heading inside My Profile bank fields. */
.profile-field-heading {
  margin: 18px 0 4px;
  padding-bottom: 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-700, #284B73);
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.profile-field-heading:first-child { margin-top: 4px; }

.onboarding-final-note {
  margin-top: 18px;
  padding: 12px 14px;
  background: rgba(22, 101, 52, 0.06);
  border-left: 3px solid #166534;
  border-radius: 4px;
  font-size: 13px;
  color: var(--ink);
}

/* Step nav */
.onboarding-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.onboarding-actions .step-indicator {
  font-size: 13px;
  color: var(--ink-muted);
  font-weight: 500;
}
.onboarding-actions .step-indicator span {
  font-weight: 700;
  color: var(--ink);
}
.btn-sm {
  padding: 6px 12px;
  font-size: 13px;
}

/* Mobile */
@media (max-width: 720px) {
  .onboarding-card { padding: 22px 18px; }
  .onboarding-step .form-row,
  .onboarding-step .form-row.form-row-3 { grid-template-columns: 1fr; gap: 4px; }
  .onboarding-intro h1 { font-size: 24px; }
  .onboarding-steps { gap: 4px; }
  .onboarding-steps li { padding: 6px 10px; font-size: 12px; }
  .onboarding-steps .step-label { display: none; }
  .onboarding-steps li.active .step-label { display: inline; }
}

/* ============================================================
   CREW DIRECTORY + HOD EXPIRY PANEL
   ============================================================ */
/* ============================================================
   WHATSAPP COMMUNITY CARD (Crew Directory top-of-page)
   Brand-matched (#25D366 green accents) but kept inside our existing
   card visual language so it doesn't fight the rest of the directory.
   ============================================================ */
.wa-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-left: 4px solid #25D366;
  border-radius: 12px;
  padding: 18px 22px;
  margin: 0 0 22px;
  box-shadow: var(--shadow-sm);
  /* Two-column grid: card body on the left, QR pinned to the right.
     `align-items: center` vertically centres the QR against the body
     so the card composes cleanly regardless of note length. */
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 22px;
  align-items: center;
}
.wa-card-body { min-width: 0; }   /* lets grid items shrink past content min-width */
.wa-card-empty {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  align-items: center;
}
.wa-card-empty .wa-card-icon { width: 32px; height: 32px; display: grid; place-items: center; }
.wa-card-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  align-items: center;
  margin-bottom: 6px;
}
.wa-card-icon svg { width: 28px !important; height: 28px !important; margin: 0 !important; vertical-align: middle !important; }
.wa-card-h {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.3;
}
.wa-card-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 2px;
}
.wa-card-edit {
  background: none;
  border: 0;
  font: inherit;
  font-size: 12px;
  color: var(--navy-700);
  cursor: pointer;
  padding: 4px 8px;
  text-decoration: underline;
}
.wa-card-edit:hover { color: var(--red-700); }
.wa-card-note {
  background: rgba(37, 211, 102, 0.06);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--ink);
  margin: 4px 0 12px;
  line-height: 1.45;
}
.wa-card-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.wa-join-btn {
  background: #25D366 !important;
  border-color: #25D366 !important;
  color: #fff !important;
  display: inline-flex;
  align-items: center;
}
.wa-join-btn:hover { background: #128C7E !important; border-color: #128C7E !important; }
.wa-join-btn svg { width: 16px !important; height: 16px !important; }
.wa-join-btn svg path { fill: #fff !important; }

.wa-card-qr-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  background: #fafbfc;
  border: 1px dashed var(--navy-100);
  border-radius: 8px;
  /* Sits in the right column of .wa-card via grid — no float, no margin
     hack. The dashed border keeps it visually distinct from the body. */
}
.wa-card-qr {
  width: 132px;
  height: 132px;
  display: block;
  background: #fff;
}
.wa-card-qr-cap {
  font-size: 11px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: center;
  max-width: 132px;
  line-height: 1.3;
}

@media (max-width: 720px) {
  /* Stack body / QR on phones — keeps the QR readable instead of squashing
     the body text down to a sliver. QR centres under the action buttons. */
  .wa-card { grid-template-columns: 1fr; gap: 14px; }
  .wa-card-qr-wrap { justify-self: center; }
  .wa-card-actions { flex-direction: column; align-items: stretch; }
  .wa-join-btn { justify-content: center; }
}


/* --- Crew Invite Code admin card (R41) -------------------------------
   Sits below the WhatsApp card on the Crew Directory page. Captain-only.
   Shares the visual language of .wa-card but tinted with the brand red
   to read as a "sensitive / admin-action" panel rather than a community
   invite. Single-column layout — there's no QR side panel here. */
.invite-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-left: 4px solid var(--red-700, #c41e1e);
  border-radius: 12px;
  padding: 18px 22px;
  margin: 0 0 22px;
  box-shadow: var(--shadow-sm);
}
.invite-card-loading,
.invite-card-err { color: var(--ink-muted); }
.invite-card-head {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: 10px;
}
.invite-card-h {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.3;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.invite-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red-700, #c41e1e);
  background: rgba(196, 30, 30, 0.08);
  border: 1px solid rgba(196, 30, 30, 0.25);
  border-radius: 999px;
  padding: 2px 8px;
}
.invite-card-sub {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 2px;
  line-height: 1.45;
  max-width: 60ch;
}
.invite-card-warn {
  background: rgba(196, 30, 30, 0.06);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--red-700, #c41e1e);
  margin: 8px 0 12px;
  line-height: 1.4;
}
.invite-card-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.invite-code-display {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 14px;
  letter-spacing: 0.04em;
  background: #f6f8fa;
  border: 1px solid var(--navy-100);
  border-radius: 6px;
  padding: 6px 12px;
  color: var(--navy-900);
  min-width: 160px;
  text-align: center;
}
.invite-card-meta {
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.invite-rotate-form {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--navy-100);
}
.invite-form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
  flex-wrap: wrap;
}
.invite-card-foot {
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.45;
  margin: 10px 0 0;
}

@media (max-width: 720px) {
  .invite-card-row { flex-direction: column; align-items: stretch; }
  .invite-code-display { text-align: left; }
  .invite-form-actions { justify-content: stretch; }
  .invite-form-actions .btn { flex: 1; }
}


.crew-list-wrap { margin-top: 24px; }
.crew-list-wrap h2 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 12px;
  letter-spacing: 0.3px;
}
.crew-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 8px;
}
.crew-row .crew-position {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--navy-700, #284B73);
  margin-bottom: 2px;
}
.crew-row .crew-name { font-weight: 600; color: var(--ink); font-size: 15px; }
.crew-row .crew-meta { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.crew-row .crew-meta span:not(:last-child)::after { content: ' · '; color: var(--ink-muted); }
.crew-row .crew-status { display: flex; align-items: center; gap: 6px; }
.crew-pill {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 3px 8px;
  border-radius: 999px;
  text-transform: uppercase;
}
.crew-pill.onboard { background: rgba(22, 101, 52, 0.1); color: #166534; }
.crew-pill.offboard { background: rgba(0,0,0,0.04); color: var(--ink-muted); }
.crew-pill.pending { background: rgba(180, 83, 9, 0.1); color: #92400e; }
.crew-pill.invited { background: rgba(37, 99, 235, 0.12); color: #1d4ed8; }

/* ============================================================
   Password reveal toggle (eye icon) — used on login, register,
   change-password, and reset-password forms. Click toggles the
   paired input.type between 'password' and 'text', handler lives
   in app.js as a document-level [data-password-toggle] listener.
   ============================================================ */
.password-field {
  position: relative;
  display: block;
}
.password-field > input {
  /* Leave room on the right edge so the toggle button doesn't
     overlap the user's typed characters. */
  padding-right: 42px !important;
  width: 100%;
}
.password-toggle {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 38px;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: var(--ink-soft, #6b7280);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 6px 6px 0;
  /* Don't grab focus on tab — tabindex="-1" handles that, this
     keeps it visually unobtrusive. */
  -webkit-tap-highlight-color: transparent;
}
.password-toggle:hover { color: var(--ink, #1a1a1a); }
.password-toggle:focus-visible { outline: 2px solid var(--primary, #0a3a5e); outline-offset: -2px; }
.password-toggle::before {
  content: '';
  display: block;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  /* Default (input.type === 'password'): show "open eye" — meaning
     "click here to reveal". Lucide eye, stroked. */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
}
/* When password is revealed (input.type === 'text'), swap to the
   "eye-off" icon meaning "click to hide again". */
.password-toggle.is-shown::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24'/%3E%3Cline x1='1' y1='1' x2='23' y2='23'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24'/%3E%3Cline x1='1' y1='1' x2='23' y2='23'/%3E%3C/svg%3E");
}

/* R132 — radio-pill row used by the +Add Crew modal sex picker.
   Two side-by-side pill buttons that toggle on click; matches the
   visual weight of the surrounding field controls. */
.radio-row { display: inline-flex; gap: 8px; flex-wrap: wrap; }
.radio-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border, #d1d5db);
  border-radius: 999px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  user-select: none;
  transition: background 0.12s, border-color 0.12s;
}
.radio-pill:hover { background: #f3f4f6; }
.radio-pill input[type="radio"] { accent-color: var(--primary, #284558); margin: 0; }
.radio-pill:has(input[type="radio"]:checked) {
  background: rgba(40, 69, 88, 0.08);
  border-color: var(--primary, #284558);
  font-weight: 600;
}

/* HOD panel */
.hod-panel {
  background: #fff;
  border: 1px solid var(--line);
  border-left: 3px solid var(--red-500);
  border-radius: var(--radius);
  padding: 18px 22px;
  margin-bottom: 28px;
  box-shadow: var(--shadow-sm);
}
.hod-panel-head h2 {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 4px;
  letter-spacing: 0.3px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.hod-badge {
  background: var(--red-500);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
}
.hod-panel-head .page-sub { margin-top: 0; }
#hod-expiry-list { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; }
.expiry-row {
  display: grid;
  grid-template-columns: 200px 1fr auto auto;
  gap: 14px;
  align-items: center;
  padding: 10px 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 13px;
}
.expiry-row .who { font-weight: 600; color: var(--ink); }
.expiry-row .who small { display: block; font-weight: 400; font-size: 11px; color: var(--ink-muted); }
.expiry-row .doc-type { color: var(--ink-soft); }
.expiry-row .expiry-date {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--ink-soft);
}
/* Base status pill rule: nowrap everywhere so "4y 9m 11d left" stays on
   one line regardless of where the pill is rendered. The expiry-row
   override below tightens font-size for the dense expiry table. */
.status-pill {
  display: inline-block;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: 999px;
}
.expiry-row .status-pill {
  font-size: 10px;
  letter-spacing: 0.6px;
  padding: 3px 8px;
}
/* ---------- Expiry-status pills (semantic class names) ----------
   Bands per Fraser 2026-04-28:
     .ok        — over 6 months remaining          (green)
     .warn      — 3 to 6 months remaining          (amber)
     .critical  — under 3 months remaining         (red)
     .expired   — past expiry                      (red, slightly heavier)
     .no-expiry — no expiry date set               (neutral)
   The legacy .s30 / .s90 names are kept as aliases so any cached HTML or
   third-party widget still renders correctly.                              */
.status-pill.expired   { background: rgba(225, 29, 46, 0.18); color: var(--red-700); font-weight: 700; }
.status-pill.critical  { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.status-pill.warn      { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.status-pill.ok        { background: rgba(22, 101, 52, 0.12); color: #166534; }
.status-pill.no-expiry { background: rgba(0,0,0,0.04);        color: var(--ink-muted); }
/* Legacy aliases — keep both old class names mapped so nothing breaks. */
.status-pill.s30 { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.status-pill.s90 { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.expiry-empty { padding: 12px; color: var(--ink-muted); font-style: italic; text-align: center; }

@media (max-width: 720px) {
  .expiry-row { grid-template-columns: 1fr; gap: 4px; }
  .expiry-row .doc-type { font-size: 12px; }
}

/* ============================================================
   SIGN-IN / SIGN-OUT BOARD (iPad kiosk)
   Optimised for a wall-mounted 10–12" tablet at the gangway.
   ============================================================ */
/* R151 (v2.04) — Force navy on the html + body when the kiosk
   view is mounted so iOS Safari's home-indicator strip (and any
   tiny pixel of safe-area below the kiosk-view fixed box) shows
   navy instead of the pale dolphin-blue gradient bleeding through.
   :has() is supported on Safari 15.4+ which is well below the
   gangway iPad's iOS version. */
html:has(#kiosk-view:not(.hidden)),
body:has(#kiosk-view:not(.hidden)) {
  background: var(--navy-900);
}

#kiosk-view {
  position: fixed; inset: 0;
  background: var(--navy-900);
  color: #fff;
  z-index: 100;
  overflow-y: auto;
  /* R128 — clip any rogue horizontal overflow. The header used to push
     the page wider than the viewport on iPad, allowing a horizontal
     scroll that hid the aboard counter / MARSEC / clock off the right
     edge. Belt + braces with the flex-wrap on .kiosk-header below. */
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  /* Respect the iOS status bar + home indicator when launched as a
     standalone PWA (apple-mobile-web-app-capable=yes + viewport-fit=cover). */
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
}
.kiosk-header {
  flex: 0 0 auto;
  background: var(--navy-800);
  border-bottom: 3px solid var(--red-500);
  padding: 14px 20px;
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
  display: flex;
  align-items: center;
  gap: 16px;
  /* R128 — wrap onto a second row on narrow viewports rather than
     pushing the stat/clock/exit beyond the right edge. */
  flex-wrap: wrap;
  row-gap: 8px;
}
.kiosk-header .header-wordmark { height: 30px; }
.kiosk-header .kiosk-brand { flex: 0 0 auto; }
.kiosk-stat { display: flex; flex-direction: column; align-items: flex-start; line-height: 1; margin-left: auto; flex: 0 0 auto; }
.kiosk-stat-num {
  font-family: var(--display);
  font-size: 32px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -1px;
}
.kiosk-stat-label {
  font-size: 11px;
  color: rgba(255,255,255,0.65);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-top: 2px;
}
.kiosk-clock {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 600;
  color: rgba(255,255,255,0.85);
  font-variant-numeric: tabular-nums;
  /* R128 — was 96px, which together with the wide aboard counter and
     MARSEC pill was enough to overflow on a 1024px iPad. The digits are
     tabular so 'min-content' is stable. */
  min-width: 0;
  text-align: right;
  flex: 0 0 auto;
}
.kiosk-exit {
  background: rgba(255,255,255,0.08);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.15);
  width: 44px; height: 44px;
  font-size: 18px;
  border-radius: 8px;
  cursor: pointer;
  font-family: var(--sans);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.kiosk-exit:hover { background: rgba(255,255,255,0.15); }
/* R128 — padlock variant signals "this is gated" rather than the old "×".
   Slightly amber-tinged border so HODs can spot the exit. */
.kiosk-exit-lock {
  background: rgba(251, 191, 36, 0.10);
  border-color: rgba(251, 191, 36, 0.35);
  color: rgba(251, 191, 36, 0.95);
}
.kiosk-exit-lock:hover { background: rgba(251, 191, 36, 0.20); }
/* R129 — size the SVG padlock inside the 44×44 button. */
.kiosk-exit-lock .ic { width: 20px; height: 20px; }

.kiosk-main {
  flex: 1;
  padding: 18px 24px 32px;
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
  max-width: 1280px;
  margin: 0 auto;
  width: 100%;
  /* R128 — guarantee main never widens the page on any device. */
  box-sizing: border-box;
}

.kiosk-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}
.kiosk-tab {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.85);
  border: 1px solid rgba(255,255,255,0.12);
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.4px;
  cursor: pointer;
  font-family: var(--sans);
}
.kiosk-tab.active {
  background: var(--red-500);
  border-color: var(--red-500);
  color: #fff;
}

.kiosk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
}

/* ============================================================
   R51 (2026-05-11) — Today's Harbour Watch banner
   ============================================================ */
.kiosk-watch {
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02));
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 14px;
}
.kiosk-watch-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 10px;
}
.kiosk-watch-eyebrow {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700;
}
.kiosk-watch-date {
  font-size: 12px; color: rgba(255,255,255,0.45); font-weight: 600;
}
/* R134 — sun-times pill in the watch header. Sits to the right of
   the date and shrinks to two stacked pairs on phone widths. */
.kiosk-watch-sun {
  display: inline-flex; gap: 10px; align-items: baseline;
  font-size: 12px; color: rgba(255,255,255,0.70); font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-left: auto; padding-left: 12px;
}
.kiosk-watch-sun .kiosk-sun-pair {
  display: inline-flex; gap: 4px; align-items: baseline;
}
.kiosk-watch-sun .kiosk-sun-icon {
  color: #fcd34d; font-weight: 800;
}
.kiosk-watch-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.kiosk-watch-tile {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.10);
  border-left: 3px solid rgba(255,255,255,0.18);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px;
  min-height: 64px;
}
.kiosk-watch-tile.role-engineer { border-left-color: #6aa3ff; }
.kiosk-watch-tile.role-deck     { border-left-color: #22c55e; }
.kiosk-watch-tile.role-interior { border-left-color: #c084fc; }
.kiosk-watch-tile.is-empty      { opacity: 0.55; border-left-color: rgba(255,255,255,0.18); }
/* R146 — a watchkeeper with approved leave covering today shouldn't
   be on the duty for today. Captain spotted McCorkindale (leave 1 May
   → 10 Jul) assigned as Engineering watchkeeper. Flag the tile in red
   so HOD sees the conflict immediately. */
.kiosk-watch-tile.is-onleave {
  border-left-color: #ef4444 !important;
  background: rgba(239, 68, 68, 0.10);
}
.kiosk-watch-tile.is-onleave .kiosk-watch-role { color: #fca5a5; }

/* R149 (v1.82) — PIN-to-claim hint on the Watchkeeper tile.
   Small purple chip on the WK row tells crew "this is where you
   start the harbour rounds". Echoes the role-interior accent so
   the affordance reads as part of the tile, not a callout. */
.kiosk-watch-cta {
  display: inline-block;
  align-self: flex-start;
  margin-top: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #d8b4fe;
  background: rgba(192, 132, 252, 0.14);
  padding: 2px 8px;
  border-radius: 999px;
}
.kiosk-watch-tile.role-interior:not(.is-empty):not(.is-onleave):hover {
  background: rgba(192, 132, 252, 0.08);
  transform: translateY(-1px);
  transition: transform 0.12s, background 0.12s;
}
.kiosk-watch-tile.role-interior:not(.is-empty):not(.is-onleave):active {
  transform: translateY(0);
  background: rgba(192, 132, 252, 0.14);
}
.kiosk-watch-role {
  font-size: 10px; letter-spacing: 0.10em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700;
}
.kiosk-watch-name {
  font-size: 16px; font-weight: 700; color: #fff; letter-spacing: 0.2px;
}
.kiosk-watch-position {
  font-size: 11px; color: rgba(255,255,255,0.55);
}

/* ============================================================
   R51 — Emergency Contacts panel
   ============================================================ */
.kiosk-emergency {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 16px;
}
.kiosk-emergency-half {
  background: linear-gradient(180deg, rgba(225,29,46,0.10), rgba(225,29,46,0.02));
  border: 1px solid rgba(225,29,46,0.30);
  border-radius: 12px;
  padding: 12px 14px;
}
.kiosk-emergency-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 8px;
}
.kiosk-emergency-eyebrow {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: #fca5a5; font-weight: 700;
}
.kiosk-emergency-sub {
  font-size: 11px; color: rgba(255,255,255,0.50); font-weight: 600;
}
.kiosk-emergency-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 6px;
}
.kiosk-emergency-row {
  display: flex; flex-direction: column; gap: 1px;
  background: rgba(0,0,0,0.18);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 8px 10px;
  text-decoration: none; color: inherit;
}
.kiosk-emergency-row.is-tel:hover {
  border-color: rgba(255,255,255,0.18);
  background: rgba(0,0,0,0.30);
}
.kiosk-emergency-label {
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700;
}
.kiosk-emergency-value {
  font-size: 15px; font-weight: 700; color: #fff; letter-spacing: 0.3px;
  font-variant-numeric: tabular-nums;
}
.kiosk-emergency-value.muted { color: rgba(255,255,255,0.40); font-weight: 500; font-style: italic; font-size: 13px; }
.kiosk-emergency-row .kiosk-emergency-position {
  font-size: 11px; color: rgba(255,255,255,0.55); font-weight: 600;
}

/* Phone: stack the kiosk emergency halves */
@media (max-width: 720px) {
  .kiosk-emergency { grid-template-columns: 1fr; }
  .kiosk-watch-row { grid-template-columns: 1fr; }
}

/* ============================================================
   R151 (v1.84) — Captain's kiosk redesign
   ------------------------------------------------------------
   Layout-only deltas on top of the R51 / R134 base. Reordering
   was done in index.html; this block restyles the four affected
   surfaces (slim muster bar, centered date label, two-line
   emergency phone, denser sign-in cards) plus the new
   collapsible emergency panels.
   ============================================================ */

/* 1. Slim muster bar — drop the height by about half so the bar
      reads as an action strip rather than a hero feature.
      v1.87 — also tightens vertical breathing room above the bar
      so it sits right under the red header line. */
.kiosk-muster-bar--slim { margin: 0 0 12px; gap: 8px; }
.kiosk-muster-bar--slim .kiosk-muster-btn,
.kiosk-muster-bar--slim .kiosk-watch-launch-btn {
  padding: 8px 14px;
  border-radius: 9px;
  gap: 10px;
  min-height: 0;
}
.kiosk-muster-bar--slim .kiosk-muster-glyph { font-size: 16px; }
.kiosk-muster-bar--slim .kiosk-muster-label { font-size: 14px; }
.kiosk-muster-bar--slim .kiosk-muster-sub   { font-size: 10px; }

/* 2. Centered, capitalised, slightly larger date over today's
      watch tiles. Sun-times pair sits to the right; the eyebrow
      label is gone (DOM removed it) — the centered date is
      self-explanatory. */
.kiosk-watch--centered .kiosk-watch-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  margin-bottom: 10px;
}
.kiosk-watch--centered .kiosk-watch-date {
  grid-column: 2;
  justify-self: center;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(255,255,255,0.92);
  text-transform: uppercase;
}
.kiosk-watch--centered .kiosk-watch-sun {
  grid-column: 3;
  justify-self: end;
  margin-left: 0;
  padding-left: 0;
}

/* 3. Collapsible emergency panels — the whole header is a
      tappable button now; chevron rotates when collapsed. The
      grid + sub-label hide so only the eyebrow row remains
      visible. State persists per-device via localStorage. */
.kiosk-emergency-head {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 10px;
  background: transparent;
  border: 0;
  padding: 0;
  margin-bottom: 8px;
  cursor: pointer;
  color: inherit;
  text-align: left;
  font: inherit;
}
.kiosk-emergency-head:hover .kiosk-emergency-chevron {
  color: #fff;
}
.kiosk-emergency-head .kiosk-emergency-sub {
  justify-self: end;
  text-align: right;
}
.kiosk-emergency-chevron {
  font-size: 12px;
  color: rgba(255,255,255,0.55);
  font-weight: 700;
  transition: transform 0.15s ease;
  margin-left: 4px;
}
.kiosk-emergency-half.is-collapsed .kiosk-emergency-chevron {
  transform: rotate(-90deg);
}
.kiosk-emergency-half.is-collapsed .kiosk-emergency-grid {
  display: none;
}
.kiosk-emergency-half.is-collapsed .kiosk-emergency-head {
  margin-bottom: 0;
}

/* 4. Two-line emergency-row treatment for any row that has both
      a label/VHF/agent and a separate phone number. Single-line
      rows (police / fire / ambulance — just "112") keep the
      original side-by-side layout. */
.kiosk-emergency-row.is-stacked {
  flex-direction: column;
  gap: 4px;
}
.kiosk-emergency-row.is-stacked .kiosk-emergency-phone,
.kiosk-emergency-row.is-stacked .kiosk-emergency-name {
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.3px;
  font-variant-numeric: tabular-nums;
}
.kiosk-emergency-row.is-stacked .kiosk-emergency-name {
  font-size: 14px;
}
.kiosk-emergency-row.is-stacked .kiosk-emergency-phone.muted {
  color: rgba(255,255,255,0.40);
  font-weight: 500;
  font-style: italic;
  font-size: 13px;
}
.kiosk-emergency-row.is-single {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.kiosk-emergency-row.is-single .kiosk-emergency-value {
  text-align: right;
}

/* 5. Denser sign-in cards. Name pushed to the top; padding
      tighter; minmax column shrunk so more fit per row on iPad
      portrait + landscape. Tap target stays comfortable. */
.kiosk-grid {
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 8px;
}
.kiosk-card {
  padding: 10px 12px 9px;
  gap: 2px;
  border-radius: 9px;
}
.kiosk-card .kiosk-name {
  font-size: 14px;
  padding-right: 44px;
  line-height: 1.1;
}
.kiosk-card .kiosk-position {
  font-size: 11px;
  padding-right: 44px;
}
.kiosk-card .kiosk-last {
  font-size: 10px;
  margin-top: 3px;
}
.kiosk-card .kiosk-status {
  top: 9px; right: 9px;
  font-size: 9px;
  padding: 2px 6px;
  letter-spacing: 1px;
}

/* ============================================================
   R151 (v1.86) — Captain's spec: SHORTER cards, width unchanged.
   The previous .kiosk-name stacked First / Last on two rows which
   ate one whole line of height per card. Switch to a horizontal
   flex (wraps gracefully if a surname is very long — never
   hyphenated mid-word). Tighten vertical padding + line height
   + the position row so the cards collapse to roughly two rows of
   text plus the status badge, not four.
   ============================================================ */
.kiosk-card {
  padding: 7px 12px 7px;
  gap: 1px;
}
.kiosk-card .kiosk-name {
  /* Was flex-direction: column; — that's what made each card a row
     taller. Row + wrap means first + surname share a line whenever
     they fit, and only flex-wrap onto a second line for very long
     surnames (Worsley-Worswick stays whole, doesn't get hyphenated). */
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  column-gap: 5px;
  row-gap: 0;
  font-size: 13.5px;
  line-height: 1.15;
  padding-right: 40px;
}
.kiosk-card .kiosk-position {
  font-size: 10.5px;
  line-height: 1.2;
  padding-right: 40px;
  margin-top: 1px;
}
.kiosk-card .kiosk-last {
  font-size: 9.5px;
  line-height: 1.2;
  margin-top: 2px;
  color: rgba(255,255,255,0.42);
}
.kiosk-card .kiosk-status {
  top: 6px;
  right: 6px;
  font-size: 8.5px;
  padding: 1px 5px;
  letter-spacing: 0.9px;
  border-radius: 999px;
}

/* ============================================================
   R151 (v1.87) — Captain's spec, second pass:
     • Date pill sits right next to the NETTO II wordmark, at
       roughly the same visual weight.
     • "ABOARD" label moves to the LEFT of the count and reads
       at peer weight to the number.
     • Muster + Watch-Checklist action strip slides UP under
       the header red line (kiosk-main top padding reduced).
   ============================================================ */

/* Date alongside the NETTO II wordmark. Sized to sit at the
   wordmark's visual line (~24px font tracks the ~30px logo
   height once you account for cap-height vs PNG glyph height).
   Uses the display font so the typographic weight matches. */
.kiosk-brand-date {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  color: rgba(255,255,255,0.92);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  line-height: 1;
  padding-left: 14px;
  margin-left: 4px;
  border-left: 2px solid rgba(255,255,255,0.20);
  white-space: nowrap;
  /* Hide on very narrow phones — the wordmark must always read;
     date is supplementary information that the watch panel
     repeats anyway. */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 720px) {
  .kiosk-brand-date {
    font-size: 14px;
    padding-left: 10px;
    margin-left: 2px;
  }
}
@media (max-width: 560px) {
  .kiosk-brand-date { display: none; }
}

/* ABOARD label moves inline with the count. Same display font,
   roughly the same size — captain wants them to read as a unit
   ("ABOARD 16 / 24") rather than label-above-number. */
.kiosk-stat.kiosk-stat--inline {
  flex-direction: row;
  align-items: baseline;
  gap: 10px;
  line-height: 1;
}
.kiosk-stat--inline .kiosk-stat-label {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  color: rgba(255,255,255,0.78);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  margin-top: 0;
  line-height: 1;
}

/* Slide the action strip up under the red line. v1.84 already
   dropped its own top margin to 0; v1.87 also tightens the
   kiosk-main top padding so there's roughly a single ~6px
   breath instead of the previous 18px. */
.kiosk-main {
  padding-top: 8px;
}
.kiosk-card {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 10px;
  padding: 16px 14px;
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
  user-select: none;
}
.kiosk-card:hover { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.18); }
.kiosk-card:active { transform: scale(0.98); }
.kiosk-card.is-onboard { border-left: 4px solid #22c55e; }
/* R146 — Captain's spec: off-vessel crew should read RED (opposite of
   onboard green), not the previous translucent-grey treatment. Same
   visual weight as the green so the eye picks it up immediately. */
.kiosk-card.is-off {
  border-left: 4px solid #ef4444;
  background: rgba(239, 68, 68, 0.06);
}
.kiosk-card.is-off:hover { background: rgba(239, 68, 68, 0.10); }
.kiosk-card .kiosk-name {
  /* R146 — Captain's spec: First / Last on separate lines, surname
     never broken mid-word. ._shortName helper writes two spans:
     .kiosk-name-first + .kiosk-name-last. flex-direction column
     stacks them; nowrap keeps each token whole; if a surname is
     ridiculously long it still won't break — it'll overflow with
     ellipsis (rare enough to be acceptable). */
  display: flex;
  flex-direction: column;
  gap: 0;
  font-weight: 700;
  font-size: 16px;
  color: #fff;
  letter-spacing: 0.2px;
  line-height: 1.15;
  padding-right: 56px;
}
.kiosk-card .kiosk-name-first,
.kiosk-card .kiosk-name-last {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kiosk-card .kiosk-position {
  font-size: 12px;
  color: rgba(255,255,255,0.6);
  padding-right: 56px;
}
.kiosk-card .kiosk-status {
  position: absolute;
  top: 12px; right: 12px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.2px;
  padding: 3px 8px;
  border-radius: 999px;
  text-transform: uppercase;
}
.kiosk-card .kiosk-status.on { background: rgba(34,197,94,0.18); color: #4ade80; }
.kiosk-card .kiosk-status.off { background: rgba(239, 68, 68, 0.20); color: #fca5a5; }
.kiosk-card .kiosk-status.leave { background: rgba(180,83,9,0.25); color: #fbbf24; }
.kiosk-card.is-onleave { opacity: 0.85; border-color: rgba(180,83,9,0.4); }
.kiosk-card .kiosk-last {
  font-size: 11px;
  color: rgba(255,255,255,0.5);
  margin-top: 6px;
  letter-spacing: 0.3px;
}

.kiosk-foot {
  text-align: center;
  font-size: 12px;
  color: rgba(255,255,255,0.4);
  margin-top: 24px;
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* ============================================================
   R114 — EMERGENCY MUSTER  (kiosk sign-in board)
   ------------------------------------------------------------
   Replaces the Crew / Visitors / All / Onboard / Off / On-leave
   chip row. Single big red button that swaps the grid into roll-
   call mode; tiles become tap-to-account targets. Active muster
   shows a sticky banner with the live count + End-muster action.
   ============================================================ */
.kiosk-muster-bar {
  margin: 14px 0 10px;
  display: flex;
  justify-content: stretch;
  /* R134 — gap when the bar is split between Muster + Watch launchers. */
  gap: 10px;
}
.kiosk-muster-btn {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 18px 22px;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(180deg, #dc2626 0%, var(--danger) 100%);
  color: #fff;
  cursor: pointer;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: 0 6px 18px rgba(220, 38, 38, 0.32), inset 0 1px 0 rgba(255,255,255,0.18);
  transition: transform 0.08s, box-shadow 0.2s;
}
.kiosk-muster-btn:hover  { box-shadow: 0 8px 24px rgba(220, 38, 38, 0.45), inset 0 1px 0 rgba(255,255,255,0.22); }
.kiosk-muster-btn:active { transform: scale(0.985); }
.kiosk-muster-glyph { font-size: 22px; }
.kiosk-muster-label { font-size: 18px; }
.kiosk-muster-sub   { margin-left: auto; font-size: 11px; opacity: 0.85; text-transform: none; letter-spacing: 0; }

/* Active muster banner — sticks below the kiosk header while a
   muster is running so the count is always visible. */
.kiosk-muster-active {
  position: sticky;
  top: 0;
  z-index: 50;
  margin: 0 0 10px;
  background: linear-gradient(180deg, #7f1d1d 0%, #991b1b 100%);
  color: #fff;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(127, 29, 29, 0.45);
  animation: kiosk-muster-pulse 1.6s ease-in-out infinite;
}
@keyframes kiosk-muster-pulse {
  0%, 100% { box-shadow: 0 6px 20px rgba(127, 29, 29, 0.45); }
  50%      { box-shadow: 0 6px 28px rgba(220, 38, 38, 0.75); }
}
.kiosk-muster-active-inner {
  display: flex; align-items: center; gap: 18px;
  padding: 12px 16px;
  flex-wrap: wrap;
}
.kiosk-muster-active-title {
  display: flex; align-items: center; gap: 8px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 14px;
}
.kiosk-muster-active-glyph { font-size: 18px; }
.kiosk-muster-active-time  { font-weight: 500; opacity: 0.7; text-transform: none; letter-spacing: 0; font-size: 12px; }
.kiosk-muster-active-count {
  flex: 1;
  font-size: 15px;
  letter-spacing: 0.02em;
}
.kiosk-muster-active-count strong { font-size: 20px; }
.kiosk-muster-unaccounted { margin-left: 6px; color: #fecaca; font-weight: 700; }
.kiosk-muster-allclear    { margin-left: 6px; color: #86efac; font-weight: 700; }
.kiosk-muster-end {
  background: rgba(255,255,255,0.14);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.22);
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
}
.kiosk-muster-end:hover { background: rgba(255,255,255,0.22); }

/* Section heads inside the muster roster (Expected onboard / Ashore).
   Force the head + the inner grid to span the WHOLE row of the parent
   .kiosk-grid so they aren't squeezed into a single column slot. */
.kiosk-muster-section-head {
  grid-column: 1 / -1;
  margin: 14px 4px 8px;
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: rgba(255,255,255,0.78);
}
.kiosk-muster-section-head-ashore { color: rgba(254, 215, 170, 0.85); }
.kiosk-muster-section-count {
  font-family: ui-monospace, Menlo, monospace;
  font-weight: 700;
  color: rgba(255,255,255,0.55);
  font-size: 12px;
}
.kiosk-grid-inner {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}

/* Muster-mode card states. */
.kiosk-card.kiosk-card-muster {
  border-left-width: 4px;
  border-left-style: solid;
  border-left-color: rgba(255,255,255,0.18);
  transition: background 0.15s, border-color 0.15s, transform 0.08s;
}
.kiosk-card.muster-pending   { border-left-color: rgba(252, 165, 165, 0.65); background: rgba(254, 226, 226, 0.04); }
.kiosk-card.muster-pending:hover { background: rgba(254, 226, 226, 0.08); }
.kiosk-card.muster-present   { border-left-color: #22c55e; background: rgba(34, 197, 94, 0.14); }
.kiosk-card.muster-present:hover { background: rgba(34, 197, 94, 0.20); }
/* R114 — muster pills are wider than ON/OFF; give them a touch more
   right-edge breathing room so "✓ PRESENT" doesn't bleed under the
   name on tablet/wider widths. The .kiosk-name padding-right of 56px
   set in R112 already reserves space; the pill just needs a clean
   white-space rule so it doesn't wrap. */
.kiosk-card .kiosk-status.muster-on,
.kiosk-card .kiosk-status.muster-pending {
  white-space: nowrap;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  font-size: 10px;
}
.kiosk-card .kiosk-status.muster-on      { background: rgba(34,197,94,0.30); color: #bbf7d0; }
.kiosk-card .kiosk-status.muster-pending { background: rgba(254,226,226,0.12); color: #fecaca; }
/* The name needs a bit more right padding in muster mode since the
   "✓ Present" pill is wider than the original "ON" / "OFF". */
.kiosk-card.kiosk-card-muster .kiosk-name,
.kiosk-card.kiosk-card-muster .kiosk-position { padding-right: 78px; }

@media (max-width: 720px) {
  .kiosk-muster-btn { padding: 14px 16px; }
  .kiosk-muster-label { font-size: 15px; }
  .kiosk-muster-sub   { display: none; }
  .kiosk-muster-active-count { font-size: 13px; }
}

/* ============================================================
   R112 — KIOSK LOCKDOWN MODE
   ------------------------------------------------------------
   When <html class="kiosk-locked"> (set by the pre-paint script
   in index.html based on localStorage.n2:kioskLocked), strip the
   portal down to just the sign-in board so the gangway iPad
   can't be navigated elsewhere by curious crew.
   • Hides the hamburger menu, nav drawer, header search, notif
     bell, user dropdown, Messages FAB, and Yacht Assistant FAB.
   • Forces the cursor to a kiosk-friendly size.
   • Adds an unobtrusive gear cog bottom-right that opens the
     unlock modal (PIN-gated).
   ============================================================ */
html.kiosk-locked body #hamburger,
html.kiosk-locked body .nav-drawer,
html.kiosk-locked body .nav-drawer-backdrop,
html.kiosk-locked body .header-search,
html.kiosk-locked body .notif-trigger,
html.kiosk-locked body .user-dropdown,
html.kiosk-locked body .messages-fab,
html.kiosk-locked body #messages-fab,
html.kiosk-locked body .assistant-fab,
html.kiosk-locked body .portal-nav,
html.kiosk-locked body #portal-nav,
html.kiosk-locked body #portal-nav.portal-nav--minimal { display: none !important; }
/* Also drop the whole top header on kiosk-locked devices — the
   #portal-nav lives inside it but the surrounding chrome (logo,
   search, etc.) also belongs to the staff-only view. */
html.kiosk-locked body > header { display: none !important; }

/* Tighten the top header so the kiosk feels purpose-built. */
html.kiosk-locked .kiosk-shell { padding-top: 8px; }

/* The gear cog itself — bottom-right corner, subtle until hover.
   8% opacity at rest so it doesn't distract crew tapping their card,
   pops on hover/focus for whoever knows to look for it. */
.kiosk-lock-gear {
  position: fixed;
  bottom: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0.18;
  transition: opacity 0.2s, background 0.2s;
  z-index: 8000;
  color: rgba(255, 255, 255, 0.7);
  font-size: 18px;
  user-select: none;
}
.kiosk-lock-gear:hover,
.kiosk-lock-gear:focus { opacity: 1; background: rgba(255, 255, 255, 0.14); }

/* Unlock modal — modal-card pattern but on the kiosk's dark
   background.  Reuses the existing .pin-card styles via class
   composition. */
.kiosk-unlock-shell {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: flex; align-items: center; justify-content: center;
  z-index: 9000;
  padding: 24px;
}
.kiosk-unlock-card {
  background: #0b1726;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  padding: 24px 22px;
  max-width: 420px;
  width: 100%;
  color: #fff;
}
.kiosk-unlock-card h3 { margin: 0 0 6px; color: #fff; font-size: 17px; }
.kiosk-unlock-card .pin-sub { color: rgba(255,255,255,0.6); font-size: 13px; margin: 0 0 14px; }
.kiosk-unlock-card select,
.kiosk-unlock-card input[type="password"],
.kiosk-unlock-card input[type="text"] {
  width: 100%;
  padding: 10px 12px;
  background: rgba(255,255,255,0.06);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 6px;
  font-size: 16px;
  margin-bottom: 10px;
}
.kiosk-unlock-card .kiosk-unlock-actions {
  display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px;
}
.kiosk-unlock-card .kiosk-unlock-actions .btn-primary {
  background: #2563eb; color: #fff; border: 0; padding: 9px 14px; border-radius: 6px; cursor: pointer; font-weight: 600;
}
.kiosk-unlock-card .kiosk-unlock-actions .btn-secondary {
  background: rgba(255,255,255,0.08); color: #fff; border: 0; padding: 9px 14px; border-radius: 6px; cursor: pointer;
}
.kiosk-unlock-error { color: #fca5a5; font-size: 13px; margin: 6px 0 0; min-height: 1.2em; text-align: center; }

/* R131 — Keypad-style unlock card. Wider than the legacy select/input
   variant so the 3-col keypad has room. */
.kiosk-unlock-card.kiosk-unlock-card--keypad {
  max-width: 380px;
  padding: 22px 22px 24px;
}
.kiosk-unlock-card--keypad h3 { text-align: center; margin: 0 0 4px; font-size: 18px; }
.kiosk-unlock-card--keypad .pin-sub { text-align: center; }

/* Captain / Chief Officer chips above the keypad. Two big tap
   targets so picking the right person is quick. */
.kiosk-unlock-chips {
  display: flex;
  gap: 8px;
  margin: 4px 0 14px;
}
.kiosk-unlock-chip {
  flex: 1 1 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: #fff;
  text-align: left;
  transition: background 0.12s, border-color 0.12s, transform 0.1s;
  font-family: var(--sans);
}
.kiosk-unlock-chip:hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.18); }
.kiosk-unlock-chip:active { transform: scale(0.98); }
.kiosk-unlock-chip.is-selected {
  background: rgba(225, 29, 46, 0.14);
  border-color: var(--red-500);
}
.kiosk-unlock-chip-role {
  font-size: 10px;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 700;
}
.kiosk-unlock-chip.is-selected .kiosk-unlock-chip-role { color: #fff; }
.kiosk-unlock-chip-name {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  letter-spacing: 0.1px;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Kiosk: Visitors mode */
.kiosk-subtabs { margin-top: 6px; opacity: 0.85; }
.kiosk-visitors { color: #fff; padding: 6px 0; }
.kiosk-visitors-actions { display: flex; justify-content: flex-end; margin-bottom: 14px; }
.kiosk-visitors-h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.6);
  margin: 18px 0 8px;
}
.kiosk-visitor-list { display: flex; flex-direction: column; gap: 8px; }
.kiosk-visitor-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto auto;
  gap: 4px 16px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 10px;
  padding: 12px 16px;
  align-items: center;
}
.kiosk-visitor-row.is-out { opacity: 0.55; }
.kiosk-visitor-name { font-size: 15px; color: #fff; }
.kiosk-visitor-meta { font-size: 12px; color: rgba(255,255,255,0.7); grid-column: 1 / -1; }
.kiosk-visitor-notes { font-size: 12px; color: rgba(255,255,255,0.55); font-style: italic; grid-column: 1 / -1; }
.kiosk-visitor-action { grid-row: 1; grid-column: 2; }
.kiosk-visitor-out { font-size: 11px; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.06em; }
.kiosk-visitor-empty { font-size: 13px; color: rgba(255,255,255,0.45); padding: 10px 0; }

/* PIN modal */
.pin-card {
  background: var(--navy-800);
  color: #fff;
  border-radius: 14px;
  padding: 32px 36px;
  max-width: 380px;
  width: calc(100% - 40px);
  box-shadow: 0 20px 60px rgba(0,0,0,0.4);
}
.pin-card h3 {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  margin: 0 0 6px;
  color: #fff;
}
.pin-card .pin-sub {
  font-size: 13px;
  color: rgba(255,255,255,0.6);
  margin: 0 0 20px;
}
.pin-display {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 16px 0 24px;
}
.pin-dot {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,0.4);
  background: transparent;
  transition: all 0.1s;
}
.pin-dot.filled { background: var(--red-500); border-color: var(--red-500); }
.pin-keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.pin-key {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.1);
  color: #fff;
  font-size: 22px;
  font-weight: 600;
  padding: 16px 0;
  border-radius: 8px;
  cursor: pointer;
  font-family: var(--sans);
  transition: all 0.1s;
}
.pin-key:hover { background: rgba(255,255,255,0.12); }
.pin-key:active { transform: scale(0.95); }
.pin-key.del { color: rgba(255,255,255,0.6); font-size: 16px; }
.pin-key.cancel { color: var(--red-500); font-size: 14px; font-weight: 700; }
.pin-error {
  color: #fca5a5;
  font-size: 13px;
  text-align: center;
  min-height: 18px;
  margin-top: 12px;
}

/* Direction prompt (sign in / sign out chooser when not yet decided) */
.pin-direction {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 18px 0 8px;
}
.pin-direction-btn {
  padding: 22px 10px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.15);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  font-family: var(--sans);
  text-align: center;
}
.pin-direction-btn.in { background: rgba(34,197,94,0.16); color: #4ade80; border-color: rgba(34,197,94,0.4); }
.pin-direction-btn.in:hover { background: rgba(34,197,94,0.28); }
.pin-direction-btn.out { background: rgba(225,29,46,0.18); color: #fca5a5; border-color: rgba(225,29,46,0.4); }
.pin-direction-btn.out:hover { background: rgba(225,29,46,0.3); }
.pin-direction-btn .dir-label { display: block; font-size: 18px; margin-bottom: 4px; }
.pin-direction-btn .dir-sub { display: block; font-size: 11px; color: rgba(255,255,255,0.6); font-weight: 500; letter-spacing: 0.3px; }

/* Reason chips */
.pin-reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 6px;
}
.pin-reason-chip {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.85);
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: var(--sans);
}
.pin-reason-chip.selected {
  background: var(--red-500);
  color: #fff;
  border-color: var(--red-500);
}
/* "Going on leave" chip — visually distinct so crew don't tap it by
   accident. This is the only reason that creates a Crew Tracker entry. */
.pin-reason-chip.leave {
  background: rgba(180, 83, 9, 0.25);
  border-color: rgba(245, 158, 11, 0.6);
  color: #fef3c7;
}
.pin-reason-chip.leave:hover { background: rgba(180, 83, 9, 0.4); }

/* Custom-message text input on the reason picker — lets crew leave a
   short note like "Gone for a run, back at 17:00". Tapping a chip
   combines chip-label + this text; "Sign out with this message" submits
   just this text. */
.pin-reason-custom {
  margin-bottom: 6px;
}
.pin-reason-custom input {
  width: 100%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px;
  font-family: var(--sans);
}
.pin-reason-custom input::placeholder { color: rgba(255, 255, 255, 0.45); }
.pin-reason-custom input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.1);
}

/* "Aboard" widget on portal home.
   R85 (2026-05-17) — Lifted out of the column grid into its own
   full-width row. The widget itself is a horizontal bar: count on
   the left, sign-in board CTA in the middle, MARSEC pill on the
   right. The wrapper (.aboard-row) inherits the same max-width as
   .bridge-board so it lines up with the cards below. */
.aboard-row {
  max-width: 1080px;
  margin: 0 auto 16px;
}
.aboard-widget { min-width: 0; }
.aboard-widget {
  background: linear-gradient(135deg, var(--navy-800), var(--navy-700));
  color: #fff;
  /* Harmonised with .bridge-header-pill + .bridge-card so the three
     home-page surfaces share one radius (12px). Previously --radius
     (4px) made the navy bar visibly tighter than the white cards
     above and below it. */
  border-radius: var(--radius-xl, 12px);
  padding: 16px 22px;
  display: flex;
  align-items: center;
  gap: 18px;
  cursor: pointer;
  transition: filter 0.15s;
}
.aboard-widget:hover { filter: brightness(1.08); }
.aboard-widget .aboard-num {
  font-family: var(--display);
  font-size: 38px;
  font-weight: 700;
  letter-spacing: -1px;
  line-height: 1;
}
.aboard-widget .aboard-frac { color: rgba(255,255,255,0.55); font-size: 24px; font-weight: 500; }
.aboard-widget .aboard-text { flex: 1; min-width: 0; font-size: 14px; }
.aboard-widget .aboard-text strong { display: block; font-size: 16px; margin-bottom: 2px; }
.aboard-widget .aboard-chev {
  font-size: 24px;
  opacity: 0.5;
  flex-shrink: 0;
}
.aboard-widget .marsec-slot {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}
/* R130 — flex-wrap so the new watchkeeper row drops underneath
   on narrower viewports without forcing horizontal scroll. */
.aboard-widget { flex-wrap: wrap; row-gap: 12px; }
.aboard-widget .aboard-count { flex: 0 0 auto; }
.aboard-widget .aboard-text  { flex: 1 1 180px; }

/* R130 — When signed-in count > ACTIVE_CREW_CAP, tint the big
   number amber so the eye notices we're over the operating cap.
   The fraction stays muted so the comparison is obvious. */
.aboard-widget.is-over-cap .aboard-num { color: #fbbf24; }

/* R130 — today's watchkeepers, three role tiles inline with the
   widget. Same role colours as the kiosk's Harbour Watch tiles
   (Engineer blue / Deck green / Interior+Galley purple) so the
   two surfaces feel like the same product. */
.aboard-widget .aboard-watch {
  display: flex;
  gap: 8px;
  flex: 1 1 100%;
  min-width: 0;
  order: 5; /* always last visual row inside the widget */
}
.aboard-widget .aboard-watch-tile {
  flex: 1 1 0;
  min-width: 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-left: 3px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.25;
}
.aboard-widget .aboard-watch-tile.role-engineer { border-left-color: #6aa3ff; }
.aboard-widget .aboard-watch-tile.role-deck     { border-left-color: #22c55e; }
.aboard-widget .aboard-watch-tile.role-interior { border-left-color: #c084fc; }
/* R134 — Sun tile sits inline with the role tiles, amber accent.
   Sizes to content so the full "↑ 05:40 · ↓ 21:47" string never
   truncates — the other three role tiles share the remaining
   space equally. */
.aboard-widget .aboard-watch-tile.role-sun {
  border-left-color: #fcd34d;
  flex: 0 0 auto;
}
.aboard-widget .aboard-watch-tile.role-sun .aboard-watch-name {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
}
.aboard-widget .aboard-watch-tile.is-empty      { opacity: 0.55; border-left-color: rgba(255, 255, 255, 0.18); }
.aboard-widget .aboard-watch-role {
  font-size: 10px;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 700;
  /* R130 — reserve 2 lines so "Engineering Officer" (which wraps in
     narrow tiles) doesn't push its name lower than "Deck Officer" /
     "Watchkeeper" (which fit one line). All three names align across
     the row. line-height 1.2 × 2 ≈ 2.4em. */
  min-height: 2.4em;
  line-height: 1.2;
  display: flex;
  align-items: flex-start;
}
.aboard-widget .aboard-watch-name {
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  letter-spacing: 0.1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Wide viewports (≥1024) — let the watch row sit inline next to
   the count/text on the same line. Below that it wraps via the
   default flex-basis 100% above. */
@media (min-width: 1024px) {
  .aboard-widget .aboard-watch {
    flex: 1 1 360px;
    max-width: 480px;
    order: 0;
  }
}

@media (max-width: 640px) {
  .aboard-widget {
    padding: 14px 16px;
    gap: 12px;
  }
  .aboard-widget .aboard-text { font-size: 13px; }
  .aboard-widget .aboard-text strong { font-size: 15px; }
  .aboard-widget .aboard-chev { display: none; }
  /* MARSEC pill wraps onto its own row underneath on phones */
  .aboard-widget .marsec-slot { flex-basis: 100%; }
  /* Watch tiles: stay 3-across but with tighter padding +
     smaller text so all three names fit on a 375px viewport. */
  .aboard-widget .aboard-watch { gap: 6px; }
  .aboard-widget .aboard-watch-tile { padding: 6px 8px; }
  .aboard-widget .aboard-watch-name { font-size: 12px; }
  .aboard-widget .aboard-watch-role { font-size: 9px; }
}

/* Movements log page */
.movements-list { display: flex; flex-direction: column; gap: 6px; }
.movement-row {
  display: grid;
  grid-template-columns: 60px 1fr auto;
  gap: 12px;
  align-items: center;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 13px;
}
.movement-row .arrow { font-size: 18px; line-height: 1; }
.movement-row.in .arrow { color: #166534; }
.movement-row.out .arrow { color: var(--red-500); }
.movement-row .who { font-weight: 600; color: var(--ink); }
.movement-row .when { color: var(--ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.movement-row .reason { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }

@media (max-width: 720px) {
  .kiosk-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
  .kiosk-card { padding: 12px 10px; }
  /* R112 — pill is smaller on mobile (top/right offsets shrink with
     padding above); reserve a tighter 44px so long surnames stay
     whole on narrow screens. */
  .kiosk-card .kiosk-name { font-size: 14px; padding-right: 44px; }
  .kiosk-card .kiosk-position { padding-right: 44px; }
  .kiosk-card .kiosk-status { top: 8px; right: 8px; padding: 2px 6px; font-size: 9px; }
  .pin-card { padding: 22px 20px; }
}

/* ============================================================
   PORTAL NAV — DROPDOWNS
   Desktop: click-to-toggle popover anchored to the trigger.
   Mobile (hamburger open): dropdowns expand inline as nested links.
   ============================================================ */
/* Only desktop needs the relative wrapper for absolute-positioned
   submenus. On mobile the drawer is `position: fixed` (R25) and a
   stray `position: relative` here would override the drawer width
   because of cascade order — found 2026-04-30 when Fraser opened
   the drawer on iOS and saw a thin navy strip. */
@media (min-width: 901px) {
  .portal-nav { position: relative; }
}
/* Higher specificity on the nav items so the broader .portal-nav a rules
   defined earlier in the file (line ~333) don't override these — both selectors
   use one class on a portal-nav child so order matters; keeping these last. */
.portal-nav .nav-item,
.portal-nav .nav-trigger,
.portal-nav button.nav-trigger {
  background: none !important;
  border: none;
  color: var(--cream) !important;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  /* R142 — bumped tracking from 0.08em → 0.12em to match the cert-plate
     typographic system on page H1s. R129 — padding 10/14 keeps the iPad
     tap area at ~36px tall. */
  letter-spacing: var(--track-wider);
  padding: 10px 14px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex !important;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  border-radius: 4px;
  transition: background 0.16s var(--ease-precise), color 0.16s var(--ease-precise);
  appearance: none;
  -webkit-appearance: none;
  outline: none;
}
.portal-nav .nav-item:hover,
.portal-nav .nav-trigger:hover {
  background: rgba(255,255,255,0.06);
  color: var(--cream);
}
.portal-nav .nav-item.active {
  /* R142 — match the simpler active treatment used on plain nav links;
     red wash retired in favour of underline + subtle white wash. */
  background: rgba(255, 255, 255, 0.04);
  color: var(--cream);
}
.portal-nav .nav-trigger .caret {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  opacity: 0.7;
  transition: transform 0.18s var(--ease-precise);
}
.portal-nav .nav-trigger .caret .ic { width: 12px; height: 12px; }
.nav-dropdown.open .nav-trigger .caret { transform: rotate(180deg); opacity: 1; }
.nav-dropdown.open .nav-trigger { background: rgba(255,255,255,0.06); }

.nav-dropdown { position: relative; }
.nav-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 220px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow-md);
  padding: 6px;
  z-index: 100;
  display: none;
}
.nav-dropdown.open .nav-menu { display: block; }
.nav-menu a {
  display: block;
  padding: 10px 14px;
  font-size: 14px;
  color: var(--ink);
  border-radius: 4px;
  text-decoration: none;
  white-space: nowrap;
}
.nav-menu a:hover {
  background: var(--cream);
  color: var(--navy-800);
}
.nav-menu a.active {
  background: rgba(225,29,46,0.08);
  color: var(--navy-800);
  font-weight: 600;
}

/* Mobile hamburger: drop popover styling, render menus inline */
@media (max-width: 900px) {
  .nav-menu {
    position: static;
    box-shadow: none;
    border: none;
    background: transparent;
    padding-left: 16px;
    display: none;
    min-width: 0;
  }
  .nav-dropdown.open .nav-menu { display: block; }
  .nav-menu a {
    color: var(--cream);
    padding: 10px 8px;
    font-size: 14px;
    /* Override the desktop `white-space: nowrap` which otherwise wins via
       cascade order (the desktop rule is later in the source than the first
       mobile-block override). Without this, long menu items overflow off
       the right edge on phones. */
    white-space: normal;
    word-break: break-word;
  }
  .nav-menu a:hover {
    background: rgba(255,255,255,0.06);
    color: var(--cream);
  }
  .nav-menu a.active {
    background: rgba(225,29,46,0.18);
    color: #fff;
  }
  .portal-nav .nav-trigger { width: 100%; justify-content: flex-start; padding: 12px 8px; }
}

/* ============================================================
   BRIDGE — captain's daily start view (R23)
   ============================================================
   Layout: greeting header → vessel HUD (readouts + chart) →
   two-up Today / Awaiting cards → existing widgets demoted.
   The visual language is tighter and more chart-like than the
   rest of the portal: navy gradients, fixed-width readouts, a
   dashed accent on the HUD frame. Reads like an instrument
   panel without veering into "dashboard with neon" territory.
   ============================================================ */
.bridge-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  /* R44 (2026-05-10) — keep the greeting + charter pill within the
     same 1080px column the cards below use, so the dashboard reads
     as one coherent stack rather than full-bleed text above
     constrained grids. */
  max-width: 1080px;
  margin: 6px auto 18px;
  flex-wrap: wrap;
}
.bridge-greeting {
  font-family: var(--display, serif);
  font-size: 28px;
  font-weight: 700;
  color: var(--navy-900, #284558);
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}
.bridge-subline {
  margin: 0;
  font-size: 14px;
  color: var(--ink-muted, #5d6f82);
}
.bridge-header-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 16px;
  background: var(--navy-900, #284558);
  color: #fff;
  /* Harmonised with .aboard-widget + .bridge-card so the three
     home-page surfaces share one radius (12px = var(--radius-xl)). */
  border-radius: var(--radius-xl, 12px);
  box-shadow: 0 6px 18px rgba(40, 69, 88, 0.25);
}
.bridge-header-pill.is-charter {
  background: linear-gradient(135deg, #8a6a1c, #b3892b);
}
.bridge-pill-eyebrow {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.75;
}
.bridge-pill-name { font-weight: 700; font-size: 14px; }
.bridge-pill-day { font-size: 12px; opacity: 0.85; }

/* ============================================================
   R84 (2026-05-17) — MARSEC level pill.
   Shown in two places:
     • The full-width Crew aboard bar on the home page (light-on-
       dark, so the pill is white with a coloured band).
     • The kiosk header (same treatment).
   Three colour states: 1 green (Normal), 2 amber (Heightened),
   3 red (Exceptional). The .can-edit modifier adds a pencil
   affordance on hover for the Captain / Chief Officer / admin
   trio.
   ============================================================ */
/* The pill itself takes the level colour (matching the USCG MARSEC
   signs — yellow/orange/red), with a darker inset disc for the
   level number. Eyebrow + label sit alongside in the sign's text
   colour (black on yellow/orange, white on red). */
.marsec-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 6px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
  line-height: 1;
  user-select: none;
  transition: filter 120ms ease, transform 120ms ease;
}
.marsec-pill-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  font-family: var(--display, serif);
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
  background: rgba(0, 0, 0, 0.18);
  color: inherit;
}
.marsec-pill-eyebrow {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  display: block;
  line-height: 1.1;
  margin-bottom: 1px;
  opacity: 0.75;
}
.marsec-pill-label {
  font-size: 12px;
  display: block;
  line-height: 1.1;
  font-weight: 700;
}
.marsec-pill-body { display: inline-flex; flex-direction: column; }
.marsec-pill-edit {
  opacity: 0;
  font-size: 11px;
  margin-left: 4px;
  transition: opacity 120ms ease;
}
.marsec-pill.can-edit { cursor: pointer; }
.marsec-pill.can-edit:hover { filter: brightness(0.96); transform: translateY(-1px); }
.marsec-pill.can-edit:hover .marsec-pill-edit { opacity: 0.7; }
/* Level palettes — matched to the official USCG MARSEC sign colours.
   MARSEC 1 yellow + MARSEC 2 orange use dark text (per the signs);
   MARSEC 3 red uses white text so the level reads loudly. */
.marsec-pill.is-1 {
  background: #FACC15;            /* sign yellow */
  color: #1a1a1a;
  border-color: rgba(0, 0, 0, 0.10);
}
.marsec-pill.is-1 .marsec-pill-badge { background: rgba(0, 0, 0, 0.14); color: #1a1a1a; }
.marsec-pill.is-2 {
  background: #F08C2E;            /* sign orange */
  color: #1a1a1a;
  border-color: rgba(0, 0, 0, 0.12);
}
.marsec-pill.is-2 .marsec-pill-badge { background: rgba(0, 0, 0, 0.18); color: #1a1a1a; }
.marsec-pill.is-3 {
  background: #DC2626;            /* sign red */
  color: #fff;
  border-color: rgba(0, 0, 0, 0.15);
}
.marsec-pill.is-3 .marsec-pill-badge { background: rgba(0, 0, 0, 0.28); color: #fff; }

/* Kiosk slot — pill keeps the same colour treatment on the dark
   header; the strong solid background reads cleanly against navy. */
.kiosk-header .marsec-slot { display: inline-flex; align-items: center; }
@media (max-width: 720px) {
  .kiosk-header .marsec-pill-eyebrow { display: none; }
  .kiosk-header .marsec-pill { padding: 4px 10px 4px 4px; }
  .kiosk-header .marsec-pill-badge { width: 22px; height: 22px; font-size: 12px; }
}

/* ============================================================
   R151 (v1.89 → v1.90) — Square MARSEC pill, site-wide.
   v1.89 scoped it to .kiosk-header only; v1.90 drops the scope
   so the home-page aboard widget gets the same corner language.
   ============================================================ */
.marsec-pill {
  border-radius: 9px;
  padding: 5px 11px 5px 5px;
  gap: 8px;
}
.marsec-pill-badge {
  border-radius: 6px;
  width: 24px;
  height: 24px;
  font-size: 13px;
}
/* Pull the kiosk slot's baseline down a hair so the bottom of
   the pill aligns with the bottom of the ABOARD 16 / 24 numbers
   it sits next to (the v1.87 inline aboard stat uses baseline
   alignment via flex; this nudges the pill onto the same line). */
.kiosk-header .marsec-slot {
  align-self: baseline;
}

/* ============================================================
   R151 (v1.90) — Captain's spec pass 4:
     • Header text all at one size, all dimmed to match ABOARD
       (the 16 / 24 was full-white #fff next to a 78% opacity
       label and read brighter).
     • Wordmark, brand-date, ABOARD, 16/24, clock all visually
       aligned to the MARSEC pill's height.
     • Crew cards squeezed further — name + position kept,
       last-seen now sits on the same row as position so we
       lose a whole text line per card.
   ============================================================ */

/* Header text harmonisation. Everything sized to roughly match
   the MARSEC pill height; v1.91 — Captain wants brightness up
   to the NETTO II logo's intensity, NOT down. Everything goes
   full white. */
.kiosk-header .header-wordmark { height: 26px; }
.kiosk-brand-date {
  font-size: 18px;
  padding-left: 12px;
  color: #fff;
}
.kiosk-stat--inline .kiosk-stat-label {
  font-size: 18px;
  color: #fff;
}
.kiosk-stat--inline .kiosk-stat-num {
  font-size: 22px;
  color: #fff;
  letter-spacing: -0.5px;
}
.kiosk-clock {
  font-size: 20px;
  color: #fff;
}
.kiosk-exit-lock {
  width: 34px;
  height: 34px;
  border-radius: 9px;                     /* matches the new MARSEC corner */
}
.kiosk-exit-lock .ic { width: 16px; height: 16px; }

/* v1.91 — bottom-align everything in the header so the foot of
   the MARSEC pill, the foot of ABOARD 16 / 24, and the foot of
   the clock all sit on one line. Baseline alignment in v1.90
   left descender-less labels floating; flex-end pulls them down
   to the pill's outer bottom. The slot's earlier align-self
   override is no longer needed; remove it so the pill sits at
   the same floor as the digits. */
.kiosk-header { align-items: flex-end; }
.kiosk-header .marsec-slot { align-self: flex-end; }
.kiosk-header .kiosk-brand,
.kiosk-header .kiosk-exit-lock {
  /* Wordmark + lock button float a touch higher than the text
     baseline — they're visual chrome rather than text content,
     and bottom-aligning the lock with the digit baseline puts it
     slightly off centre against the header bar. Keep these two
     centred. */
  align-self: center;
}

/* Squeeze the crew cards one more rung. v1.86 dropped them from
   four text rows to three (name on one line). v1.90 compresses
   the remaining rows: tighter padding, smaller fonts, near-1
   line-height. Last-seen sits as a faint caption so it consumes
   the smallest possible vertical space without disappearing.
   Width unchanged (158px floor from v1.84) per Captain. */
.kiosk-card {
  padding: 5px 11px 5px;
  gap: 0;
  border-radius: 8px;
}
.kiosk-card .kiosk-name {
  font-size: 13px;
  line-height: 1.05;
  padding-right: 38px;
  margin: 0;
}
.kiosk-card .kiosk-position {
  font-size: 10px;
  line-height: 1.1;
  padding-right: 38px;
  margin-top: 1px;
}
.kiosk-card .kiosk-last {
  font-size: 9px;
  line-height: 1.1;
  margin-top: 1px;
  color: rgba(255,255,255,0.38);
}
.kiosk-card .kiosk-status {
  top: 4px;
  right: 5px;
  font-size: 8px;
  padding: 1px 5px;
  letter-spacing: 0.8px;
}

/* ============================================================
   R151 (v1.92) — Strip the header to four items so it can
   actually align cleanly:
     • NETTO II wordmark
     • ABOARD 16 / 24
     • 19:41 clock
     • 🔒 lock button
   Date + MARSEC moved DOWN into the watch panel header. The
   PNG wordmark has invisible padding below the visible text,
   so we nudge it back up with vertical-align: bottom and a
   tuned line-box height so the visible "NETTO II" bottom
   actually sits at the header's flex-end line.
   ============================================================ */
.kiosk-header .header-wordmark {
  display: block;
  height: 26px;
  /* The PNG's transparent box extends ~3px below the visible
     "NETTO II" baseline. Negative margin pulls the element's
     bounding bottom up to where the visible text actually ends,
     so flex-end alignment matches what the eye expects. */
  margin-bottom: -3px;
}
/* Now align-items: flex-end (set in v1.91) will land everything
   — including the wordmark's visible bottom — on one line. */
.kiosk-header .kiosk-brand,
.kiosk-header .kiosk-exit-lock {
  align-self: flex-end;
}

/* Watch panel header becomes a three-column row: MARSEC slot
   on the LEFT, centered uppercase date in the MIDDLE, sun
   times on the RIGHT. The .kiosk-watch--centered grid from
   v1.84 was 1fr / auto / 1fr — keep that, the MARSEC slot
   naturally takes the left column. */
.kiosk-watch--centered .kiosk-watch-head .marsec-slot {
  grid-column: 1;
  justify-self: start;
}
/* MARSEC inside the watch panel can shed the kiosk-header
   baseline override from earlier — flex-grid handles it. */
.kiosk-watch--centered .kiosk-watch-head .marsec-slot { align-self: center; }

/* Sun emoji glyphs are wider than the previous arrows; nudge
   font-size up so they read as icons rather than dingbats and
   give them a little breathing room from the time digits. */
.kiosk-watch-sun .kiosk-sun-icon {
  font-size: 16px;
  /* Override the v1.84 yellow color — emoji glyphs render with
     their own native palette; the gold tint was for the arrow
     character. */
  color: inherit;
  font-weight: normal;
  /* Tighten optical line-height so the emoji sits on the same
     baseline as the time digits. */
  line-height: 1;
  margin-right: 2px;
}
.kiosk-watch-sun .kiosk-sun-pair {
  align-items: center;
  gap: 5px;
}

/* ============================================================
   R151 (v1.93 → v1.96) — Captain's iterative header geometry:
     • Clock + lock pinned to the FAR RIGHT.
     • ABOARD pill floats at the BOTTOM-LEFT of the viewport
       this time, sized to a crew-card's height (~40 px).
   ============================================================ */
.kiosk-header .kiosk-clock {
  font-size: 30px;
  line-height: 1;
  /* Pushes clock + lock to the far right of the flex row. */
  margin-left: auto;
  align-self: center;
}

/* ============================================================
   R151 (v1.99) — Captain's spec: ABOARD pinned bottom-LEFT,
   MARSEC pinned bottom-RIGHT. Both at crew-card dimensions but
   FIXED outside the grid flow, so the crew cards reflow under
   them without the chips moving. Same corner / border /
   background language as a crew card so they read as siblings.
   ============================================================ */
.kiosk-fixed-card {
  position: fixed;
  z-index: 6;
  bottom: 16px;
  /* Match the crew-grid minmax floor — same width as a crew card
     on the iPad's typical 158-180 px column. */
  width: 158px;
  height: 48px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.kiosk-fixed-card--aboard { left: 16px; flex-direction: column; gap: 1px; pointer-events: none; }
.kiosk-fixed-card--marsec { right: 16px; background: transparent; border: 0; box-shadow: none; padding: 0; backdrop-filter: none; -webkit-backdrop-filter: none; }

/* ABOARD chip — number + label fill the card centred. */
.kiosk-fixed-card-num {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.5px;
  line-height: 1;
}
.kiosk-fixed-card-label {
  font-family: var(--display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.78);
  line-height: 1.1;
  margin-top: 2px;
}

/* MARSEC chip — wraps Marsec.renderPill output. The pill's own
   coloured background (yellow / orange / red) fills the cell.
   v2.01 — Captain spec: badge + text centred inside the cell
   (was left-aligned because the base .marsec-pill is an inline
   flex without justify-content). */
.kiosk-fixed-card--marsec .marsec-pill {
  width: 100%;
  height: 100%;
  padding: 6px 10px;
  gap: 10px;
  border-radius: 8px;
  border-width: 1px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
  align-self: stretch;
  justify-content: center;
}
.kiosk-fixed-card--marsec .marsec-pill-badge {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  font-size: 15px;
}
.kiosk-fixed-card--marsec .marsec-pill-eyebrow { font-size: 10px; }
.kiosk-fixed-card--marsec .marsec-pill-label   { font-size: 13px; }

/* v2.03 — Crew grid no longer needs the previous 72 px buffer
   because the footer + cog (next rules) sit in normal flow
   directly after the grid rather than at the viewport floor.
   The ABOARD / MARSEC chips are still fixed at the bottom
   corners; the footer text + cog tuck above them in the
   natural document order. */
.kiosk-grid {
  padding-bottom: 0;
}

/* Hide the fixed chips while an active emergency muster is
   running — the muster banner takes priority on the lower edge. */
.kiosk-view.kiosk-muster-active .kiosk-fixed-card {
  display: none;
}

/* ============================================================
   v2.03 — Cog + "Tap your card …" footer text both move OUT of
   the viewport floor and flow naturally just below the last
   row of crew cards. Cog sits centred immediately under the
   footer text via flex.
   ============================================================ */
.kiosk-foot {
  margin-top: 12px;
  margin-bottom: 4px;
  text-align: center;
}
.kiosk-lock-gear {
  /* Was position: fixed bottom: 14 px. Now flows after the
     footer text. Margin centres horizontally. */
  position: static;
  display: block;
  margin: 6px auto 16px;
  transform: none;
  left: auto;
  right: auto;
  bottom: auto;
}

/* ============================================================
   R151 (v1.94) — Home-page MARSEC pill sized to the sun tile.
   The home page aboard widget renders a row of small tiles
   (Engineer / Deck / Watchkeeper / Sun) at ~50px height; the
   MARSEC pill was sitting next to them at ~34px and reading as
   visually undersized. Captain wants the pill height-matched to
   the sun tile, OK if slightly wider.
   ============================================================ */
.aboard-widget .marsec-pill {
  padding: 12px 16px 12px 12px;
  gap: 11px;
  border-radius: 10px;
}
.aboard-widget .marsec-pill-badge {
  width: 34px;
  height: 34px;
  font-size: 18px;
  border-radius: 8px;
}
.aboard-widget .marsec-pill-eyebrow {
  font-size: 11px;
  letter-spacing: 0.14em;
}
.aboard-widget .marsec-pill-label {
  font-size: 14px;
  margin-top: 1px;
}

/* ============================================================
   MARSEC change modal (R84).
   ============================================================ */
.marsec-modal-card { max-width: 460px; width: calc(100% - 32px); }
.marsec-modal-body { padding: 8px 20px 18px; }
.marsec-modal-current {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--ink-muted, #5d6f82);
}
.marsec-modal-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}
.marsec-opt {
  display: grid;
  grid-template-columns: 44px 1fr;
  grid-template-rows: auto auto;
  gap: 2px 14px;
  align-items: center;
  padding: 14px 16px;
  border-radius: 10px;
  border: 2px solid var(--line, #e5e7eb);
  background: #fff;
  text-align: left;
  cursor: pointer;
  font: inherit;
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.marsec-opt:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.marsec-opt-num {
  grid-row: 1 / span 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  font-family: var(--display, serif);
  font-size: 22px;
  font-weight: 700;
  color: #fff;
}
.marsec-opt-label {
  font-weight: 700;
  font-size: 15px;
  color: var(--navy-900, #284558);
  align-self: end;
}
.marsec-opt-sub {
  font-size: 12px;
  color: var(--ink-muted, #5d6f82);
  align-self: start;
}
/* Modal option borders + badge discs match the USCG sign palette
   so the three big buttons read as the same colours as the pill. */
.marsec-opt.marsec-1 { border-color: rgba(250, 204, 21, 0.45); }
.marsec-opt.marsec-1 .marsec-opt-num { background: #FACC15; color: #1a1a1a; }
.marsec-opt.marsec-1:hover { border-color: #FACC15; }
.marsec-opt.marsec-2 { border-color: rgba(240, 140, 46, 0.45); }
.marsec-opt.marsec-2 .marsec-opt-num { background: #F08C2E; color: #1a1a1a; }
.marsec-opt.marsec-2:hover { border-color: #F08C2E; }
.marsec-opt.marsec-3 { border-color: rgba(220, 38, 38, 0.40); }
.marsec-opt.marsec-3 .marsec-opt-num { background: #DC2626; color: #fff; }
.marsec-opt.marsec-3:hover { border-color: #DC2626; }
.marsec-opt.is-current { box-shadow: inset 0 0 0 2px rgba(40, 69, 88, 0.12); }
.marsec-modal-reason {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; color: var(--ink-muted, #5d6f82);
}
.marsec-modal-reason input {
  font: inherit;
  font-size: 13px;
  padding: 8px 10px;
  border: 1px solid var(--line, #e5e7eb);
  border-radius: 8px;
  background: #fff;
  color: var(--ink, #284558);
}
.marsec-modal-err {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--red-500, #c0392b);
  min-height: 14px;
}

/* Vessel HUD — readouts strip + chart frame */
.vessel-hud {
  background: linear-gradient(160deg, #284558 0%, #1F3845 60%, #284558 100%);
  border-radius: 14px;
  padding: 18px;
  /* Keep the HUD aligned with the cards above so the dashboard
     reads as one column down the page (R44, 2026-05-10). */
  max-width: 1080px;
  margin: 0 auto 20px;
  box-shadow: 0 12px 30px rgba(40, 69, 88, 0.18);
  position: relative;
  overflow: hidden;
}
.vessel-hud::before {
  content: '';
  position: absolute; inset: 8px;
  border: 1px dashed rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  pointer-events: none;
}
.vessel-hud-readouts {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 14px;
  position: relative;
  z-index: 1;
}
.hud-readout {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
/* Sun cell stacks two times vertically inside a single grid column so
   all seven readouts fit on one row at desktop width (R23.2). */
.hud-readout.sun .hud-readout-value {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.hud-sun-line { white-space: nowrap; line-height: 1.15; }
.hud-readout-label {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.hud-readout-value {
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
  font-size: 19px;
  font-weight: 600;
  color: #fff;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hud-readout-unit {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 1px;
}
.vessel-hud-chart {
  background: #fff;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  z-index: 1;
}
.vessel-hud-chart-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.vessel-hud-chart-head h2 {
  font-family: var(--display, serif);
  font-size: 16px;
  font-weight: 700;
  margin: 0 0 2px;
  color: var(--navy-900);
  letter-spacing: 0.01em;
}
.vessel-hud-chart-head p {
  margin: 0;
  font-size: 12px;
  color: var(--ink-muted);
}
.vessel-hud-chart-actions {
  display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap;
}
.vessel-hud-chart-foot {
  display: flex; gap: 8px;
  padding: 8px 14px;
  border-top: 1px solid var(--line);
  background: rgba(40, 69, 88, 0.02);
}

/* R56 (2026-05-12) — vessel tracker tabs (above the map). Lets the
   user swap which boat the VesselFinder embed is following. */
.vessel-trackers-tabs {
  display: flex;
  gap: 6px;
  padding: 8px 14px 0;
  flex-wrap: wrap;
  background: #fff;
}
.vessel-tracker-tab {
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-700);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  letter-spacing: 0.01em;
}
.vessel-tracker-tab:hover { border-color: var(--navy-700); color: var(--navy-900); }
.vessel-tracker-tab.is-active {
  background: var(--navy-900, #284558);
  border-color: var(--navy-900, #284558);
  color: #fff;
}
.vessel-tracker-tab.is-disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.vessel-tracker-tab-pending {
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.7;
}
/* R56 (2026-05-12) — ad-hoc vessel search after the tab pills. */
.vessel-tracker-search {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.vessel-tracker-search-input {
  font: inherit;
  font-size: 12px;
  padding: 5px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  background: #fff;
  color: var(--navy-900);
  width: 110px;
  outline: none;
  transition: border-color 0.12s, width 0.15s;
}
.vessel-tracker-search-input:focus {
  border-color: var(--navy-700);
  width: 150px;
}
.vessel-tracker-search-btn {
  /* inherits .vessel-tracker-tab base styles */
  font-size: 12px;
  padding: 5px 12px;
}
.vessel-tracker-search-help {
  font-size: 11px;
  font-weight: 500;
  color: var(--navy-700);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: 999px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.vessel-tracker-search-help:hover {
  color: var(--navy-900);
  background: rgba(40, 69, 88, 0.05);
}
@media (max-width: 640px) {
  /* On phones, the search becomes its own row below the tabs. */
  .vessel-trackers-tabs { gap: 6px; }
  .vessel-tracker-search {
    margin-left: 0;
    width: 100%;
    margin-top: 4px;
  }
  .vessel-tracker-search-input {
    flex: 1;
    width: auto;
  }
}
.vessel-hud-chart .btn-ghost { background: transparent; color: var(--navy-700, #284B73); }

/* R85 (2026-05-17) — Restructured: aboard widget now lives in
   its own full-width row above the board, and YOUR TASKS sits in
   its own full-width row below. The board is now a single-column
   stack: TODAY full-width on top, AWAITING YOU full-width below.
   The legacy .bridge-column flex stack is preserved below in case
   any other view still references it. */
.bridge-board {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  max-width: 1080px;
  margin: 0 auto 16px;
}
.bridge-column {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
/* YOUR TASKS as a full-width row matching the board's max-width. */
.home-todos-row {
  max-width: 1080px;
  margin: 0 auto 20px;
}
@media (max-width: 880px) {
  .bridge-board { grid-template-columns: 1fr; }
  .vessel-hud-readouts { grid-template-columns: repeat(3, 1fr); }
  .bridge-greeting { font-size: 22px; }
}

/* Legacy aliases — keep .bridge-grid / .bridge-secondary working in
   case any other view or cached page still references them. */
.bridge-grid,
.bridge-secondary {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 16px;
  align-items: start;
  max-width: 1080px;
  margin: 0 auto 20px;
}
@media (max-width: 880px) {
  .bridge-grid,
  .bridge-secondary { grid-template-columns: 1fr; }
}
.bridge-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px;
  box-shadow: 0 2px 8px rgba(40, 69, 88, 0.04);
  /* R44 (2026-05-10) — CRITICAL: grid items default to min-width:auto
     which equals min-content. A long task title (like a Netlify token
     name with no spaces) makes the column expand past its allocated
     fr share, overflowing the grid's max-width and pushing the card
     off-screen. min-width:0 lets the column collapse to the fr ratio,
     and overflow:hidden enforces the bounds visually. The
     .bridge-row-title inside already has white-space:nowrap +
     ellipsis, which now actually fires because its grid ancestor
     finally allows shrinking. */
  min-width: 0;
  overflow: hidden;
}
.bridge-list { min-width: 0; }
.bridge-row { min-width: 0; }
.bridge-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.bridge-card-head h2 {
  font-family: var(--display, serif);
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--navy-900);
  margin: 0;
}
.bridge-card-meta {
  font-size: 11px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.bridge-list {
  display: flex; flex-direction: column; gap: 8px;
}
.bridge-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: rgba(40, 69, 88, 0.025);
  border-radius: 8px;
  text-decoration: none;
  color: var(--ink);
  transition: background 120ms ease, transform 120ms ease;
}
.bridge-row:hover { background: rgba(40, 69, 88, 0.06); transform: translateX(2px); }
.bridge-row-time {
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-700, #284B73);
  min-width: 44px;
  letter-spacing: 0.02em;
}
.bridge-row-icon {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--navy-50, #EBF1F7);
  color: var(--navy-900);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
}
.bridge-row-icon.cruise { background: rgba(159, 18, 32, 0.10); color: #9F1220; }
.bridge-row-icon.drill  { background: rgba(220, 130, 0, 0.12); color: #b86a00; }
.bridge-row-icon.todo   { background: rgba(40, 69, 88, 0.10); color: #284558; }
.bridge-row-icon.maintenance { background: rgba(120, 80, 30, 0.10); color: #78501e; }
.bridge-row-icon.leave  { background: rgba(20, 120, 90, 0.10); color: #14785a; }
.bridge-row-icon.finance{ background: rgba(40, 69, 88, 0.10); color: #284558; }
.bridge-row-icon.expiry { background: rgba(220, 130, 0, 0.12); color: #b86a00; }
.bridge-row-body {
  display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0;
}
.bridge-row-title {
  font-size: 13.5px; font-weight: 600;
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bridge-row-detail {
  font-size: 12px;
  color: var(--ink-muted);
}
.bridge-row-cta {
  font-size: 11px;
  color: var(--navy-700);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.bridge-empty {
  padding: 22px 14px;
  text-align: center;
  font-size: 13px;
  color: var(--ink-muted);
  font-style: italic;
}
/* (R56 2026-05-12) .bridge-secondary moved into the .bridge-board
   alias block at the top of this section — kept as legacy alias
   only. Removed the old standalone definition here. */

/* ============================================================
   VESSEL TRACKER (home page map)
   ============================================================ */
.vessel-tracker {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 24px;
  box-shadow: var(--shadow-sm);
}
.vessel-tracker-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.vessel-tracker-head h2 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  margin: 0 0 4px;
  color: var(--ink);
  letter-spacing: 0.2px;
}
.vessel-tracker-head p {
  margin: 0;
  font-size: 13px;
  color: var(--ink-soft);
}
.vessel-tracker-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }
.vessel-tracker-actions .btn-sm { padding: 6px 12px; font-size: 12px; }
#vessel-map {
  height: 380px;
  width: 100%;
  background: linear-gradient(180deg, #d6e3ec 0%, #c8d8e3 100%);
}
#vessel-map iframe { display: block; width: 100%; height: 100%; border: 0; }
/* R56 — backstop sizing for the VesselFinder script embed. Their
   aismap.js injects an iframe whose width/height it sets from the
   `var width` / `var height` globals; this rule guarantees the
   injected element fills the mount regardless. */
#vessel-tracker-mount,
#vessel-tracker-mount iframe {
  width: 100% !important;
  height: 100% !important;
  border: 0;
  display: block;
}
.vessel-map-fallback {
  padding: 60px 20px;
  text-align: center;
  color: var(--ink-muted);
  font-size: 13px;
}

/* Pulsing red marker for the boat. The pulse layer expands outward and fades;
   the dot is layered on top so it stays sharp. */
.vessel-marker { position: relative; }
.vessel-marker-dot {
  width: 14px; height: 14px;
  background: var(--red-500);
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.45);
  position: absolute;
  top: 1px; left: 1px;
  z-index: 2;
}
.vessel-marker-pulse {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--red-500);
  position: absolute;
  top: 0; left: 0;
  opacity: 0.55;
  animation: vesselPulse 2.2s ease-out infinite;
  z-index: 1;
}
@keyframes vesselPulse {
  0%   { transform: scale(1);   opacity: 0.55; }
  100% { transform: scale(3.4); opacity: 0;    }
}

/* Other-traffic markers — small triangular arrows pointed by COG when
   we have it, dot fallback when we don't. Stale marker (>5 min) fades.
   Kept far visually subordinate to the pulsing red own-vessel marker. */
.traffic-marker { pointer-events: auto; }
.traffic-marker .tm-arrow {
  position: absolute;
  top: 50%; left: 50%;
  width: 0; height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 11px solid rgba(52, 85, 120, 0.78);
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.45));
  transform-origin: 50% 60%;
}
.traffic-marker .tm-dot {
  width: 8px; height: 8px;
  background: rgba(52, 85, 120, 0.75);
  border-radius: 50%;
  border: 1px solid #fff;
  margin: 3px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
.traffic-marker.stale .tm-arrow,
.traffic-marker.stale .tm-dot { opacity: 0.35; }

/* Toolbar controls next to the AIS pill */
.ais-traffic-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--navy-800);
  cursor: pointer;
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  background: #fff;
  user-select: none;
}
.ais-traffic-toggle input { accent-color: var(--navy-700); margin: 0; }
.ais-traffic-range {
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  background: #fff;
  color: var(--navy-800);
}

/* ============================================================
   WATCH KEEPING (harbour watch — daily duty assignments)
   ============================================================ */
.watch-shell {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  overflow: hidden;
}
.watch-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  flex-wrap: wrap;
}
.watch-list { display: flex; flex-direction: column; }
/* R50 (2026-05-11) — three duty slots per day (Engineer + Deck +
   Interior/Galley). Date column narrowed slightly to fit. */
.watch-day {
  display: grid;
  grid-template-columns: 92px 1fr 1fr 1fr;
  gap: 8px;
  padding: 10px 16px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  align-items: center;
}
.watch-day.today { background: rgba(225, 29, 46, 0.04); }
.watch-day.weekend .watch-date small { color: var(--red-600); }
/* Cruising day — banner replaces all three slot cells */
.watch-day-cruising { grid-template-columns: 92px 1fr; }
/* Phone: stack slots under the date column */
@media (max-width: 720px) {
  .watch-day { grid-template-columns: 80px 1fr; row-gap: 6px; }
  .watch-day .watch-slot { grid-column: 2; }
  .watch-day-cruising { grid-template-columns: 80px 1fr; }
}
.watch-cruise-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(90deg, rgba(76, 115, 133, 0.06), rgba(76, 115, 133, 0.02));
  border-left: 3px solid var(--navy-700);
  border-radius: 6px;
  padding: 10px 14px;
}
.watch-cruise-icon { font-size: 18px; }
.watch-cruise-banner strong { display: block; font-size: 13px; color: var(--navy-900); }
.watch-cruise-banner small { display: block; font-size: 11px; color: var(--ink-muted); margin-top: 2px; }

/* R147 (v1.70) — Soft "Planned voyage" strip. Sits above the watch
   slots when a draft itinerary covers the day. Spans the whole row,
   slots flow into a second grid row below it and remain assignable. */
.watch-day.has-planned { row-gap: 8px; }
.watch-planned-strip {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--navy-800, #284558);
  background: rgba(167, 134, 70, 0.08);      /* warm gold tint */
  border-left: 3px solid #a78646;
  border-radius: 4px;
  padding: 6px 12px;
}
.watch-planned-strip strong { font-weight: 600; }
.watch-planned-icon { font-size: 14px; line-height: 1; }
.watch-planned-sub  { color: var(--ink-muted, #64748b); font-style: italic; }
.watch-date { display: flex; flex-direction: column; }
.watch-date strong { font-size: 13px; color: var(--navy-900); font-weight: 700; }
.watch-date small { font-size: 11px; color: var(--ink-muted, #64748b); text-transform: uppercase; letter-spacing: 0.04em; }
.watch-slot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  background: #f8fafc;
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
  min-height: 36px;
}
.watch-slot:hover { border-color: var(--navy-700); background: #fff; }
.watch-slot.empty { color: var(--ink-muted, #64748b); font-style: italic; }
.watch-slot.mine { border-color: var(--red-500); background: rgba(225, 29, 46, 0.05); }
.watch-slot.swap-pending { border-color: #b45309; background: rgba(180, 83, 9, 0.10); }
.watch-slot-role {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  width: 14px;
  flex-shrink: 0;
}
.watch-slot.role-engineer .watch-slot-role { color: var(--navy-700); }
.watch-slot.role-deck     .watch-slot-role { color: var(--success, #137a40); }
.watch-slot.role-interior .watch-slot-role { color: #8a4fff; }
/* Legacy 'other' kept for any cached HTML — same colour as deck. */
.watch-slot.role-other    .watch-slot-role { color: var(--success); }
.watch-slot-name { font-weight: 500; color: var(--navy-900); flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.watch-slot-tag {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.watch-slot-tag.swap { background: rgba(180, 83, 9, 0.15); color: #92400e; }
.watch-slot-tag.warn { background: rgba(225, 29, 46, 0.12); color: var(--danger); }
/* Coverage gap — no eligible crew available in this pool today. */
.watch-slot.no-cover {
  border-color: rgba(225, 29, 46, 0.45);
  background: rgba(225, 29, 46, 0.06);
  color: var(--danger);
}

/* ============================================================
   NOTIFICATIONS BELL + DROPDOWN
   ============================================================ */
.notif-trigger {
  position: relative;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #fff;
  border-radius: 50%;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  margin-right: 8px;
  transition: background 0.16s var(--ease-precise), border-color 0.16s var(--ease-precise);
}
.notif-trigger .ic { width: 18px; height: 18px; }
.notif-trigger:hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255,255,255,0.3); }
.notif-badge {
  position: absolute;
  top: -4px; right: -4px;
  background: var(--red-500);
  color: #fff;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 5px;
  border: 1px solid var(--navy-800);
  min-width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.notif-badge.zero { display: none; }

/* R27 P2 — Web Push opt-in banner that surfaces on the home page
   when the user hasn't yet enabled phone notifications. Designed
   to be polite and dismissable; mounts as the first child of
   #page-portal so it sits above the bridge HUD. */
.push-prompt-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  margin: 0 0 16px;
  background: linear-gradient(135deg, #FFF4E0 0%, #FFE9CC 100%);
  border: 1px solid #F2CE96;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.push-prompt-icon {
  font-size: 28px;
  flex: 0 0 auto;
}
.push-prompt-text { flex: 1; min-width: 0; }
.push-prompt-text strong {
  display: block;
  color: var(--navy-900, #284558);
  font-size: 14px;
  margin-bottom: 2px;
}
.push-prompt-text p {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted, #4A5568);
  line-height: 1.4;
}
.push-prompt-actions {
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
}
@media (max-width: 640px) {
  .push-prompt-banner { flex-wrap: wrap; }
  .push-prompt-actions { width: 100%; justify-content: flex-end; }
}

/* R27 P1 — visual cue when a new notification arrives. The bell
   shakes for ~2.4s (4 quick wobbles) and the red badge does a
   pulsing halo so it draws the eye even if the captain is on
   another tab. Triggered by Notifications._alertNew(). */
.notif-trigger.is-flashing {
  animation: notif-bell-shake 0.6s ease-in-out 4;
  transform-origin: 50% 8px;     /* pivot at the bell's "yoke" */
}
@keyframes notif-bell-shake {
  0%, 100% { transform: rotate(0); }
  20%      { transform: rotate(-14deg); }
  40%      { transform: rotate(12deg); }
  60%      { transform: rotate(-9deg); }
  80%      { transform: rotate(6deg); }
}
.notif-badge.is-pulsing {
  animation: notif-badge-pulse 0.7s ease-out 3;
}
@keyframes notif-badge-pulse {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 rgba(225, 29, 46, 0.6); }
  60%  { transform: scale(1.35); box-shadow: 0 0 0 8px rgba(225, 29, 46, 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(225, 29, 46, 0); }
}
/* R27 P3d — panel lives at body root now (was inside .portal-nav,
   which is display:none on mobile). Fixed positioning so it
   anchors to the viewport regardless of the host. */
.notif-panel {
  position: fixed;
  top: 70px;
  right: 16px;
  width: 380px;
  max-width: calc(100vw - 24px);
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(52, 85, 120, 0.2);
  display: none;
  flex-direction: column;
  z-index: 1250;
  max-height: 75vh;
  overflow: hidden;
}
.notif-panel.open { display: flex; }
/* On mobile (where the bell is hidden inside the closed drawer),
   the panel becomes a full-width sheet anchored under the header. */
@media (max-width: 900px) {
  .notif-panel {
    top: 64px;
    right: 0;
    left: 0;
    width: 100vw;
    max-width: 100vw;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    max-height: calc(100vh - 64px);
    max-height: calc(100dvh - 64px);
  }
}
.notif-head {
  padding: 10px 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  background: #fafbfc;
}
.notif-head h3 { margin: 0; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--navy-700); white-space: nowrap; }
/* R39c — tidy toolbar inside the notifications panel.  No wrapping,
   consistent spacing, icon buttons for mute / close. */
.notif-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
}
.notif-actions .btn-link {
  font-size: 12px;
  font-weight: 600;
  padding: 6px 8px;
  border-radius: 6px;
  white-space: nowrap;
  background: transparent;
  border: 0;
  color: var(--navy-700);
  cursor: pointer;
  text-decoration: none;
}
.notif-actions .btn-link:hover { background: var(--navy-50, #F2F5F8); color: var(--navy-900); }
.notif-actions .btn-icon {
  width: 28px; height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
}
.notif-list { overflow-y: auto; padding: 4px 0; }
.notif-row {
  display: flex;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  cursor: pointer;
  transition: background 0.12s;
}
.notif-row:hover { background: var(--cream, #faf6f0); }
.notif-row.unread { background: rgba(225, 29, 46, 0.04); }
/* R39c — per-row dismiss X. Subtle until hover. */
.notif-row { position: relative; align-items: flex-start; }
.notif-dismiss {
  flex-shrink: 0;
  width: 22px; height: 22px;
  border: 0;
  background: transparent;
  color: var(--ink-muted, #94a3b8);
  font-size: 16px;
  line-height: 1;
  border-radius: 6px;
  padding: 0;
  margin-left: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.notif-row:hover .notif-dismiss,
.notif-dismiss:focus-visible { opacity: 1; }
.notif-dismiss:hover {
  background: rgba(225, 29, 46, 0.08);
  color: var(--red-700, var(--danger));
}
@media (hover: none) {
  /* On touch devices show the X always — no hover state */
  .notif-dismiss { opacity: 0.5; }
}
.notif-row .notif-icon {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: rgba(76, 115, 133, 0.06);
  color: var(--navy-700);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}
.notif-row.kind-leave .notif-icon { background: rgba(180, 83, 9, 0.12); color: #92400e; }
.notif-row.kind-hours .notif-icon { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.notif-row.kind-watch .notif-icon { background: rgba(76, 115, 133, 0.10); color: var(--navy-800); }
.notif-row.kind-expiry .notif-icon { background: rgba(180, 83, 9, 0.15); color: #92400e; }
.notif-row.kind-bank .notif-icon { background: rgba(22, 101, 52, 0.10); color: var(--success); }
.notif-row .notif-body { flex: 1; min-width: 0; }
.notif-row .notif-title { font-size: 13px; color: var(--navy-900); font-weight: 500; }
.notif-row .notif-sub   { font-size: 11px; color: var(--ink-muted, #64748b); margin-top: 2px; }
.notif-empty { font-size: 13px; color: var(--ink-muted, #64748b); padding: 24px 16px; text-align: center; }

/* ============================================================
   R27 P3 — Direct Messages between crew
   Two-pane layout (rail + thread). Rail collapses on narrow
   viewports; the active thread becomes a single column with a
   sticky composer at the bottom.
   ============================================================ */
.messages-shell {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 12px;
  /* R129 — dynamic viewport height for iOS Safari address-bar jank. */
  height: calc(100dvh - 220px);
  min-height: 500px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  overflow: hidden;
}
/* R129 — phone stacking. The existing 720px rule further down handles
   tablets; this 640px breakpoint snaps the rail into a horizontal strip
   above the thread so neither pane is < 200px wide. */
@media (max-width: 640px) {
  .messages-shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    height: calc(100dvh - 180px);
  }
  .messages-rail {
    max-height: 180px;
    border-right: 0;
    border-bottom: 1px solid var(--navy-100, #DCE7ED);
  }
}
.messages-rail {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
  min-height: 0;
}
.messages-rail-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
}
.messages-rail-head h3 {
  margin: 0;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
}
.messages-conv-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0;
}
.messages-conv-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  width: 100%;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  transition: background 0.12s;
  position: relative;
}
.messages-conv-row:hover { background: var(--cream, #faf6f0); }
.messages-conv-row.active { background: rgba(76, 115, 133, 0.06); }
.messages-conv-row.unread .messages-conv-name { font-weight: 700; color: var(--navy-900); }
.messages-conv-avatar {
  width: 36px; height: 36px;
  border-radius: 999px;
  background: var(--navy-700);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.messages-conv-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.messages-conv-name {
  font-size: 14px;
  color: var(--navy-900);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.messages-conv-time {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  margin-top: 2px;
}
.messages-conv-dot {
  width: 8px; height: 8px;
  border-radius: 999px;
  background: var(--red-500, #e11d2e);
  flex-shrink: 0;
}
.messages-thread {
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}
.messages-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
#messages-thread-active {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.messages-thread-head {
  padding: 12px 18px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  font-size: 14px;
  color: var(--navy-900);
}
.messages-thread-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: #f7f9fc;
}
.messages-msg {
  display: flex;
  flex-direction: column;
  max-width: 75%;
}
.messages-msg.is-mine { align-self: flex-end; align-items: flex-end; }
.messages-msg.is-theirs { align-self: flex-start; align-items: flex-start; }
.messages-msg-sender {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  margin-bottom: 2px;
  margin-left: 4px;
}
.messages-msg-bubble {
  padding: 8px 12px;
  border-radius: 14px;
  font-size: 14px;
  line-height: 1.4;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.messages-msg.is-mine .messages-msg-bubble {
  background: var(--navy-700);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.messages-msg.is-theirs .messages-msg-bubble {
  background: #fff;
  color: var(--navy-900);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-bottom-left-radius: 4px;
}
.messages-msg-time {
  font-size: 10px;
  color: var(--ink-muted, #64748b);
  margin-top: 2px;
  padding: 0 4px;
}
.messages-composer {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding: 10px 14px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
}
.messages-composer textarea {
  flex: 1;
  resize: none;
  font-family: inherit;
  font-size: 14px;
  padding: 8px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  min-height: 38px;
  max-height: 140px;
  line-height: 1.4;
}
.messages-composer textarea:focus {
  outline: none;
  border-color: var(--navy-700);
}

/* R28 P4 — Attach button + queued attachment chips */
.messages-attach-btn {
  background: transparent;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--navy-700);
  flex-shrink: 0;
  transition: background 0.16s var(--ease-precise), border-color 0.16s var(--ease-precise);
}
.messages-attach-btn .ic { width: 18px; height: 18px; }
.messages-attach-btn:hover { background: var(--cream, #faf6f0); border-color: var(--navy-700); }
.messages-composer-queue {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
}
.messages-composer-queue.hidden { display: none; }
.att-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 6px 8px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  font-size: 12px;
  color: var(--navy-900);
  position: relative;
  transition: border-color 0.12s, opacity 0.18s;
}
.att-chip.uploading { border-color: var(--navy-700); }
.att-chip.error     { border-color: var(--red-500, #e11d2e); background: rgba(225, 29, 46, 0.06); }
.att-chip.uploaded  { opacity: 0.7; }
.att-chip-icon { font-size: 14px; }
.att-chip-text { display: inline-flex; flex-direction: column; line-height: 1.15; }
.att-chip-name { font-weight: 600; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-chip-meta { font-size: 10px; color: var(--ink-muted, #64748b); }
.att-chip-remove {
  background: transparent;
  border: 0;
  color: var(--ink-muted, #64748b);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0 2px;
}
.att-chip-remove:hover { color: var(--red-500, #e11d2e); }

/* Drop-target visual cue when files are being dragged over the thread */
#messages-thread-active.drop-target {
  outline: 2px dashed var(--navy-700);
  outline-offset: -8px;
  background: rgba(76, 115, 133, 0.04);
}

/* ============================================================
   R28 P4c — Inline attachment rendering inside message bubbles
   ============================================================ */
.messages-msg-attachments {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 4px;
}
.msg-att {
  display: block;
  border-radius: 12px;
  overflow: hidden;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  position: relative;
  max-width: 280px;
}
.msg-att-img {
  width: 280px;
  background: #e6ecf3;
}
.msg-att-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.msg-att-video {
  width: 280px;
  background: #000;
  position: relative;
}
.msg-att-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: pointer;
}
.msg-att-vid-badge {
  position: absolute;
  bottom: 8px;
  left: 8px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  pointer-events: none;
}
.msg-att-file {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  text-decoration: none;
  color: var(--navy-900);
  max-width: 280px;
  border-radius: 10px;
}
.messages-msg.is-mine .msg-att-file {
  background: rgba(255, 255, 255, 0.94);
}
.msg-att-file:hover { border-color: var(--navy-700); }
.msg-att-file-icon { font-size: 18px; flex-shrink: 0; }
.msg-att-file-meta { display: flex; flex-direction: column; min-width: 0; }
.msg-att-file-name {
  font-size: 13px; font-weight: 600; max-width: 220px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.msg-att-file-size { font-size: 11px; color: var(--ink-muted, #64748b); }

/* Day divider in the thread */
.messages-day-divider {
  text-align: center;
  margin: 12px 0 6px;
  position: relative;
}
.messages-day-divider span {
  display: inline-block;
  background: rgba(76, 115, 133, 0.08);
  color: var(--navy-700);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 12px;
  border-radius: 999px;
}

/* ============================================================
   R28 P4c — Fullscreen lightbox
   ============================================================ */
body.lb-locked { overflow: hidden; }
.messages-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(8, 12, 24, 0.96);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  padding: 16px;
  animation: lbFadeIn 0.18s ease;
}
.messages-lightbox.hidden { display: none; }
@keyframes lbFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lb-close, .lb-prev, .lb-next {
  position: absolute;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  border: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 24px;
  cursor: pointer;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.lb-close:hover, .lb-prev:hover, .lb-next:hover { background: rgba(255, 255, 255, 0.22); }
.lb-close { top: 16px; right: 16px; }
.lb-prev  { left: 16px;  top: 50%; transform: translateY(-50%); }
.lb-next  { right: 16px; top: 50%; transform: translateY(-50%); }
.lb-stage {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
.lb-stage img, .lb-stage video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
}
.lb-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 12px;
  color: #cbd5e1;
  font-size: 12px;
  gap: 12px;
}
.lb-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-actions { display: inline-flex; gap: 8px; flex-shrink: 0; }
.lb-actions .btn-ghost { color: #fff; border-color: rgba(255,255,255,0.3); }
.lb-actions .btn-ghost:hover { background: rgba(255,255,255,0.12); }

/* ============================================================
   R28 P4d — Right-click context menu on message bubbles
   ============================================================ */
.messages-ctxmenu {
  position: fixed;
  z-index: 2100;
  min-width: 220px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  box-shadow: 0 12px 36px rgba(52, 85, 120, 0.25);
  padding: 6px 0;
  animation: ctxFadeIn 0.12s ease;
}
.messages-ctxmenu.hidden { display: none; }
@keyframes ctxFadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.ctx-item {
  display: block;
  width: 100%;
  padding: 9px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  font-size: 13px;
  color: var(--navy-900);
  cursor: pointer;
}
.ctx-item:hover { background: var(--cream, #faf6f0); }
.ctx-divider {
  border-top: 1px solid var(--navy-100, #DCE7ED);
  margin: 4px 0;
}

/* TODO row attachment indicator + modal attachment grid */
.todo-att-flag {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  padding: 0 6px;
}
#todo-attachments-block { margin: 8px 0 4px; }
.todo-attachments-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
.todo-att {
  display: inline-block;
  border-radius: 8px;
  overflow: hidden;
  border: 0;
  padding: 0;
  background: #e6ecf3;
  cursor: pointer;
  position: relative;
  width: 110px;
  height: 110px;
}
.todo-att-img img,
.todo-att-video video { width: 100%; height: 100%; object-fit: cover; display: block; }
.todo-att-file {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  height: auto;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  padding: 8px 10px;
  text-decoration: none;
  color: var(--navy-900);
  border-radius: 8px;
}

/* ============================================================
   R29 + R37 — Finance tabs (pill buttons) + Budget editor + Dashboard
   ============================================================ */
.finance-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
  padding-bottom: 4px;
}
.finance-tab {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  padding: 9px 18px;
  font-size: 13px;
  color: var(--navy-700);
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.05s;
  white-space: nowrap;
}
.finance-tab:hover {
  border-color: var(--navy-700);
  color: var(--navy-900);
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.08);
}
.finance-tab:focus-visible {
  outline: 2px solid var(--red-500, #e11d2e);
  outline-offset: 2px;
}
.finance-tab:active { transform: translateY(1px); }
.finance-tab.active {
  background: var(--navy-900, #284558);
  border-color: var(--navy-900, #284558);
  color: #fff;
  box-shadow: 0 2px 8px rgba(40, 69, 88, 0.25);
}
.finance-tab.active:hover {
  background: var(--navy-700, #4A7791);
  border-color: var(--navy-700, #4A7791);
  color: #fff;
}
.finance-pane.hidden { display: none; }
.finance-pane { padding-top: 18px; }

@media (max-width: 640px) {
  .finance-tabs {
    gap: 6px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
    padding-bottom: 8px;
    margin-bottom: 4px;
  }
  .finance-tab { padding: 8px 14px; font-size: 12.5px; }
}

.budget-toolbar {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.budget-tip {
  background: rgba(76, 115, 133, 0.04);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--navy-700);
  margin: 12px 0;
}
.budget-section {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  margin-bottom: 12px;
  overflow: hidden;
}
.budget-section > summary {
  padding: 12px 16px;
  cursor: pointer;
  background: #fafbfc;
  border-bottom: 1px solid transparent;
  font-size: 14px;
}
.budget-section[open] > summary {
  border-bottom-color: var(--navy-100, #DCE7ED);
}
.budget-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.budget-table th {
  text-align: left;
  padding: 8px 12px;
  background: #fafbfc;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
}
.budget-table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  vertical-align: middle;
}
.budget-table tbody tr:last-child td { border-bottom: 0; }

/* R39 — lock budget editor columns so each group's table aligns
   identically.  Without this, table-auto sizing makes the budget
   input column shift left/right depending on the longest description
   in each group. */
.budget-editor-table { table-layout: fixed; }
.budget-editor-table .bcol-code   { width: 110px; }
.budget-editor-table .bcol-desc   { width: auto; }
.budget-editor-table .bcol-amount { width: 200px; }
.budget-editor-table .bcol-ccy    { width: 90px; }
.budget-editor-table .bcol-status { width: 90px; }
.budget-editor-table .th-amount,
.budget-editor-table td:nth-child(3) { text-align: right; }
.budget-editor-table .th-ccy,
.budget-editor-table td:nth-child(4) { text-align: left; }
.budget-editor-table .th-status,
.budget-editor-table td:nth-child(5) { text-align: right; }
.budget-editor-table .budget-input {
  width: 100%;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.budget-table code {
  background: rgba(76, 115, 133, 0.06);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
  color: var(--navy-700);
}
.budget-input {
  width: 140px;
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  text-align: right;
  font-family: ui-monospace, monospace;
}
.budget-input:focus { outline: none; border-color: var(--navy-700); }
.budget-pill.saved {
  display: inline-block;
  font-size: 10px;
  text-transform: uppercase;
  background: rgba(22, 101, 52, 0.10);
  color: var(--success, #166534);
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 600;
}

/* Dashboard rows: progress bars */
.dashboard-table .bar {
  position: relative;
  background: rgba(76, 115, 133, 0.08);
  border-radius: 6px;
  height: 22px;
  width: 200px;
  overflow: hidden;
}
.dashboard-table .bar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 6px;
  transition: width 0.3s;
}
.dashboard-table .bar-ok    { background: var(--success, #166534); }
.dashboard-table .bar-warn  { background: #b45309; }
.dashboard-table .bar-over  { background: var(--red-500, #e11d2e); }
.dashboard-table .bar-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0,0,0,0.2);
}

/* ============================================================
   R31 — Card Transactions tab
   ============================================================ */
.cards-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin: 8px 0;
}
.cards-toolbar input[type="month"],
.cards-toolbar select {
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
}
/* R38a — month picker as a single segmented control */
.card-month-picker {
  display: inline-flex;
  align-items: center;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  overflow: hidden;
  margin-right: 8px;
}
.card-month-picker input[type="month"] {
  border: 0;
  border-radius: 0;
  background: transparent;
  margin: 0;
  padding: 6px 8px;
  font-size: 13px;
  min-width: 130px;
}
.card-month-picker .card-month-nav {
  border: 0 !important;
  border-radius: 0;
  padding: 6px 12px;
  font-size: 18px;
  line-height: 1;
  color: var(--navy-700);
  background: transparent;
  cursor: pointer;
}
.card-month-picker .card-month-nav:hover {
  background: var(--navy-50, #F2F5F8);
  color: var(--navy-900);
}
.card-month-picker .card-month-nav:focus-visible {
  outline: 2px solid var(--red-500, #e11d2e);
  outline-offset: -2px;
}
.card-txn-table tr.card-txn-row { cursor: pointer; }
.card-txn-table tr.card-txn-row:hover { background: var(--cream, #faf6f0); }
.card-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: capitalize;
}
.card-pill-unmatched   { background: rgba(180, 83, 9, 0.15);  color: #92400e; }
.card-pill-matched     { background: rgba(22, 101, 52, 0.10); color: var(--success, #166534); }
.card-pill-disputed    { background: rgba(225, 29, 46, 0.10); color: var(--red-700, var(--danger)); }
.card-pill-reimbursable{ background: rgba(76, 115, 133, 0.10);  color: var(--navy-700); }
/* R119 — grey "Receipt Missing" pill for txns where the captain has
   attested no receipt exists. Visually distinct from "Unmatched"
   (orange = action needed) so the captain knows it's paperwork-only. */
.card-pill-receipt-missing { background: rgba(100, 116, 139, 0.15); color: #475569; text-transform: none; }
/* R125 — Computed pill colours for the 5-state model.
   Override pair (disputed / reimbursable) lives in the existing rules
   above; these are the auto-derived states that follow from
   (has_receipt, has_code, missing_attested). */
.card-pill-completed             { background: rgba(22, 101, 52, 0.10); color: var(--success, #166534); text-transform: none; }
.card-pill-completed-noreceipt   { background: rgba(22, 101, 52, 0.08); color: #15803d; text-transform: none; border: 1px dashed rgba(22, 101, 52, 0.35); }
.card-pill-pending-code          { background: rgba(202, 138, 4, 0.15); color: #a16207; text-transform: none; }
.card-pill-pending-receipt       { background: rgba(180, 83, 9, 0.15);  color: #92400e; text-transform: none; }
.card-pill-incomplete            { background: rgba(225, 29, 46, 0.10); color: var(--red-700, var(--danger)); text-transform: none; }

/* R125 — Receipt-column icon.  Wise-style: paper glyph + a small
   corner badge (✓ when attached, + when empty).  Attested-missing
   uses the 📝 emoji on its own. */
.rcpt-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--navy-50, #F2F5F8);
  font-size: 14px;
  line-height: 1;
}
.rcpt-icon-empty    { cursor: pointer; opacity: 0.7; }
.rcpt-icon-attached { background: rgba(22, 101, 52, 0.08); }
.rcpt-icon-attested { cursor: pointer; background: rgba(100, 116, 139, 0.15); }
.rcpt-badge {
  position: absolute;
  right: -3px; bottom: -3px;
  width: 14px; height: 14px;
  border-radius: 50%;
  font-size: 9px;
  font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  background: #fff;
  border: 1px solid var(--navy-100);
}
.rcpt-badge-ok  { color: #166534; background: #dcfce7; border-color: #bbf7d0; }
.rcpt-badge-add { color: #475569; font-size: 11px; line-height: 1; }
/* R125 — Drop highlight: ring + scale-up so the crew knows the icon
   accepts the file.  Any rcpt-icon* can take it; specificity is high
   enough to win over the base-state backgrounds. */
.rcpt-icon.rcpt-icon-dragover {
  background: #dcfce7;
  outline: 2px dashed #166534;
  outline-offset: 2px;
  transform: scale(1.1);
  transition: transform 0.1s;
}

/* R125 polish — Tighten Merchant + widen Account code so the code+sub
   never wraps onto a second line.  Merchant truncates with ellipsis
   when very long; tooltip on hover via the cell's own title (set by
   the strong tag).  Targets only the card-txn-table so other budget
   tables stay auto-sized. */
.card-txn-table .col-merchant {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-txn-table .col-merchant strong {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}
.card-txn-table .col-account-code {
  min-width: 240px;
  white-space: nowrap;
}
/* R125 — Inline code <select> in the cards table.  Borderless until
   hover so the table doesn't look noisy with 200 dropdown frames;
   on hover the border shows so the user knows it's interactive. */
.inline-code-select {
  width: 100%;
  padding: 4px 6px;
  font: inherit;
  font-size: 12px;
  color: var(--ink, #4A7791);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  text-overflow: ellipsis;
}
.inline-code-select:hover,
.inline-code-select:focus {
  border-color: var(--navy-100, #DCE7ED);
  background: #fff;
  outline: none;
}

/* R125 — Mobile reflow.  Under 720px the cards table stops being a
   table and becomes a stack of vertical cards, one per txn.  Each
   card has:
     [Date · Card]        [All-in (currency)]
     [Merchant]           [USD subline]
     [Account code select — full width]
     [Status pill]                  [Receipt icon]
   The thead is hidden — labels are inferred from layout + the cell
   itself.  Desktop layout (table) stays unchanged above the breakpoint.
*/
@media (max-width: 720px) {
  .card-txn-table,
  .card-txn-table thead,
  .card-txn-table tbody,
  .card-txn-table td { display: block; box-sizing: border-box; }
  .card-txn-table thead { display: none; }
  .card-txn-table tr.card-txn-row {
    position: relative;
    margin: 0 0 10px;
    padding: 12px 14px 10px;
    border: 1px solid var(--navy-100, #DCE7ED);
    border-radius: 10px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(52, 85, 120, 0.04);
    display: grid !important;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "date     allin"
      "merchant usd"
      "card     card"
      "code     code"
      "status   receipt";
    column-gap: 12px;
    row-gap: 4px;
  }
  .card-txn-table tr.card-txn-row > td { padding: 0; border: none; }
  .card-txn-table tr.card-txn-row .col-date     { grid-area: date;     font-size: 12px; color: var(--ink-muted); }
  .card-txn-table tr.card-txn-row .col-card     { grid-area: card;     font-size: 11px; color: var(--ink-muted); margin-top: -2px; }
  .card-txn-table tr.card-txn-row .col-merchant { grid-area: merchant; max-width: none; white-space: normal; font-size: 15px; }
  .card-txn-table tr.col-merchant strong        { display: block; }
  .card-txn-table tr.card-txn-row .col-all-in   { grid-area: allin;    text-align: right; font-size: 15px; }
  .card-txn-table tr.card-txn-row .col-usd      { grid-area: usd;      text-align: right; font-size: 12px; color: var(--ink-muted); }
  .card-txn-table tr.card-txn-row .col-charge   { display: none; }     /* "All-in" covers the math; "Charge + fee" is desktop-detail */
  .card-txn-table tr.card-txn-row .col-account-code {
    grid-area: code;
    min-width: 0;
    margin-top: 4px;
    padding: 4px 6px;
    border: 1px solid var(--navy-100);
    border-radius: 6px;
    background: var(--navy-50, #F2F5F8);
  }
  .card-txn-table tr.card-txn-row .col-account-code .inline-code-select {
    background: transparent;
    font-size: 13px;
    padding: 2px 4px;
  }
  .card-txn-table tr.card-txn-row .col-status   { grid-area: status;   margin-top: 6px; }
  .card-txn-table tr.card-txn-row .col-receipt  { grid-area: receipt;  margin-top: 6px; text-align: right; }
  /* Receipt icon a hair bigger on mobile — easier to tap, easier to drop on. */
  .card-txn-table .rcpt-icon { width: 36px; height: 36px; font-size: 16px; }
  .card-txn-table .rcpt-badge { width: 16px; height: 16px; font-size: 10px; }
  /* KPI strip already collapses via .cards-kpis grid auto-fit; the
     existing rule handles it.  Filter chips wrap naturally. */
}

/* R30 P6a — PO row + status pills */
.po-row { cursor: pointer; }
.po-row:hover { background: var(--cream, #faf6f0); }
.po-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: capitalize;
}
.po-pill-draft           { background: rgba(76, 115, 133, 0.06);  color: var(--ink-muted, #64748b); }
.po-pill-submitted       { background: rgba(180, 83, 9, 0.15);  color: #92400e; }
.po-pill-pending_hod     { background: rgba(180, 83, 9, 0.15);  color: #92400e; }
.po-pill-pending_captain { background: rgba(31, 77, 143, 0.18); color: #1f4d8f; }
.po-pill-pending_office  { background: rgba(168, 85, 247, 0.16); color: #6d28d9; }
.po-pill-approved        { background: rgba(76, 115, 133, 0.10);  color: var(--navy-700); }
.po-pill-ordered         { background: rgba(31, 77, 143, 0.12); color: #1f4d8f; }
.po-pill-received        { background: rgba(31, 77, 143, 0.18); color: #4A7791; }
.po-pill-invoiced        { background: rgba(180, 83, 9, 0.18);  color: #b45309; }
.po-pill-paid            { background: rgba(22, 101, 52, 0.10); color: var(--success, #166534); }
.po-pill-cancelled       { background: rgba(225, 29, 46, 0.10); color: var(--red-700, var(--danger)); }
.po-pill-rejected        { background: rgba(225, 29, 46, 0.14); color: var(--red-700, var(--danger)); }
/* R41 — final delivery / service-completed stage */
.po-pill-delivered       { background: rgba(22, 101, 52, 0.18); color: var(--success, #14532d); font-weight: 800; }
/* R104 — Receipt-Missing attestation. Amber so it stands next to
   the green "paid" / "attested ✓" pills without being mistaken for
   an error. The -pending modifier nudges saturation up so co-sign-
   pending rows pop in a long list. */
.po-pill-receipt-missing         { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.po-pill-receipt-missing-pending { background: rgba(245, 158, 11, 0.32); color: #78350f; font-weight: 700; }

/* R41b — Captain override picker in PR action row */
.po-captain-override {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 12px;
  border: 1px dashed var(--navy-200, #C2CDDD);
  border-radius: 999px;
  background: rgba(76, 115, 133, 0.03);
}
.po-captain-override select {
  border: 0;
  background: transparent;
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-900);
  padding: 4px 8px;
  cursor: pointer;
}
.po-captain-override:hover {
  border-color: var(--navy-700);
  background: rgba(76, 115, 133, 0.06);
}

/* R40 — miscategorisation flag badge in PO list */
.po-flag-badge {
  display: inline-block;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 4px;
  margin-right: 4px;
  font-weight: 700;
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fde68a;
  vertical-align: middle;
  cursor: help;
}
.po-flag-iban { background: #fde68a; border-color: #f59e0b; }
.po-flag-name { background: #fef3c7; border-color: #fde68a; }
.po-row-flagged { background: rgba(254, 243, 199, 0.35); }
.po-row-flagged:hover { background: rgba(254, 243, 199, 0.65); }
/* R40 — clickable amber tile on the dashboard */
.dashboard-flag-tile { transition: background 0.15s, box-shadow 0.15s; }
.dashboard-flag-tile:hover { background: #fde68a !important; box-shadow: 0 2px 8px rgba(146,64,14,0.18); }

/* R38 — traffic-light stepper used inside the PO detail modal */
.po-stepper {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 12px 0 18px;
  padding: 14px 16px;
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.po-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 60px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted, #94a3b8);
}
.po-step + .po-step::before {
  content: '';
  position: absolute;
  top: 9px;
  left: -50%;
  width: 100%;
  height: 2px;
  background: #e2e8f0;
  z-index: 0;
}
.po-step-dot {
  position: relative;
  z-index: 1;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #cbd5e1;
}
.po-step-label { font-weight: 600; }
.po-step-done .po-step-dot   { background: #22c55e; border-color: #16a34a; }
.po-step-done                { color: #16a34a; }
.po-step-done + .po-step::before { background: #86efac; }
.po-step-active .po-step-dot {
  background: #f59e0b;
  border-color: #b45309;
  box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.18);
  animation: po-step-pulse 1.6s ease-in-out infinite;
}
.po-step-active              { color: #92400e; }
.po-step-paid .po-step-dot   { background: var(--success, #166534); border-color: var(--success, #166534); }
.po-stepper-rejected .po-step-rejected .po-step-dot {
  background: var(--red-500, #e11d2e);
  border-color: var(--red-700, var(--danger));
}
.po-stepper-rejected .po-step-rejected { color: var(--red-700, var(--danger)); }
@keyframes po-step-pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.18); }
  50%      { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0.06); }
}

/* R38 — compact inline traffic-light next to the row's status pill */
.po-tl {
  display: inline-flex;
  gap: 3px;
  vertical-align: middle;
  margin-right: 6px;
}
.po-tl-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #e2e8f0;
}
.po-tl-dot.done   { background: #22c55e; }
.po-tl-dot.active { background: #f59e0b; box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18); }
.po-tl-rejected .po-tl-dot.active { background: var(--red-500, #e11d2e); box-shadow: 0 0 0 2px rgba(225, 29, 46, 0.16); }
.po-tl-cancelled .po-tl-dot.active { background: var(--ink-muted, #64748b); }

/* R38 — signatures block in the PO detail modal */
.po-signatures {
  background: #fafbfc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px 16px;
  margin: 14px 0;
}
.po-signatures h4 {
  margin: 0 0 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
}
.po-sig-row {
  display: grid;
  grid-template-columns: 90px 1fr auto;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  font-size: 13px;
  align-items: center;
}
.po-sig-row:first-of-type { border-top: 0; }
.po-sig-row strong {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted, #64748b);
  font-weight: 700;
}
.po-sig-name {
  font-family: var(--display, 'Georgia', serif);
  font-style: italic;
  font-size: 16px;
  color: var(--navy-900);
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  padding-bottom: 2px;
}
.po-sig-time { font-size: 11px; color: var(--ink-muted, #64748b); }

/* Print: keep the stepper + signatures readable on paper */
@media print {
  .po-stepper { background: transparent; border: 0; padding: 0; margin: 8px 0; }
  .po-step-active .po-step-dot { animation: none !important; box-shadow: none !important; }
  .po-signatures { break-inside: avoid; }
}

.po-lines-table input,
.po-lines-table select {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  font-size: 12px;
}
.po-lines-table th { font-size: 10px; }
.po-lines-table td { padding: 4px 6px; }

/* ============================================================
   R32 — Purchase Orders list, grouped by department
   ============================================================ */
.po-group {
  background: rgba(255,255,255,0.5);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  margin-bottom: 14px;
  overflow: hidden;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.po-group-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 12px 18px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: linear-gradient(180deg, rgba(20,37,61,0.04), rgba(20,37,61,0.01));
}
.po-group-head h3 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--navy-900);
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
}
.po-group-count {
  background: var(--navy-700);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 8px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  text-transform: none;
}
.po-group-totals {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-family: ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}
.po-group-base-total {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900);
  letter-spacing: -0.01em;
}
.po-group-breakdown {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  font-weight: 400;
  margin-top: 2px;
}

.po-table-wrap { overflow-x: auto; }
/* R32 — table-layout:fixed + explicit column widths so every group's
   columns line up vertically with every other group's. Without this,
   each <table> auto-sizes independently and "Saltwater Recruitment"
   pushes the SUPPLIER column wider for the Administration group than
   the Deck group. */
.po-table {
  width: 100%;
  border-collapse: collapse;
  background: rgba(255,255,255,0.6);
  table-layout: fixed;
}
.po-table colgroup col.po-col-date     { width: 8%; }
.po-table colgroup col.po-col-supplier { width: 22%; }
.po-table colgroup col.po-col-invoice  { width: 13%; }
.po-table colgroup col.po-col-usd      { width: 13%; }
.po-table colgroup col.po-col-urgency  { width: 8%; }
.po-table colgroup col.po-col-ref      { width: 28%; }
.po-table colgroup col.po-col-status   { width: 8%; }
.po-table thead th {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted, #64748b);
  background: transparent;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  padding: 8px 12px;
  text-align: left;
  font-weight: 600;
}
.po-table th.po-cell-num { text-align: right; }
.po-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid rgba(76, 115, 133, 0.04);
  font-size: 13px;
  vertical-align: middle;
}
.po-table tbody tr:last-child td { border-bottom: 0; }
.po-table tbody tr:hover {
  background: rgba(76, 115, 133, 0.04);
  cursor: pointer;
}

.po-cell-date {
  font-family: ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--ink-muted, #64748b);
  white-space: nowrap;
}
.po-cell-supplier {
  font-weight: 600;
  color: var(--navy-900);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.po-cell-num {
  text-align: right;
  font-family: ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.po-cell-base { color: var(--navy-700); font-weight: 600; }

.po-cell-ref {
  font-family: ui-monospace, monospace;
  font-size: 10px;
  line-height: 1.3;
}
.po-ref-fname {
  display: block;
  color: var(--navy-900);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.po-ref-num {
  display: block;
  color: var(--ink-muted, #64748b);
  font-size: 9px;
  letter-spacing: 0.02em;
}

/* Urgency pills — small, coloured, sit alongside status pills */
.urg-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.urg-low    { background: rgba(76, 115, 133, 0.06);  color: var(--ink-muted, #64748b); }
.urg-medium { background: rgba(180, 83, 9, 0.15);  color: #92400e; }
.urg-high   { background: rgba(225, 29, 46, 0.12); color: var(--red-700, var(--danger)); }

/* ============================================================
   R56 (2026-05-12) — Mobile card layout for the Purchase Request
   table. Below 720px the desktop fixed-width grid is unusable (7
   columns squeezed into 360px → text bleeds across cells). Each
   <tr> becomes a stacked card with the supplier as the headline,
   labeled key/value rows below, and pills aligned to the right.
   thead is hidden; labels come from CSS ::before content keyed off
   the existing .po-cell-* classes so we don't need to retrofit the
   row template with data-label attributes.
   ============================================================ */
@media (max-width: 720px) {
  /* Group totals: stack header into two rows so the dept name and
     the big USD total don't collide. */
  .po-group-head {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 12px 14px;
  }
  .po-group-totals {
    align-items: flex-start;
  }
  .po-group-base-total { font-size: 18px; }

  /* Kill the horizontal scroll wrapper — cards don't need it. */
  .po-table-wrap { overflow-x: visible; }

  /* Re-flow the table itself as a stack of cards. */
  .po-table,
  .po-table thead,
  .po-table tbody,
  .po-table tr,
  .po-table td {
    display: block;
    width: 100%;
  }
  .po-table { table-layout: auto; background: transparent; }
  .po-table colgroup { display: none; }
  .po-table thead { display: none; }
  .po-table tbody tr.po-row {
    background: #fff;
    border: 1px solid var(--navy-100, #DCE7ED);
    border-radius: 10px;
    padding: 12px 14px 10px;
    margin: 10px 14px;
    box-shadow: 0 1px 2px rgba(40, 69, 88, 0.04);
    cursor: pointer;
  }
  .po-table tbody tr.po-row:hover { background: #fff; }
  .po-table tbody td {
    padding: 6px 0;
    border: 0;
    font-size: 13px;
    display: grid;
    grid-template-columns: 88px 1fr;
    gap: 10px;
    align-items: baseline;
  }
  /* Label generation — ::before on each typed cell. */
  .po-table tbody td.po-cell-date::before    { content: 'Date'; }
  .po-table tbody td.po-cell-num::before     { content: 'Native'; }
  .po-table tbody td.po-cell-num.po-cell-base::before { content: 'USD'; }
  .po-table tbody td.po-cell-ref::before     { content: 'Reference'; }
  .po-table tbody td.po-cell-status::before  { content: 'Status'; }
  /* Urgency cell has no class — target by position (5th td). */
  .po-table tbody td:nth-of-type(5)::before  { content: 'Urgency'; }
  .po-table tbody td::before {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted, #64748b);
    font-weight: 600;
    align-self: center;
  }
  /* Supplier is the headline — full width, no label, bold and
     larger than the rest. Sits at the top of every card. */
  .po-table tbody td.po-cell-supplier {
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--navy-900);
    white-space: normal;
    margin-bottom: 6px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(76, 115, 133, 0.06);
  }
  .po-table tbody td.po-cell-supplier::before { content: none; }
  /* Numbers stay right-aligned inside the value column. */
  .po-table tbody td.po-cell-num { text-align: left; }
  .po-table tbody td.po-cell-num > * { text-align: left; }
  /* Status cell: pills should wrap on narrow screens, not overflow. */
  .po-table tbody td.po-cell-status {
    flex-wrap: wrap;
  }
  .po-table tbody td.po-cell-status > * {
    display: inline-block;
    vertical-align: middle;
  }
  /* Ref cell — file name + PO number on separate lines, both
     left-aligned in the value column. */
  .po-table tbody td.po-cell-ref .po-ref-fname,
  .po-table tbody td.po-cell-ref .po-ref-num { white-space: normal; }
}

/* R56 (2026-05-12) — Generic .budget-table mobile fallback. Many
   secondary Finance tables (payroll runs, suppliers, sub-accounts,
   account-code editor, dashboard breakdowns) use .budget-table
   without semantic cell classes. On phones we collapse each row
   into a card with the first cell as the headline and remaining
   cells stacked vertically below — no labels (no data-label
   attrs to lean on). The user gets the row's identity + values
   in a thumb-readable layout instead of a 6-column squeeze. The
   :not(.po-table) guard keeps the PO table on its richer card
   pattern with labels (defined above). */
@media (max-width: 720px) {
  table.budget-table:not(.po-table) {
    display: block;
    width: 100%;
    background: transparent;
  }
  table.budget-table:not(.po-table) thead { display: none; }
  table.budget-table:not(.po-table) tbody,
  table.budget-table:not(.po-table) tr {
    display: block;
    width: 100%;
  }
  table.budget-table:not(.po-table) tbody tr {
    background: #fff;
    border: 1px solid var(--navy-100, #DCE7ED);
    border-radius: 10px;
    padding: 12px 14px;
    margin: 10px 0;
    box-shadow: 0 1px 2px rgba(40, 69, 88, 0.04);
  }
  table.budget-table:not(.po-table) tbody td {
    display: block;
    padding: 4px 0;
    border: 0;
    font-size: 13px;
    text-align: left !important;
  }
  table.budget-table:not(.po-table) tbody td:first-child {
    font-weight: 700;
    font-size: 14.5px;
    color: var(--navy-900);
    margin-bottom: 6px;
    padding-bottom: 6px;
    border-bottom: 1px solid rgba(76, 115, 133, 0.06);
  }
}

/* ============================================================
   R56 (2026-05-12) — Generic responsive-table card pattern.
   Add class="responsive-table" to any <table> to opt every row
   into the same supplier-card collapse below 720px. Cells use
   data-label="…" attributes on each <td> so the cell labels survive
   without depending on the table's specific class names.
   Usage in JS templates:
     <td data-label="Vendor">Acme</td>
   On mobile this renders as:
     ┌──────────────────────┐
     │ Vendor       Acme    │
     └──────────────────────┘
   ============================================================ */
@media (max-width: 720px) {
  table.responsive-table,
  table.responsive-table thead,
  table.responsive-table tbody,
  table.responsive-table tr,
  table.responsive-table td {
    display: block;
    width: 100%;
  }
  table.responsive-table { table-layout: auto; background: transparent; }
  table.responsive-table thead { display: none; }
  table.responsive-table tbody tr {
    background: #fff;
    border: 1px solid var(--navy-100, #DCE7ED);
    border-radius: 10px;
    padding: 12px 14px 10px;
    margin: 10px 0;
    box-shadow: 0 1px 2px rgba(40, 69, 88, 0.04);
  }
  table.responsive-table tbody td {
    padding: 6px 0;
    border: 0;
    font-size: 13px;
    display: grid;
    grid-template-columns: 100px 1fr;
    gap: 10px;
    align-items: baseline;
  }
  table.responsive-table tbody td::before {
    content: attr(data-label);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted, #64748b);
    font-weight: 600;
    align-self: center;
  }
  /* Headline cell — opt-in via data-headline="true" — spans the
     full card width with no label, bold and large. Use for the
     primary identifier of each row (supplier, crew name, vehicle). */
  table.responsive-table tbody td[data-headline="true"] {
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--navy-900);
    margin-bottom: 6px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(76, 115, 133, 0.06);
  }
  table.responsive-table tbody td[data-headline="true"]::before { content: none; }
  /* Cells that should keep their full layout (e.g. action buttons) — opt out. */
  table.responsive-table tbody td[data-label=""],
  table.responsive-table tbody td[data-no-label="true"] {
    display: block;
  }
  table.responsive-table tbody td[data-label=""]::before,
  table.responsive-table tbody td[data-no-label="true"]::before { content: none; }
}

/* ============================================================
   R33 — General Arrangement viewer
   ============================================================ */
.ga-cats {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 8px 0 14px;
}
.ga-stage {
  position: relative;
  background: rgba(255,255,255,0.7);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 12px;
  overflow: auto;
}
.ga-stage img,
.ga-stage canvas.ga-canvas {
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}
.ga-loading {
  position: absolute;
  inset: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 13px;
  color: var(--ink-muted, #607089);
  background:
    linear-gradient(90deg,
      rgba(222, 229, 238, 0.35) 0%,
      rgba(222, 229, 238, 0.75) 50%,
      rgba(222, 229, 238, 0.35) 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 8px;
  pointer-events: none;
}
.ga-pins-layer {
  position: absolute;
  inset: 12px;
}
.ga-pin {
  position: absolute;
  transform: translate(-50%, -100%);
  background: var(--navy-700);
  color: #fff;
  border: 2px solid #fff;
  border-radius: 999px;
  padding: 0;
  width: 14px;
  height: 14px;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0,0,0,0.25);
  z-index: 2;
  transition: transform 0.12s, box-shadow 0.12s;
}
.ga-pin::after {
  content: '';
  position: absolute;
  bottom: -6px; left: 50%;
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.25));
  color: inherit;
}
.ga-pin:hover {
  transform: translate(-50%, -100%) scale(1.4);
  z-index: 4;
  box-shadow: 0 4px 10px rgba(0,0,0,0.35);
}
.ga-pin .ga-pin-label {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: rgba(52, 85, 120, 0.92);
  color: #fff;
  font-size: 10px;
  white-space: nowrap;
  padding: 2px 8px;
  border-radius: 999px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.ga-pin .ga-pin-label em {
  font-style: normal;
  background: var(--red-500, #e11d2e);
  padding: 0 5px;
  border-radius: 999px;
  margin-left: 2px;
}
.ga-pin:hover .ga-pin-label,
.ga-pin.is-edit .ga-pin-label {
  opacity: 1;
}
.ga-pin.is-edit {
  cursor: grab;
  width: 18px;
  height: 18px;
  box-shadow: 0 0 0 3px rgba(225, 29, 46, 0.25), 0 2px 4px rgba(0,0,0,0.25);
}
.ga-pin.is-edit:active { cursor: grabbing; }
.ga-stage[data-editing="true"] {
  outline: 2px dashed var(--red-500, #e11d2e);
  outline-offset: -2px;
}
.ga-edit-hint {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--red-700, var(--danger));
  text-align: center;
}
/* R36b — All-decks (whole-vessel) variant */
.ga-all-hint {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--ink-muted, #607089);
  line-height: 1.45;
}
.ga-stage.is-all-decks {
  /* Whole-page canvas is tall — let the stage grow to the canvas's natural
     height so the absolutely-positioned pins layer covers every deck.
     The page itself scrolls. */
  overflow: visible;
}
.ga-stage.is-all-decks .ga-pin.ga-pin-sm {
  width: 9px;
  height: 9px;
  border-width: 1.5px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.25);
}
.ga-stage.is-all-decks .ga-pin.ga-pin-sm::after {
  bottom: -4px;
  border-left-width: 3px;
  border-right-width: 3px;
  border-top-width: 4px;
}
.ga-stage.is-all-decks .ga-pin.ga-pin-sm:hover {
  transform: translate(-50%, -100%) scale(1.6);
}
.ga-stage.is-all-decks .ga-pin.ga-pin-sm .ga-pin-label {
  font-size: 9px;
  padding: 1px 6px;
}

/* ============================================================
   R33 P8c — LocationPicker (reusable spatial-pin field)
   Used inside the ToDo modal (and later, Inventory/Maintenance).
   Inline autocomplete + chip showing the chosen location.
   ============================================================ */
.loc-picker {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.loc-picker .loc-picker-dd {
  flex: 1 1 240px;
  min-width: 200px;
  padding: 8px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 14px;
  background: #fff;
  color: var(--ink, #1a2538);
}
.loc-picker .loc-picker-dd:focus {
  outline: 2px solid var(--brand-500, #2A6DD4);
  outline-offset: 1px;
}
.loc-picker input[type="text"] {
  flex: 1 1 220px;
  min-width: 180px;
  padding: 8px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 14px;
  background: #fff;
}
.loc-picker input[type="text"]:focus {
  outline: 2px solid var(--brand-500, #2A6DD4);
  outline-offset: 1px;
}
.loc-picker-map {
  white-space: nowrap;
}
.loc-picker-results {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(52, 85, 120, 0.12);
  z-index: 30;
  max-height: 280px;
  overflow-y: auto;
}
.loc-picker-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--navy-50, #EEF2F8);
  padding: 8px 12px;
  text-align: left;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink, #1a2538);
}
.loc-picker-row:last-child { border-bottom: 0; }
.loc-picker-row:hover { background: var(--navy-50, #EEF2F8); }
.loc-picker-row strong { font-size: 13px; font-weight: 600; }
.loc-picker-row span {
  font-size: 11px;
  color: var(--ink-muted, #607089);
  text-transform: capitalize;
}
.loc-picker-empty {
  padding: 10px 12px;
  font-size: 12px;
  color: var(--ink-muted, #607089);
}
.loc-picker-empty-hint {
  flex: 1 1 100%;
  margin-top: 4px;
  padding: 8px 10px;
  background: var(--amber-50, #FFF7E6);
  border: 1px solid var(--amber-200, #FACC8A);
  border-radius: 6px;
  font-size: 12px;
  color: var(--amber-800, #8a5a05);
  line-height: 1.4;
}
.loc-picker-empty-hint code {
  background: rgba(0,0,0,0.06);
  padding: 1px 4px;
  border-radius: 4px;
  font-size: 11px;
}
.loc-picker-selected {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.loc-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  background: var(--navy-50, #EEF2F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 16px;
  font-size: 13px;
  color: var(--ink, #1a2538);
}
.loc-chip span { line-height: 1; }

/* Small location chip on each todo row — taps through to the GA viewer. */
.todo-loc-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: var(--navy-50, #EEF2F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  font-size: 11px;
  color: var(--ink-muted, #607089);
  cursor: pointer;
  white-space: nowrap;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.todo-loc-chip:hover {
  background: var(--brand-50, #E5EEFA);
  color: var(--brand-700, #1B4FAD);
  border-color: var(--brand-200, #B7CDF0);
}

/* "Pick a spot on the GA" map modal — zoom + pan viewport. */
.loc-map-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.loc-map-toolbar select {
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
}
.loc-map-zoom-ctrls {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 4px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  background: #fff;
}
.loc-map-zoom-ctrls .btn {
  min-width: 32px;
  padding: 4px 8px;
  font-weight: 600;
}
.loc-map-zoom-val {
  display: inline-block;
  min-width: 48px;
  text-align: center;
  font-size: 12px;
  color: var(--ink-muted, #607089);
  font-variant-numeric: tabular-nums;
}
.loc-map-viewport {
  position: relative;
  width: 100%;
  max-height: 75vh;
  overflow: hidden;
  background: var(--navy-50, #EEF2F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  touch-action: none;       /* let our pinch handler take wheel/touch */
  cursor: crosshair;
}
.loc-map-stage {
  position: relative;
  display: block;
  width: 100%;
  transform-origin: 0 0;
  transition: transform 60ms ease-out;
  user-select: none;
  -webkit-user-drag: none;
}
.loc-map-stage img,
.loc-map-stage canvas.loc-map-canvas {
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}
.loc-map-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: var(--ink-muted, #607089);
  background: rgba(255,255,255,0.85);
  pointer-events: none;
}
/* R36 — error state replaces the loading overlay when PDF.js fails. */
.loc-map-loading.is-error {
  background: rgba(255, 251, 235, 0.96);
  pointer-events: auto;
  padding: 24px;
}
.loc-map-error {
  max-width: 560px;
  text-align: center;
}
.loc-map-error-title {
  font-size: 16px;
  font-weight: 600;
  color: #8A5A05;
  margin-bottom: 8px;
}
.loc-map-error-msg {
  font-size: 12px;
  color: #78501e;
  background: #fff;
  border: 1px solid #FACC8A;
  border-radius: 6px;
  padding: 8px 10px;
  margin: 0 auto 14px;
  word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  line-height: 1.5;
}
.loc-map-error-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ============================================================
   R32 — Printable Purchase Order matching the master template
   (270426 - MYN2-PO-MASTER). Navy header bars, two-column
   tables, signature row at the bottom.
   ============================================================ */
.po-print-doc {
  background: #fff;
  max-width: 820px;
  margin: 0 auto;
  padding: 28px 32px 36px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-family: 'Helvetica Neue', Arial, sans-serif;
  color: #38617A;
  box-shadow: 0 4px 16px rgba(52, 85, 120, 0.08);
}
.po-print-logo {
  text-align: center;
  margin-bottom: 4px;
}
.po-print-logo img {
  max-height: 60px;
  width: auto;
}
.po-print-title {
  text-align: center;
  font-size: 22px;
  font-weight: 700;
  color: #38617A;
  margin: 6px 0 18px;
  letter-spacing: 0.01em;
}
.po-print-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 14px;
  font-size: 11px;
  table-layout: fixed;
}
.po-print-table th {
  background: #38617A;
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: 10.5px;
  text-align: center;
  padding: 5px 6px;
  border: 1px solid #38617A;
}
.po-print-table td {
  border: 1px solid #B8C4D2;
  padding: 8px 10px;
  vertical-align: middle;
  background: #fff;
}

/* Header (Department · Issued by · Date) */
.po-print-header td {
  text-align: center;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 10px;
}

/* Items table */
.po-print-items th.po-pr-col-code { width: 22%; }
.po-print-items th.po-pr-col-desc { width: 50%; }
.po-print-items th.po-pr-col-amt  { width: 28%; text-align: right; padding-right: 12px; }
.po-pr-cell-code {
  font-size: 10.5px;
  color: #38617A;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.35;
}
/* R32 — stacked rendering inside the ITEMS column: bare code on the
   first line in monospace, then the human-readable group:sub label
   on a second line. So a row reads "5023-0005 / Deck: Equipment /
   Spare Parts" without overflowing a narrow column. */
.po-pr-cell-code .po-pr-code-num {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700;
  font-size: 10.5px;
  color: #38617A;
}
.po-pr-cell-code .po-pr-code-label {
  display: block;
  font-weight: 400;
  font-size: 9.5px;
  color: #555;
  margin-top: 1px;
  line-height: 1.3;
}
.po-pr-cell-desc {
  font-size: 11px;
  color: #38617A;
}
.po-pr-cell-amt {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: 11px;
}
.po-pr-pay-label {
  text-align: right;
  background: #fff;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #38617A;
  font-size: 10.5px;
}
.po-pr-pay-currency {
  background: #E5EBF1;
  text-align: center;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #38617A;
}
.po-pr-grand td {
  border-top: 2px solid #38617A;
}
.po-pr-grand-label {
  display: block;
  text-align: right;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #38617A;
  font-size: 11px;
}
.po-pr-grand td:first-child { border-right: none; }
.po-pr-grand-amt {
  font-weight: 700;
  font-size: 13px;
  background: #fff;
}
.po-pr-usd-label {
  text-align: right;
  font-style: italic;
  color: #555;
  font-size: 10.5px;
}
.po-pr-usd-amt {
  font-style: italic;
  color: #555;
  font-size: 11px;
}

/* Recipient / Payment row */
.po-print-recipient {
  table-layout: fixed;
}
.po-print-recipient th { width: 33.33%; }
.po-pr-recipient-name {
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 16px 12px !important;
}
.po-pr-payment-row {
  text-align: center;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
}
.po-pr-due {
  text-align: left;
  font-size: 10.5px;
  background: #fff;
}
.po-pr-due strong {
  background: #38617A;
  color: #fff;
  padding: 2px 8px;
  border-radius: 2px;
  letter-spacing: 0.04em;
  font-size: 10px;
}

/* Banking + delivery address (4-column row) */
.po-print-banking { table-layout: fixed; }
.po-print-banking th:nth-child(1),
.po-print-banking th:nth-child(2) { width: 25%; }
.po-print-banking th:nth-child(3),
.po-print-banking th:nth-child(4) { width: 50%; }
.po-pr-bank-label {
  font-style: italic;
  color: #555;
  font-size: 10.5px;
  width: 35%;
}
.po-pr-bank-val {
  font-size: 11px;
  font-weight: 500;
}
.po-pr-delivery {
  text-align: center;
  font-size: 11px;
  font-style: italic;
  color: #38617A;
  padding: 14px;
  vertical-align: middle;
}

/* Notes */
.po-print-notes {
  margin: 6px 0 14px;
  padding: 10px 12px;
  background: #fafbfc;
  border: 1px solid #B8C4D2;
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.5;
  color: #333;
}
.po-print-notes strong {
  display: inline-block;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: #555;
  margin-bottom: 4px;
}

/* Signatures */
.po-print-signatures th { width: 33.33%; }
.po-pr-sig-cell {
  height: 64px;
  background: #fff;
  text-align: center;
  vertical-align: middle;
}
/* R38 — typed signatures rendered in a script-style face */
.po-pr-sig-typed {
  font-family: 'Brush Script MT', 'Lucida Handwriting', 'Apple Chancery', cursive;
  font-size: 22px;
  color: #284558;
  letter-spacing: 0.5px;
}
.po-pr-sig-date td {
  background: #38617A;
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 5px 10px;
}
.po-pr-date-label {
  background: #fff;
  color: #38617A;
  padding: 1px 6px;
  border-radius: 2px;
  font-weight: 700;
}

/* DEMO watermark removed 2026-05-09 — real data is in the Finance
   tables now (build-budget wires + Wise card transactions imported). */

/* Print rules — R32: tuned to fit on a single A4 portrait page.
   - Compact paddings on every row so 6 line items + payment block +
     recipient + banking + notes + signatures all fit in one page.
   - @page sets a small fixed margin so we use the full sheet area.
   - page-break-inside on each block keeps related rows together.
   - The whole document is also slightly scaled down as a safety net. */
@page {
  size: A4 portrait;
  margin: 8mm 10mm;
}
@media print {
  body.printable-report {
    background: #fff !important;
  }
  body.printable-report .po-print-doc {
    border: 0;
    box-shadow: none;
    padding: 0;
    max-width: none;
    margin: 0 auto;
  }
  body.printable-report .po-print-logo {
    margin: 0 0 2px;
  }
  body.printable-report .po-print-logo img { max-height: 38px; }
  body.printable-report .po-print-title {
    font-size: 15px;
    margin: 2px 0 8px;
  }
  body.printable-report .po-print-table {
    page-break-inside: avoid;
    margin-bottom: 6px;
    font-size: 9.5px;
  }
  body.printable-report .po-print-table th {
    padding: 3px 5px;
    font-size: 9px;
  }
  body.printable-report .po-print-table td {
    padding: 3px 6px;
    font-size: 9.5px;
  }
  body.printable-report .po-print-header td {
    padding: 5px;
    font-size: 10.5px;
  }
  body.printable-report .po-pr-cell-code .po-pr-code-num { font-size: 9px; }
  body.printable-report .po-pr-cell-code .po-pr-code-label { font-size: 8px; }
  body.printable-report .po-pr-recipient-name {
    padding: 9px 10px !important;
    font-size: 12px;
  }
  body.printable-report .po-pr-grand-amt { font-size: 11px; }
  body.printable-report .po-pr-delivery {
    font-size: 9.5px;
    padding: 8px;
  }
  body.printable-report .po-print-notes {
    margin: 4px 0 6px;
    padding: 5px 8px;
    font-size: 9px;
    line-height: 1.4;
    page-break-inside: avoid;
  }
  body.printable-report .po-pr-sig-cell {
    height: 40px;
  }
  body.printable-report .po-pr-sig-date td {
    font-size: 8.5px;
    padding: 3px 8px;
  }
  body.printable-report .po-print-signatures {
    page-break-inside: avoid;
    page-break-before: avoid;
  }
  /* Fall-back safety: if the content still pushes past one page on
     unusual locales / fonts, scale the whole doc down a touch. The
     scale-origin keeps the top-left anchored so margins stay clean. */
  body.printable-report .po-print-doc {
    transform-origin: top center;
  }
}

/* R96 — html2canvas (used by Finance.downloadPoPdf) does NOT honour
   @media print, so we replicate the same compaction rules under a
   class toggle. downloadPoPdf adds body.po-pdf-rendering for the
   duration of the capture; the rules below mirror the @media print
   block above so the PDF fits a single A4 portrait page. */
body.po-pdf-rendering .po-print-doc {
  border: 0;
  box-shadow: none;
  padding: 0;
  max-width: none;
  margin: 0 auto;
  background: #fff;
}
body.po-pdf-rendering .po-print-logo {
  margin: 0 0 2px;
}
body.po-pdf-rendering .po-print-logo img { max-height: 38px; }
body.po-pdf-rendering .po-print-title {
  font-size: 15px;
  margin: 2px 0 8px;
}
body.po-pdf-rendering .po-print-table {
  margin-bottom: 6px;
  font-size: 9.5px;
}
body.po-pdf-rendering .po-print-table th {
  padding: 3px 5px;
  font-size: 9px;
}
body.po-pdf-rendering .po-print-table td {
  padding: 3px 6px;
  font-size: 9.5px;
}
body.po-pdf-rendering .po-print-header td {
  padding: 5px;
  font-size: 10.5px;
}
body.po-pdf-rendering .po-pr-cell-code .po-pr-code-num { font-size: 9px; }
body.po-pdf-rendering .po-pr-cell-code .po-pr-code-label { font-size: 8px; }
body.po-pdf-rendering .po-pr-recipient-name {
  padding: 9px 10px !important;
  font-size: 12px;
}
body.po-pdf-rendering .po-pr-grand-amt { font-size: 11px; }
body.po-pdf-rendering .po-pr-delivery {
  font-size: 9.5px;
  padding: 8px;
}
body.po-pdf-rendering .po-print-notes {
  margin: 4px 0 6px;
  padding: 5px 8px;
  font-size: 9px;
  line-height: 1.4;
}
body.po-pdf-rendering .po-pr-sig-cell {
  height: 40px;
}
body.po-pdf-rendering .po-pr-sig-date td {
  font-size: 8.5px;
  padding: 3px 8px;
}
/* Hide the on-screen action buttons (Back / Print / Download) during
   capture so they don't end up rasterised into the PDF. The .no-print
   class is already applied by renderPrintablePo. */
body.po-pdf-rendering .no-print { display: none !important; }

/* ============================================================
   R31 P7e — Printable monthly card report
   ============================================================ */
.card-report-page {
  max-width: 900px;
  margin: 0 auto;
  padding: 24px;
}
.card-report-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-bottom: 16px;
}
.card-report-document {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 36px 40px;
  font-family: Georgia, 'Times New Roman', serif;
  color: #4A7791;
  box-shadow: 0 4px 16px rgba(52, 85, 120, 0.08);
}
.report-tile {
  background: #fafbfc;
  border: 1px solid #e5eaf0;
  border-radius: 6px;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.report-tile-label {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #666;
  font-family: -apple-system, sans-serif;
}
.report-tile-value {
  font-size: 18px;
  font-weight: 700;
  color: #4A7791;
  font-family: -apple-system, sans-serif;
}
.report-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-family: -apple-system, sans-serif;
}
.report-table th {
  text-align: left;
  padding: 6px 10px;
  background: #f7f9fc;
  border-bottom: 1px solid #ccc;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #4A7791;
}
.report-table td {
  padding: 6px 10px;
  border-bottom: 1px solid #eee;
  vertical-align: top;
}
.report-table tbody tr:last-child td { border-bottom: 0; }

/* ============================================================
   R30 P6b — Suppliers
   ============================================================ */
.suppliers-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 8px 0 16px;
}
.suppliers-toolbar input[type="search"] {
  flex: 1;
  max-width: 480px;
  padding: 8px 12px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 13px;
}
.suppliers-grid {
  display: grid;
  /* R129 — min(320px, 100%) prevents the 320px floor from forcing horizontal page scroll when the container is narrower (iPhone SE etc.). */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 12px;
}
.supplier-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
  border-left: 4px solid var(--navy-700);
}
.supplier-card:hover {
  border-color: var(--navy-700);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(52, 85, 120, 0.08);
}
.supplier-card.is-inactive {
  opacity: 0.55;
  border-left-color: var(--ink-muted, #64748b);
}
.supplier-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 4px;
  font-size: 14px;
  color: var(--navy-900);
}
.supplier-card-meta {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  margin-bottom: 8px;
  line-height: 1.4;
}
.supplier-card-bank {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11px;
  color: var(--navy-700);
  font-family: ui-monospace, monospace;
  word-break: break-all;
}
.supplier-card-bank span strong {
  color: var(--ink-muted, #64748b);
  font-weight: 600;
  font-family: -apple-system, sans-serif;
  margin-right: 4px;
}

/* R30 P6c/P6d — drop-to-scan zones inside Supplier + PO modals */
.supplier-scan-zone {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 8px 24px 16px;
  padding: 14px 16px;
  background: linear-gradient(135deg, rgba(31,77,143,0.04), rgba(225,29,46,0.04));
  border: 2px dashed var(--navy-100, #DCE7ED);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.supplier-scan-zone:hover,
.supplier-scan-zone.is-over {
  border-color: var(--navy-700);
  background: linear-gradient(135deg, rgba(31,77,143,0.08), rgba(225,29,46,0.06));
}
.supplier-scan-icon {
  font-size: 24px;
  flex-shrink: 0;
}
.supplier-scan-zone strong {
  display: block;
  font-size: 13px;
  color: var(--navy-900);
}

/* Print-mode rules: drop nav, FAB, header chrome.
   Body gets `printable-report` class while in this view. */
@media print {
  body.printable-report .portal-header,
  body.printable-report .portal-nav,
  body.printable-report .messages-fab,
  body.printable-report .assistant-fab,
  body.printable-report .messages-fab-panel,
  body.printable-report .assistant-panel,
  body.printable-report .notif-panel,
  body.printable-report .no-print {
    display: none !important;
  }
  body.printable-report .card-report-document {
    border: 0;
    box-shadow: none;
    padding: 0;
  }
  body.printable-report .card-report-page {
    padding: 0;
    max-width: none;
  }
}

/* Mobile: stack the rail above the thread, rail becomes scrollable
   horizontal-ish list. We keep it simple and just collapse to one
   column; the empty state hides automatically once a conv is open. */
@media (max-width: 720px) {
  .messages-shell {
    grid-template-columns: 1fr;
    height: calc(100vh - 180px);
    height: calc(100dvh - 180px);
  }
  .messages-rail {
    border-right: 0;
    border-bottom: 1px solid var(--navy-100, #DCE7ED);
    max-height: 220px;
  }
}

/* ============================================================
   MAINTENANCE — equipment register + service log
   ============================================================ */
.maint-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 12px;
}
.maint-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
  border-left: 4px solid var(--navy-700);
}
.maint-card:hover { border-color: var(--navy-700); transform: translateY(-1px); box-shadow: 0 4px 14px rgba(52, 85, 120, 0.08); }
.maint-card.due-soon { border-left-color: #b45309; }
.maint-card.overdue  { border-left-color: var(--red-500); }
.maint-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.maint-card-head h3 { margin: 0; font-size: 15px; color: var(--navy-900); font-weight: 700; }
.maint-card-meta { font-size: 12px; color: var(--ink-muted, #64748b); }
.maint-card-system {
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--navy-700);
  background: rgba(76, 115, 133, 0.06);
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 600;
  display: inline-block;
}
.maint-due {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 600;
}
.maint-due.ok       { background: rgba(22, 101, 52, 0.10); color: var(--success); }
.maint-due.due-soon { background: rgba(180, 83, 9, 0.12); color: #92400e; }
.maint-due.overdue  { background: rgba(225, 29, 46, 0.12); color: var(--red-700); }
.maint-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: 6px; }
.maint-services {
  margin-top: 8px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 8px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
}
.maint-services .ms-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0;
}

/* ============================================================
   GLOBAL SEARCH (Cmd+K)
   ============================================================ */
.gs-modal {
  position: fixed; inset: 0;
  background: rgba(40, 69, 88, 0.55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh 16px 16px;
  z-index: 2100;
}
.gs-modal.hidden { display: none; }
.gs-card {
  width: min(640px, 100%);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(52, 85, 120, 0.4);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.gs-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.gs-head input {
  flex: 1;
  border: 0;
  outline: 0;
  font: inherit;
  font-size: 16px;
  background: transparent;
  color: var(--navy-900);
}
.gs-head .gs-icon { display: inline-flex; color: var(--ink-muted, #64748b); }
.gs-head .gs-icon .ic { width: 18px; height: 18px; }
.gs-results {
  max-height: 50vh;
  overflow-y: auto;
}
.gs-result {
  display: flex;
  gap: 10px;
  padding: 10px 16px;
  cursor: pointer;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  transition: background 0.08s;
}
.gs-result:hover, .gs-result.active { background: var(--cream, #faf6f0); }
.gs-result-kind {
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--navy-700);
  background: rgba(76, 115, 133, 0.06);
  padding: 2px 6px;
  border-radius: 4px;
  height: fit-content;
  white-space: nowrap;
}
.gs-result-body { flex: 1; min-width: 0; }
.gs-result-title { font-size: 14px; color: var(--navy-900); font-weight: 500; }
.gs-result-sub { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 2px; }
.gs-foot {
  padding: 8px 16px;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
  display: flex;
  justify-content: space-between;
}
.gs-foot kbd {
  display: inline-block;
  padding: 1px 5px;
  font-family: var(--sans);
  font-size: 10px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 3px;
  color: var(--navy-800);
}

@media (max-width: 720px) {
  #vessel-map { height: 260px; }
  .vessel-tracker-head { flex-direction: column; }
}

/* AIS connection status pill (live / cached / reconnecting / not configured).
   Dot animates when actively polling so a glance tells you the state. */
.ais-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  margin-left: 8px;
}
.ais-status .ais-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ink-muted, #94a3b8);
  flex-shrink: 0;
  position: relative;
}
.ais-status.live .ais-dot {
  background: var(--success);
  box-shadow: 0 0 0 0 rgba(22, 101, 52, 0.7);
  animation: aisPulse 1.6s ease-out infinite;
}
.ais-status.cached .ais-dot { background: #b45309; }
.ais-status.reconnecting .ais-dot {
  background: var(--red-500);
  animation: aisBlink 0.8s ease-in-out infinite;
}
.ais-status.unconfigured { background: rgba(180, 83, 9, 0.08); border-color: rgba(180, 83, 9, 0.3); color: #92400e; cursor: pointer; }
.ais-status.unconfigured:hover { background: rgba(180, 83, 9, 0.14); }
.ais-status .ais-action {
  font-size: 11px;
  background: transparent;
  border: 0;
  color: var(--navy-700);
  text-decoration: underline;
  cursor: pointer;
  padding: 0 0 0 4px;
  font: inherit;
  font-size: 11px;
  font-weight: 500;
}
.ais-status .ais-action:hover { color: var(--red-500); }
@keyframes aisPulse {
  0%   { box-shadow: 0 0 0 0 rgba(22, 101, 52, 0.6); }
  70%  { box-shadow: 0 0 0 6px rgba(22, 101, 52, 0); }
  100% { box-shadow: 0 0 0 0 rgba(22, 101, 52, 0); }
}
@keyframes aisBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* Auto-detected port-info source tag */
.port-info-block .pi-source {
  display: inline-block;
  font-size: 9px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(76, 115, 133, 0.06);
  color: var(--navy-700);
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 6px;
  font-weight: 600;
  vertical-align: 1px;
}
.port-info-block .pi-source.auto    { background: rgba(22, 101, 52, 0.10); color: var(--success); }
.port-info-block .pi-source.manual  { background: rgba(76, 115, 133, 0.10); color: var(--navy-800); }
.port-info-block .pi-source.country { background: rgba(245, 158, 11, 0.15); color: #92400e; }
.port-info-foot {
  margin-top: 12px;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 10px;
}
.port-info-foot a { text-decoration: underline; }

/* ============================================================
   KIOSK HEADER NAV (logged-in users only)
   Same dropdowns as the portal nav, restyled for the dark kiosk header.
   ============================================================ */
.kiosk-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 24px;
}
.kiosk-nav.hidden { display: none; }
.kiosk-nav > a,
.kiosk-nav .nav-trigger {
  background: none !important;
  border: none;
  color: rgba(255,255,255,0.85) !important;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.3px;
  padding: 8px 12px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex !important;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  border-radius: 4px;
  appearance: none;
}
.kiosk-nav > a:hover,
.kiosk-nav .nav-trigger:hover {
  background: rgba(255,255,255,0.08) !important;
  color: #fff !important;
}
.kiosk-nav > a.active {
  background: rgba(225,29,46,0.18) !important;
  color: #fff !important;
}
.kiosk-nav .nav-trigger .caret { display: inline-flex; align-items: center; opacity: 0.7; transition: transform 0.18s var(--ease-precise); }
.kiosk-nav .nav-trigger .caret .ic { width: 12px; height: 12px; }
.kiosk-nav .nav-dropdown { position: relative; }
.kiosk-nav .nav-dropdown.open .nav-trigger {
  background: rgba(255,255,255,0.08) !important;
}
.kiosk-nav .nav-dropdown.open .nav-trigger .caret { transform: rotate(180deg); }

/* Dropdown menus inside the kiosk nav: white card on dark header */
.kiosk-nav .nav-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 220px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.35);
  padding: 6px;
  z-index: 200;
  display: none;
}
.kiosk-nav .nav-dropdown.open .nav-menu { display: block; }
.kiosk-nav .nav-menu a {
  display: block;
  padding: 10px 14px;
  font-size: 14px;
  color: var(--ink);
  border-radius: 4px;
  text-decoration: none;
  white-space: nowrap;
  background: transparent !important;
}
.kiosk-nav .nav-menu a:hover {
  background: var(--cream) !important;
  color: var(--navy-800) !important;
}

/* On smaller iPads / phones, collapse the kiosk nav into icons-only style */
@media (max-width: 720px) {
  .kiosk-nav { margin-left: 8px; gap: 2px; }
  .kiosk-nav > a,
  .kiosk-nav .nav-trigger { padding: 6px 8px; font-size: 12px; }
}

/* Kiosk wordmark as a Home link (logged-in users only) */
.kiosk-brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  cursor: pointer;
  border-radius: 4px;
  padding: 4px 6px;
  transition: background 0.12s, opacity 0.12s;
}
.kiosk-brand:hover { background: rgba(255,255,255,0.06); }

/* ============================================================
   VESSEL CERTIFICATES
   Page header, summary KPIs, filter chips, certificate cards,
   upload form + full-screen preview modal.
   Reuses existing tokens: --navy-*, --red-*, --success/warn/danger,
   .modal/.modal-card, .btn-*, .status-pill {ok|s30|s90|expired|no-expiry}.
   ============================================================ */
.certs-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
}

/* --- Summary tiles ------------------------------------------------- */
/* R32 — `.cert-kpis` was being used in HTML but had no CSS, so finance
   tiles were stacking full-width. Added it as an alias for the existing
   `.cert-summary` 4-up grid so every "row of KPI tiles" looks the same
   regardless of which class the page used. */
.cert-summary,
.cert-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 18px 0 22px;
}
.cert-kpi {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
  text-align: left;
  font: inherit;
  color: inherit;
}
.cert-kpi:hover { border-color: var(--navy-700); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(52, 85, 120, 0.06); }
.cert-kpi.active { border-color: var(--navy-800); box-shadow: inset 0 0 0 1px var(--navy-800); }
.cert-kpi-label { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted, #64748b); }
/* R32 — uniform value font-size across every KPI tile (short labels
   like "116" + long money strings like "7,842,042.50 USD" all sit at
   the same 22px). Was 28px which made money values overflow. */
.cert-kpi-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
  /* Long strings shrink to fit within the tile, never break out */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Money tiles already inherit size from .cert-kpi-value above. Keep
   the class so JS that adds it for typographic intent still works. */
.cert-kpi-money { font-variant-numeric: tabular-nums; }

/* R32 — stacked multi-currency tile: when a tile holds multiple
   currency totals, each lands on its own line. Removes the
   nowrap/ellipsis from the parent so all lines stay readable. */
.cert-kpi-stack {
  display: flex;
  flex-direction: column;
  white-space: normal !important;
  overflow: visible !important;
  text-overflow: clip !important;
  font-size: 17px !important;
  line-height: 1.2;
  gap: 1px;
}
.kpi-money-line {
  display: block;
  white-space: nowrap;
}
.cert-kpi.kpi-warn  .cert-kpi-value { color: #b45309; }
.cert-kpi.kpi-danger .cert-kpi-value { color: var(--red-700); }
.cert-kpi.kpi-ok    .cert-kpi-value { color: var(--success); }
.cert-kpi-sub { font-size: 12px; color: var(--ink-muted, #64748b); }

@media (max-width: 720px) {
  .cert-summary, .cert-kpis { grid-template-columns: repeat(2, 1fr); }
  .cert-kpi-value { font-size: 19px; }
}

/* R112 — Compact KPI strip for Card Transactions view. Default
   .cert-kpis tiles are oversized for 5 tiles; this variant fits
   them all on one horizontal row and cuts vertical real estate
   roughly in half so the table sits higher. Same data, tighter
   padding + fonts, auto-fit grid for narrow widths. */
.cards-kpis {
  display: grid;
  /* 130px floor lets the 5-tile set (incl. USD anchor) sit on one
     row at ~700px and stay one row at every common desktop width. */
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
  margin: 12px 0 14px;
}
.cards-kpis .cert-kpi {
  padding: 8px 12px;
  gap: 2px;
  border-radius: 8px;
  cursor: default;
}
.cards-kpis .cert-kpi:hover { transform: none; box-shadow: none; border-color: var(--navy-100, #DCE7ED); }
.cards-kpis .cert-kpi-label { font-size: 10px; }
.cards-kpis .cert-kpi-value { font-size: 16px; }
.cards-kpis .cert-kpi-stack { font-size: 13px !important; }
.cards-kpis .cert-kpi-sub   { font-size: 10px; }

/* --- Filter / sort toolbar ---------------------------------------- */
.cert-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.cert-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* R122 — To-Do tab strip + per-dept list-chip strip should run across the
   page on a single line. They wrap if the viewport is narrower than the
   chips, which (on the desktop module) clumped them at the left and read
   as cramped. nowrap + horizontal scroll keeps every chip reachable and
   visually anchored to the full module width. Scrollbar fades to nothing
   on macOS / iOS by default; the rule below thins it on other platforms. */
#todos-tabs,
#todos-lists {
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(52, 85, 120, 0.18) transparent;
  -webkit-overflow-scrolling: touch;
  /* Leave a hair of bottom padding so the focus-ring on chips isn't
     clipped by the scroll container. */
  padding-bottom: 2px;
}
#todos-tabs::-webkit-scrollbar,
#todos-lists::-webkit-scrollbar {
  height: 6px;
}
#todos-tabs::-webkit-scrollbar-thumb,
#todos-lists::-webkit-scrollbar-thumb {
  background: rgba(52, 85, 120, 0.18);
  border-radius: 999px;
}
/* Chips inside these strips should never shrink below their natural
   width — otherwise text gets clipped in narrow scroll containers. */
#todos-tabs .cert-chip,
#todos-lists .cert-chip {
  flex-shrink: 0;
  white-space: nowrap;
}

/* R124 — Department tab strip uses a slightly darker neutral than the
   list-pill strip below so the two rows read as parent / child.
   Active tab is unchanged (still inverts to navy). */
#todos-tabs .cert-chip {
  background: #E4E9EE;
  border-color: #CED5DD;
}
#todos-tabs .cert-chip:hover {
  border-color: var(--navy-700);
}
#todos-tabs .cert-chip.active {
  background: var(--navy-800);
  border-color: var(--navy-800);
  color: #fff;
}

/* R123 — Group dropdown pill. Multiple lists with the same group_name
   collapse into a single parent chip with a ▾ caret; clicking expands a
   popover of child chips. The popover renders as a body-attached
   fixed-position element (.cert-chip-group-menu--floating) so the chip
   strip's overflow doesn't clip it. (overflow-x:auto forces overflow-y
   to auto per CSS spec — a normal absolute-positioned dropdown got
   cropped under the strip.) */
.cert-chip-group {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
}
.cert-chip-group .cert-chip-caret {
  display: inline-block;
  margin-left: 2px;
  font-size: 11px;
  opacity: 0.7;
  transition: transform 0.15s;
}
.cert-chip-group.is-open .cert-chip-caret {
  transform: rotate(180deg);
}
.cert-chip-group-menu {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(40, 69, 88, 0.14),
              0 2px 6px rgba(40, 69, 88, 0.08);
  z-index: 1500;
  max-width: min(640px, 90vw);
}
/* Floating variant lives on <body>; coordinates set in JS at click time
   via getBoundingClientRect. Sits above the chip strip's stacking
   context regardless of its overflow rules. */
.cert-chip-group-menu--floating {
  position: fixed;
}
.cert-chip-group-menu[hidden] {
  display: none;
}
.cert-chip {
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  color: var(--navy-800);
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.cert-chip:hover { border-color: var(--navy-700); }
.cert-chip.active {
  background: var(--navy-800);
  border-color: var(--navy-800);
  color: #fff;
}
.cert-chip-count {
  margin-left: 6px;
  opacity: 0.7;
  font-weight: 400;
}
.cert-sort {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-muted, #64748b);
}
.cert-sort select {
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  background: #fff;
  font: inherit;
  color: var(--navy-900);
}

/* --- Certificate cards -------------------------------------------- */
.cert-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}
.cert-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
  position: relative;
}
.cert-card:hover {
  border-color: var(--navy-700);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(52, 85, 120, 0.08);
}
.cert-card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
}
.cert-card-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.25;
  margin: 0;
}
.cert-card-cat {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--navy-700);
  background: rgba(76, 115, 133, 0.06);
  padding: 3px 8px;
  border-radius: 999px;
  margin-bottom: 8px;
  font-weight: 600;
}
.cert-card-meta {
  font-size: 13px;
  color: var(--ink-muted, #64748b);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cert-card-meta .cert-meta-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.cert-card-meta .cert-meta-key {
  color: var(--ink-muted, #64748b);
  font-weight: 500;
}
.cert-card-meta .cert-meta-val {
  color: var(--navy-900);
  text-align: right;
  font-feature-settings: 'tnum' 1;
}
.cert-card-file {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 10px;
}
.cert-card-file-icon {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  background: var(--red-100);
  color: var(--red-700);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.cert-card-file.no-file .cert-card-file-icon {
  background: rgba(0,0,0,0.05);
  color: var(--ink-muted, #64748b);
}
.cert-card-actions {
  display: flex;
  gap: 8px;
  margin-top: auto;
  flex-wrap: wrap;
}
.cert-card-actions .btn { flex: 1 1 auto; min-width: 0; }
.cert-card-actions .btn-icon {
  flex: 0 0 auto;
  padding: 7px 10px;
  font-size: 13px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  color: var(--navy-800);
  border-radius: 6px;
  cursor: pointer;
}
.cert-card-actions .btn-icon:hover { border-color: var(--navy-700); }
.cert-card-actions .btn-icon.danger:hover { border-color: var(--danger); color: var(--danger); }

/* --- Empty state -------------------------------------------------- */
.cert-empty {
  background: #fff;
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 36px 24px;
  text-align: center;
  margin-top: 16px;
}
.cert-empty-crest {
  width: 110px;
  opacity: 0.6;
  margin-bottom: 10px;
}
.cert-empty h2 {
  margin: 0 0 6px;
  font-size: 20px;
  color: var(--navy-900);
}
.cert-empty p { color: var(--ink-soft, #475569); max-width: 480px; margin: 0 auto 14px; }
.cert-empty-note { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 12px; }

/* --- Upload modal extras ------------------------------------------ */
.cert-upload-card { max-width: 560px; }
.cert-file-field input[type="file"] {
  display: block;
  margin-top: 6px;
  font: inherit;
  color: var(--navy-900);
}
.cert-file-meta {
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  background: rgba(76, 115, 133, 0.04);
  border-radius: 6px;
  padding: 8px 10px;
}
.cert-ai-extract {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.cert-ai-status {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
}
.cert-no-expiry {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  margin-top: 6px;
  cursor: pointer;
}
.field-hint { font-weight: 400; color: var(--ink-muted, #64748b); font-size: 12px; }

/* --- Preview modal ------------------------------------------------ */
.cert-preview-modal .modal-card.cert-preview-card {
  width: min(1100px, 96vw);
  max-width: 1100px;
  height: min(86vh, 800px);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.cert-preview-header {
  padding: 14px 18px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.cert-preview-header h3 { margin: 0; font-size: 17px; }
.cert-preview-sub {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
}
.cert-preview-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cert-preview-body {
  flex: 1;
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 0; /* lets the iframe inside actually scroll */
}
.cert-preview-meta {
  background: #f8fafc;
  border-right: 1px solid var(--navy-100, #DCE7ED);
  padding: 16px;
  overflow-y: auto;
  font-size: 13px;
}
.cert-preview-meta dl { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.cert-preview-meta dt {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.cert-preview-meta dd { margin: 2px 0 0; color: var(--navy-900); word-break: break-word; }
.cert-preview-viewer {
  background: #1f2937;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
.cert-preview-viewer iframe,
.cert-preview-viewer embed {
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
}
.cert-preview-viewer img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.cert-preview-fallback {
  color: #cbd5e1;
  text-align: center;
  padding: 32px;
  font-size: 14px;
}
.cert-preview-fallback strong { color: #fff; display: block; margin-bottom: 6px; font-size: 16px; }

@media (max-width: 720px) {
  .cert-preview-modal .modal-card.cert-preview-card {
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    border-radius: 0;
  }
  .cert-preview-body {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
  .cert-preview-meta {
    border-right: 0;
    border-bottom: 1px solid var(--navy-100, #DCE7ED);
    max-height: 35vh;
  }
}

/* ============================================================
   USER-NAME DROPDOWN (top-right of portal nav)
   Replaces the static crew name + sign-out link with a dropdown
   that hosts My Profile / Hours / Leave / Change PIN / Sign Out.
   ============================================================ */
.user-dropdown { position: relative; }
.user-trigger {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #fff;
  border-radius: 999px;
  padding: 5px 14px 5px 5px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.user-trigger:hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255,255,255,0.3); }
.user-trigger .user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--red-500);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
}
.user-trigger .caret { display: inline-flex; align-items: center; opacity: 0.7; transition: transform 0.18s var(--ease-precise); }
.user-trigger .caret .ic { width: 12px; height: 12px; }
.user-menu {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 8px;
  min-width: 240px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(52, 85, 120, 0.18);
  display: none;
  flex-direction: column;
  z-index: 50;
  overflow: hidden;
}
.user-dropdown.open .user-menu { display: flex; }
.user-menu-header {
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: #f8fafc;
}
.user-menu-header .um-name { font-weight: 700; color: var(--navy-900); display: block; }
.user-menu-header .um-role { font-size: 12px; color: var(--ink-muted, #64748b); display: block; }
/* R97 follow-up (2026-05-20) — the user menu sits inside #portal-nav,
   so a mobile @media rule on `body #portal-nav a` was painting the
   first three menu items (My profile / Hours of rest / My leave —
   all <a>) white-on-white at 16px. That rule uses !important on
   every property to enforce big mobile tap targets, so we have to
   match the cascade tier here. Selector specificity (#user-dropdown
   = 1,1,1) is already higher than `body #portal-nav a` (1,0,2);
   adding !important on the visual properties (color, font-size,
   padding, display, background) closes the gap. The <button>
   items (Request leave, Sign out) were never affected because the
   mobile rule's selector list only targets `body #portal-nav a`
   and `body #portal-nav button.nav-trigger`. */
#user-dropdown .user-menu a,
#user-dropdown .user-menu button {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  padding: 10px 14px !important;
  border: 0;
  background: transparent !important;
  text-align: left !important;
  font: inherit;
  font-size: 13px !important;
  color: var(--navy-800) !important;
  cursor: pointer;
  text-decoration: none !important;
  width: 100% !important;
  /* Reset the mobile-nav decorations the offending rule layers on. */
  min-height: 0 !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
  border-radius: 0 !important;
  margin-bottom: 0 !important;
  text-shadow: none !important;
}
#user-dropdown .user-menu a:hover,
#user-dropdown .user-menu button:hover { background: var(--cream, #faf6f0) !important; color: var(--navy-900) !important; }
#user-dropdown .user-menu .um-divider { height: 1px; background: var(--navy-100, #DCE7ED); margin: 4px 0; }
#user-dropdown .user-menu .um-icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--ink-soft);
}
#user-dropdown .user-menu .um-icon .ic { width: 16px; height: 16px; vertical-align: middle; }
#user-dropdown .user-menu .um-signout .um-icon { color: var(--danger) !important; }
#user-dropdown .user-menu .um-signout { color: var(--danger) !important; }
#user-dropdown .user-menu .um-signout:hover { background: rgba(225, 29, 46, 0.08) !important; color: var(--red-700) !important; }

@media (max-width: 720px) {
  .user-trigger { padding: 4px 12px 4px 4px; font-size: 12px; }
  .user-trigger .user-avatar { width: 24px; height: 24px; font-size: 11px; }
  .user-menu { right: -8px; min-width: 220px; }
}

/* ============================================================
   GENERIC KPI / TOOLBAR / EMPTY-STATE TOKENS  (shared)
   The vessel-cert page introduced these patterns; this block
   makes them reusable by Crew Tracker, Drills, Cruises etc.
   ============================================================ */
.module-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 18px 0 22px;
}
@media (max-width: 720px) { .module-summary { grid-template-columns: repeat(2, 1fr); } }
.module-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.module-empty {
  background: #fff;
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 36px 24px;
  text-align: center;
  margin-top: 16px;
}
.module-empty h2 { margin: 0 0 6px; font-size: 18px; color: var(--navy-900); text-transform: uppercase; letter-spacing: 0.02em; }
.module-empty p { color: var(--ink-soft, #475569); max-width: 480px; margin: 0 auto 14px; }
.module-empty .mod-empty-note { font-size: 12px; color: var(--ink-muted, #64748b); }

/* ============================================================
   CREW TRACKER — leave + on-board status board
   ============================================================ */
.tracker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.tracker-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: border-color 0.12s;
}
.tracker-row:hover { border-color: var(--navy-700); }
.tracker-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--navy-700);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
}
.tracker-row-body { flex: 1; min-width: 0; }
.tracker-name { font-weight: 600; color: var(--navy-900); font-size: 14px; line-height: 1.2; }
.tracker-meta { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 2px; }

.tracker-status-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.tracker-status-pill.onboard   { background: rgba(22, 101, 52, 0.12); color: var(--success); }
.tracker-status-pill.shore     { background: rgba(76, 115, 133, 0.06); color: var(--navy-700); }
.tracker-status-pill.leave     { background: rgba(180, 83, 9, 0.15); color: #92400e; }
.tracker-status-pill.sick      { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.tracker-status-pill.unapproved{ background: rgba(225, 29, 46, 0.18); color: var(--red-700); border: 1px dashed var(--red-700); }

/* Leave list */
.leave-list { display: flex; flex-direction: column; gap: 14px; }

/* R146 — Captain's leave-requests UX: group by department, each section
   collapsible, plus a Historic archive section that's collapsed by default. */
.leave-dept-section {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  overflow: hidden;
}
.leave-dept-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  background: #f1f5f9;
  border: 0;
  padding: 12px 16px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--navy-900);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.leave-dept-header:hover { background: #e2e8f0; }
.leave-dept-chevron {
  display: inline-block;
  width: 14px;
  color: var(--navy-700);
  font-size: 12px;
}
.leave-dept-name { flex: 1; }
.leave-dept-count {
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}
.leave-dept-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
}
.leave-dept-section.is-collapsed .leave-dept-body { display: none; }
.leave-dept-section.is-collapsed .leave-dept-header { border-bottom-color: transparent; }
/* Historic section is muted so it doesn't compete visually with active requests */
.leave-dept-section.leave-historic { opacity: 0.85; }
.leave-dept-section.leave-historic .leave-dept-header {
  background: #fafbfc;
  color: var(--ink-soft, #475569);
}
.leave-dept-section.leave-historic .leave-row {
  border-color: var(--navy-100, #DCE7ED);
  background: #fafbfc;
}
.leave-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 16px;
  align-items: start;
}
.leave-row.unapproved { border-color: var(--red-700); border-style: dashed; }
.leave-row-main { display: flex; flex-direction: column; gap: 2px; }
.leave-row-title { font-weight: 600; color: var(--navy-900); }
.leave-row-meta { font-size: 13px; color: var(--ink-muted, #64748b); }
.leave-row-reason { font-size: 13px; color: var(--ink-soft, #475569); margin-top: 4px; }
.leave-row-status {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}
.leave-row-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.leave-row-actions .btn { padding: 5px 10px; font-size: 12px; }

.leave-status-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.leave-status-pill.pending_hod      { background: rgba(180, 83, 9, 0.12); color: #92400e; }
.leave-status-pill.pending_captain  { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.leave-status-pill.approved         { background: rgba(22, 101, 52, 0.12); color: var(--success); }
.leave-status-pill.denied           { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.leave-status-pill.withdrawn        { background: rgba(0,0,0,0.06); color: var(--ink-muted, #64748b); }
.leave-status-pill.unapproved       { background: rgba(225, 29, 46, 0.16); color: var(--red-700); }
/* R110 — lifecycle-aware leave statuses set by the kiosk auto-stamp. */
.leave-status-pill.in_progress      { background: rgba(13, 148, 136, 0.16); color: #0f766e; }
.leave-status-pill.completed        { background: rgba(76, 115, 133, 0.10); color: var(--navy-700); }
.leave-status-pill.unauthorised     { background: rgba(225, 29, 46, 0.22); color: var(--red-700); }

/* R111 — reconciliation banner shown on the leave row when the
   kiosk-stamped actual span differs from the approved span. */
.leave-row-reconciliation {
  margin-top: 6px;
  font-size: 11.5px;
  padding: 4px 8px;
  border-radius: 4px;
  background: rgba(22, 101, 52, 0.08);
  color: var(--success);
  display: inline-block;
}
.leave-row-reconciliation-active {
  background: rgba(13, 148, 136, 0.12);
  color: #0f766e;
}
.leave-row-reconciliation-over {
  background: rgba(180, 83, 9, 0.14);
  color: #92400e;
}
.leave-row-reconciliation-under {
  background: rgba(31, 77, 143, 0.14);
  color: #1f4d8f;
}

/* R105 — Flight booking status pills on the Crew Tracker & Leave rows.
   Matches the leave-status-pill shape so they sit next to each other
   visually without competing for attention. */
.flight-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.flight-pill-booked          { background: rgba(22, 101, 52, 0.12); color: var(--success); }
.flight-pill-not-booked      { background: rgba(180, 83, 9, 0.12); color: #92400e; }
.flight-pill-missing-detail  { background: rgba(225, 29, 46, 0.16); color: var(--red-700); }
.flight-pill-confirmed       { background: rgba(22, 101, 52, 0.18); color: var(--success); font-weight: 700; }

/* R107 — Master Calendar v2: RSVP pills + dept chip row.
   RSVP pills follow the same shape as leave/flight pills.  Dept
   chip row sits under the toolbar, between nav + filters and the
   month grid; each chip carries its dept's color as a left border
   when active. */
.rsvp-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-right: 4px;
}
.rsvp-pill-accepted  { background: rgba(22, 101, 52, 0.14); color: var(--success); }
.rsvp-pill-declined  { background: rgba(225, 29, 46, 0.12); color: var(--red-700); }
.rsvp-pill-tentative { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.rsvp-pill-pending   { background: rgba(76, 115, 133, 0.08);  color: var(--ink-muted, #64748b); }

.calendar-dept-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding: 6px 12px;
  border-bottom: 1px solid var(--cream-dark, rgba(0,0,0,0.06));
  background: rgba(0,0,0,0.015);
}
.calendar-dept-chip {
  --chip-color: var(--navy-700, #4A7791);
  background: transparent;
  border: 1px solid var(--cream-dark, rgba(0,0,0,0.12));
  color: var(--ink-soft, #4A5568);
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  line-height: 1.6;
}
.calendar-dept-chip:hover { background: rgba(0,0,0,0.04); }
.calendar-dept-chip.active {
  background: var(--chip-color);
  color: #fff;
  border-color: var(--chip-color);
}
/* Jarvis / Radar variants — keep the chip shape but use HUD tokens. */
[data-theme="jarvis"] .calendar-dept-chips { background: rgba(92, 240, 255, 0.04); border-color: rgba(92, 240, 255, 0.18); }
[data-theme="jarvis"] .calendar-dept-chip  { color: var(--j-text-soft, #7fa8b8); border-color: rgba(92, 240, 255, 0.28); }
[data-theme="jarvis"] .calendar-dept-chip.active { background: var(--j-accent, #5cf0ff); color: #04070d; border-color: var(--j-accent, #5cf0ff); }

/* R108 — LOCODE Search (Wheelhouse → LOCODE Search). Single-input
   typeahead with card-grid results. Card carries the canonical
   5-char code at the top in a monospaced display so it pops. */
.locode-search-shell { max-width: 720px; margin: 18px auto; }
.locode-search-input-wrap { margin-bottom: 14px; }
.locode-search-input-wrap input[type="search"] {
  width: 100%;
  padding: 12px 14px;
  font-size: 15px;
  border: 1px solid var(--cream-dark, rgba(0,0,0,0.12));
  border-radius: 6px;
  background: #fff;
}
.locode-result-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.locode-card {
  border: 1px solid var(--cream-dark, rgba(0,0,0,0.08));
  border-radius: 6px;
  padding: 12px 14px;
  background: var(--cream, #faf7f2);
  display: flex; flex-direction: column; gap: 4px;
}
.locode-card-validated { border-style: dashed; background: rgba(245, 158, 11, 0.05); }
.locode-code {
  font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.04em;
  color: var(--navy-800, #38617A);
}
.locode-name    { font-weight: 600; color: var(--ink, #1A1A1A); }
.locode-country { font-size: 12px; color: var(--ink-muted, #64748b); }
.locode-actions { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }

[data-theme="jarvis"] .locode-search-input-wrap input[type="search"] {
  background: var(--j-bg-panel, #0a1320);
  color: var(--j-text, #dff6ff);
  border-color: rgba(92, 240, 255, 0.28);
}
[data-theme="jarvis"] .locode-card {
  background: rgba(92, 240, 255, 0.04);
  border-color: rgba(92, 240, 255, 0.18);
}
[data-theme="jarvis"] .locode-code { color: var(--j-accent, #5cf0ff); }

/* ============================================================
   NOTICES BOARD — captain/HOD pinned messages
   ============================================================ */
.notices-list { display: flex; flex-direction: column; gap: 10px; }
.notice-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  position: relative;
}
.notice-row.pinned {
  border-left: 4px solid var(--red-500);
  background: linear-gradient(90deg, rgba(225,29,46,0.04), #fff 12%);
}
.notice-row .notice-pin-mark {
  position: absolute;
  top: 12px;
  right: 14px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--red-700);
}
.notice-row h3 { margin: 0 0 4px; font-size: 16px; color: var(--navy-900); }
.notice-row .notice-meta { font-size: 12px; color: var(--ink-muted, #64748b); margin-bottom: 6px; }
.notice-row .notice-body { font-size: 14px; color: var(--ink-soft, #475569); line-height: 1.55; white-space: pre-wrap; }
.notice-row .notice-body a { color: var(--navy-700); text-decoration: underline; }
.notice-row .notice-actions { margin-top: 10px; display: flex; gap: 8px; }

.home-notices {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px 14px;
  margin-top: 18px;
}
.home-notices-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 10px;
}
.home-notices-head h2 { margin: 0; font-size: 14px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--navy-700); }
.home-notices-head a { font-size: 12px; }
.home-notices-empty { font-size: 13px; color: var(--ink-muted, #64748b); padding: 4px 0; }

/* ============================================================
   PORT INFO — emergency / hospital / agent panel on home
   ============================================================ */
.port-info {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px;
  margin: 18px auto 0;
  max-width: 1080px;
}
.port-info-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.port-info-head h2 {
  margin: 0;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
}
.port-info-head .port-name { font-size: 13px; color: var(--ink-muted, #64748b); }
.port-info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 18px;
}
.port-info-block {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.port-info-block .pi-label {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.port-info-block .pi-value { font-size: 14px; color: var(--navy-900); }
.port-info-block .pi-value a { color: var(--navy-800); text-decoration: none; border-bottom: 1px dotted currentColor; }
.port-info-block .pi-value a:hover { color: var(--red-500); border-bottom-color: var(--red-500); }
.port-info-block.emergency .pi-label { color: var(--red-700); }
.port-info-block.emergency .pi-value { font-weight: 700; }

/* ============================================================
   DRILL LOG — list rows
   ============================================================ */
.drill-list { display: flex; flex-direction: column; gap: 10px; }

/* Drill matrix — at-a-glance compliance against SOLAS / ISM intervals.
   One row per drill type with target / last / next-due / status traffic light. */
.drill-matrix-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 16px;
}
.drill-matrix-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.drill-matrix-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.drill-matrix-sub { font-size: 12px; color: var(--ink-muted); }

.drill-matrix-row {
  display: grid;
  grid-template-columns: 170px 1fr 1fr 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  border: 1px solid transparent;
}
.drill-matrix-row:hover { background: #f8fafc; border-color: var(--navy-100); }
.drill-matrix-row + .drill-matrix-row { margin-top: 4px; }
.drill-matrix-row .drill-type-pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.drill-matrix-cell { display: flex; flex-direction: column; gap: 2px; }
.drill-matrix-lbl {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.drill-matrix-val {
  font-size: 13px;
  color: var(--navy-900);
  font-variant-numeric: tabular-nums;
}
.drill-matrix-status {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 5px 12px;
  border-radius: 999px;
  white-space: nowrap;
}
.drill-status-ok       { background: rgba(22, 101, 52, 0.12); color: #166534; }
.drill-status-due-soon { background: rgba(245, 158, 11, 0.18); color: #92400e; }
.drill-status-overdue  { background: rgba(225, 29, 46, 0.16); color: var(--red-700); }
.drill-status-never    { background: rgba(0,0,0,0.06); color: var(--ink-muted); }

@media (max-width: 720px) {
  .drill-matrix-row { grid-template-columns: 1fr; gap: 4px; padding: 12px; }
  .drill-matrix-status { justify-self: flex-start; margin-top: 4px; }
}
.drill-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 16px;
}
.drill-row h3 { margin: 0; font-size: 15px; color: var(--navy-900); }
.drill-row .drill-meta { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 2px; }
.drill-row .drill-notes { font-size: 13px; color: var(--ink-soft, #475569); margin-top: 6px; white-space: pre-wrap; }
.drill-row .drill-attendees { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 4px; }
.drill-type-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  background: rgba(76, 115, 133, 0.06);
  color: var(--navy-700);
}
.drill-type-pill.fire     { background: rgba(225, 29, 46, 0.12); color: var(--red-700); }
.drill-type-pill.abandon  { background: rgba(180, 83, 9, 0.15); color: #92400e; }
.drill-type-pill.mob      { background: rgba(76, 115, 133, 0.10); color: var(--navy-700); }
.drill-type-pill.security { background: rgba(76, 115, 133, 0.08); color: var(--navy-700); }
.drill-type-pill.medical  { background: rgba(22, 101, 52, 0.10); color: var(--success); }

/* ============================================================
   CRUISE CALENDAR
   ============================================================ */

/* R148 (v1.72) — "Managed by Itinerary Planner" banner inside
   the cruise edit modal. Same warm-gold language as the
   planned-voyage strip on the watch grid (R147), so the visual
   thread "this is itinerary-managed" is consistent across the app. */
.cruise-managed-banner {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: rgba(167, 134, 70, 0.10);
  border-left: 3px solid #a78646;
  border-radius: 6px;
  padding: 12px 14px;
  margin-bottom: 16px;
}
.cruise-managed-icon { font-size: 20px; line-height: 1.2; }
.cruise-managed-text { flex: 1; min-width: 0; }
.cruise-managed-text strong {
  display: block;
  font-size: 13px;
  color: var(--navy-900);
  margin-bottom: 4px;
}
.cruise-managed-text small {
  display: block;
  font-size: 12px;
  color: var(--ink-soft, #475569);
  line-height: 1.4;
  margin-bottom: 8px;
}
.cruise-managed-text em { font-style: italic; }
.cruise-managed-jump { font-size: 12px; padding: 4px 10px; }

/* Locked fields look distinctly read-only — pale fill + subtle
   border so the captain doesn't waste a beat trying to type into
   them. Native `disabled` already blocks input; this just makes
   the state legible. */
.is-managed-lock {
  background: #f5f3ee !important;
  color: var(--ink-muted, #64748b) !important;
  border-color: var(--navy-100, #DCE7ED) !important;
  cursor: not-allowed !important;
}

.cruise-grid {
  display: grid;
  /* R129 — min(320px, 100%) prevents the 320px floor from forcing horizontal page scroll when the container is narrower (iPhone SE etc.). */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 14px;
}
.cruise-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-left: 4px solid var(--navy-700);
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
}
.cruise-card:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(52, 85, 120, 0.08); }
.cruise-card.status-confirmed   { border-left-color: var(--success); }
.cruise-card.status-in_progress { border-left-color: var(--red-500); }
.cruise-card.status-complete    { border-left-color: var(--ink-muted, #64748b); opacity: 0.85; }
.cruise-card.status-planned     { border-left-color: #b45309; }
.cruise-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.cruise-card-title { margin: 0; font-size: 16px; color: var(--navy-900); font-weight: 700; }
.cruise-status-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.cruise-status-pill.planned     { background: rgba(180, 83, 9, 0.12); color: #92400e; }
.cruise-status-pill.confirmed   { background: rgba(22, 101, 52, 0.12); color: var(--success); }
.cruise-status-pill.in_progress { background: rgba(225, 29, 46, 0.12); color: var(--red-700); }
.cruise-status-pill.complete    { background: rgba(0,0,0,0.06); color: var(--ink-muted, #64748b); }
.cruise-card-dates { font-size: 13px; color: var(--ink-muted, #64748b); }
.cruise-card-principal {
  font-size: 13px;
  color: var(--navy-800);
  font-weight: 600;
}
.cruise-card-principal .principal-tag {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--navy-800);
  color: #fff;
  padding: 2px 6px;
  border-radius: 4px;
  margin-right: 6px;
  vertical-align: 1px;
}
.cruise-card-principal .principal-tag.charter { background: var(--red-600); }
.cruise-card-itin { font-size: 13px; color: var(--ink-soft, #475569); margin-top: 4px; line-height: 1.5; }
.cruise-card-guests {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 8px;
  margin-top: auto;
}
.cruise-card-actions { display: flex; gap: 6px; margin-top: 6px; }

/* Compact "next cruise" widget on home page */
.home-next-cruise {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-left: 4px solid var(--red-500);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 18px auto 0;
  max-width: 1080px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.home-next-cruise-label {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.home-next-cruise-title { font-size: 16px; font-weight: 700; color: var(--navy-900); }
.home-next-cruise-dates { font-size: 13px; color: var(--ink-soft, #475569); }

/* ============================================================
   EXPIRY DASHBOARD — grouped by crew member
   ============================================================ */
.expiry-list { display: flex; flex-direction: column; gap: 14px; }
.expiry-person {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px 16px;
}
.expiry-person-head {
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  padding-bottom: 8px;
  margin-bottom: 8px;
}
.expiry-person-name { font-weight: 700; color: var(--navy-900); }
/* Inline rank — sits next to the name with a hyphen separator and matches
   the name's size/weight (Fraser, 2026-04-30). Was previously a small
   right-aligned label; he wanted it tucked under the name typographically
   instead of pushed to the row's far right. */
.expiry-person-pos { font-size: inherit; font-weight: inherit; color: inherit; }
/* Compact row layout: file-icon | doc text (name + sub) | expiry date | status pill.
   Polished 2026-04-29 — the previous full-width Preview button looked cramped and
   broke the visual rhythm. The icon-only file button is enough now that the row
   itself is densely informative. */
.expiry-doc-row {
  display: grid;
  grid-template-columns: 28px 1fr auto auto;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
  font-size: 13px;
}
.expiry-doc-row + .expiry-doc-row { border-top: 1px solid var(--navy-100, #E6ECF3); }
.expiry-doc-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.expiry-doc-name { color: var(--navy-900); font-weight: 600; }
.expiry-doc-sub  { font-size: 11px; color: var(--ink-muted, #64748b); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* R26 — the actual stored filename, surfaced as a tertiary meta line so
   the captain can verify what's attached without opening the file. */
.expiry-doc-filename {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.expiry-doc-date { color: var(--ink-muted, #64748b); font-feature-settings: 'tnum' 1; font-size: 12px; }
/* R26b — auto-rotate photos in the doc preview based on EXIF.
   Most modern browsers honour EXIF orientation by default for
   <img>, but we set it explicitly here so any older or
   non-default browser also gets it right. Belt-and-braces — the
   real fix is the client-side rotate-on-upload pipeline that
   strips EXIF and writes the file upright. Files uploaded
   before that fix shipped still rely on this rule. */
#doc-preview-body img {
  image-orientation: from-image;
  -webkit-image-orientation: from-image;
}

/* R26b — labelled mini-header at the top of each cert group on the
   Document Expiry page (Identity & travel / Medical / Practical /
   STCW & GMDSS / Galley & Interior / Yacht-specific / Other).
   Replaces the silent dashed separator with an explicit label so
   the captain can scan by category rather than guess at boundaries.
   First header in a person's body has no top margin so it tucks
   neatly against the person row. */
.expiry-doc-group-head {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  margin: 14px 0 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--navy-100, #E6ECF3);
}
.expiry-doc-group-head.is-first { margin-top: 0; }

/* Icon-only preview button — sits at the start of each row when a file is
   attached. Hover reveals it's clickable; otherwise it reads like a quiet
   status indicator. */
.expiry-doc-file {
  width: 28px; height: 28px;
  border: 1px solid var(--navy-100, #DCE7ED);
  background: var(--navy-50, #F2F5F8);
  border-radius: 6px;
  color: var(--navy-700, #5C8AA4);
  cursor: pointer;
  display: grid; place-items: center;
  padding: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.expiry-doc-file:hover {
  background: var(--navy-700, #5C8AA4);
  border-color: var(--navy-700, #5C8AA4);
  color: #fff;
}
.expiry-doc-file:focus-visible { outline: 2px solid var(--navy-700); outline-offset: 2px; }
.expiry-doc-nofile {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  color: rgba(52, 85, 120, 0.18);
  font-size: 14px;
}

/* Department grouping — single capitalised heading above the cards.
   Stays sticky-feeling without actually pinning so the captain can
   scan the whole page and the eye finds dept boundaries quickly. */
.expiry-dept { margin-bottom: 24px; }
.expiry-dept + .expiry-dept { margin-top: 4px; }
.expiry-dept-head {
  font-family: var(--display, sans-serif);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy-700, #5C8AA4);
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.expiry-dept-count {
  font-size: 11px;
  letter-spacing: 0.04em;
  font-weight: 500;
  color: var(--ink-muted, #64748b);
  text-transform: lowercase;
}
.expiry-dept .expiry-person { margin-bottom: 8px; }

/* Person card — slight refresh: tighten head padding, lighten the divider. */
.expiry-person { padding: 14px 18px 10px; }
.expiry-person-head { padding-bottom: 10px; margin-bottom: 6px; border-color: var(--navy-100, #E6ECF3); }
.expiry-person-name { font-size: 15px; }
.expiry-person-pos { font-size: inherit; }

/* ============================================================
   R26 — collapsible per-crew row on the Document Expiry page.
   Default state is collapsed (just the name + status summary);
   chevron click reveals .expiry-person-body. When collapsed,
   the head is the only thing visible so the page reads as a
   compact crew list with "X expired / Y < 3 mo" indicators.
   ============================================================ */
.expiry-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 14px;
  padding: 10px 14px;
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #E6ECF3);
  border-radius: 8px;
}
.expiry-toolbar-meta {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  font-weight: 500;
}
.expiry-toolbar-actions { display: flex; gap: 6px; }

.expiry-person-head {
  /* Now a real <button> — strip default chrome and make it
     read as a clickable row. */
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid transparent;
  text-align: left;
  cursor: pointer;
  padding: 4px 0;
  margin: 0;
  font: inherit;
  color: inherit;
}
.expiry-person.is-open .expiry-person-head {
  border-bottom-color: var(--navy-100, #E6ECF3);
  padding-bottom: 10px;
  margin-bottom: 8px;
}
.expiry-person-head:focus-visible {
  outline: 2px solid var(--navy-700, #5C8AA4);
  outline-offset: 2px;
  border-radius: 6px;
}

.expiry-person-chevron {
  display: inline-block;
  width: 16px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  transition: transform 0.15s;
  flex: 0 0 auto;
}
.expiry-person.is-open .expiry-person-chevron { transform: rotate(90deg); }

.expiry-person-summary {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.expiry-person-summary .status-pill {
  font-size: 11px;
  padding: 2px 8px;
}
.expiry-person-total {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #E6ECF3);
}

.expiry-person-body { display: block; }
.expiry-person-body[hidden] { display: none; }

/* Tighten the collapsed card a touch — without docs visible the
   default 14px / 18px / 10px padding makes the row feel tall. */
.expiry-person:not(.is-open) {
  padding: 10px 18px;
}

/* ============================================================
   DIRECTORY CARDS — expanded contact info
   ============================================================ */
.crew-row {
  display: flex;
  align-items: stretch;
  gap: 0;
  flex-direction: column;
}
.crew-row {
  /* override prior single-row appearance to support an expandable detail panel */
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 0;
  overflow: hidden;
  margin-bottom: 8px;
}
.crew-row-summary {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background 0.12s;
}
.crew-row-summary:hover { background: var(--cream, #faf6f0); }
.crew-row-summary .tracker-avatar { background: var(--navy-700); }
.crew-row-summary .crew-name { font-weight: 600; color: var(--navy-900); font-size: 14px; }
.crew-row-summary .crew-meta {
  font-size: 12px; color: var(--ink-muted, #64748b);
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 2px;
}
.crew-row-summary .crew-meta span { white-space: nowrap; }
.crew-row-status { display: inline-flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.crew-row-toggle {
  background: transparent; border: 0; font-size: 16px; color: var(--ink-muted, #64748b);
  padding: 4px 6px; cursor: pointer;
  transition: transform 0.18s;
}
.crew-row.open .crew-row-toggle { transform: rotate(180deg); }
.crew-row-detail {
  display: none;
  padding: 14px 16px 16px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
}
.crew-row.open .crew-row-detail { display: block; }
.crew-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
/* Uniform sizing per Fraser 2026-04-28 — colour and weight differentiate
   label vs value; size doesn't change. Also align section headers. */
.crew-detail-block .cd-label {
  font-size: 13px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.crew-detail-block .cd-value {
  font-size: 13px;
  color: var(--navy-900);
  font-weight: 500;
  margin-top: 2px;
}
.crew-detail-block .cd-value a { color: var(--navy-800); border-bottom: 1px dotted currentColor; }
.crew-detail-block .cd-value a:hover { color: var(--red-500); border-bottom-color: var(--red-500); }
.crew-detail-section { margin-top: 14px; }
.crew-detail-section h4 {
  margin: 0 0 8px;
  font-size: 13px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--navy-700);
  font-weight: 700;
}
.crew-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 12px;
  margin-top: 14px;
}
.crew-detail-actions .btn-sm {
  padding: 6px 12px;
  font-size: 12px;
  text-decoration: none;
}

/* ============================================================
   YACHT ASSISTANT  (Claude — floating chat panel)
   Per-user-paste API key model, lives in localStorage.
   ============================================================ */
/* ============================================================
   R27 P3 — Floating Messages launcher (lives beside the
   Assistant FAB). Lets crew open a quick-chat panel without
   leaving the page they're on.
   ============================================================ */
.messages-fab {
  position: fixed;
  bottom: 24px;
  /* Sits to the LEFT of the assistant FAB. Assistant is at right:24
     with width 56 → leave 24 + 56 + 12 = 92px between right edge
     and the messages FAB. */
  right: 96px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 0;
  background: linear-gradient(135deg, #1f4d8f, #4A7791);
  color: #fff;
  cursor: pointer;
  z-index: 1150;
  box-shadow: 0 6px 20px rgba(52, 85, 120, 0.35);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.18s, box-shadow 0.18s;
  position: fixed;
}
.messages-fab:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 10px 28px rgba(52, 85, 120, 0.4); }
.messages-fab.hidden { display: none; }
.messages-fab-icon { display: inline-flex; }
.messages-fab-icon .ic { width: 26px; height: 26px; stroke-width: 1.5; }
.messages-fab-badge {
  position: absolute;
  top: -4px; right: -4px;
  min-width: 20px; height: 20px;
  border-radius: 999px;
  background: var(--red-500, #e11d2e);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  border: 2px solid #fff;
  box-shadow: 0 2px 6px rgba(225, 29, 46, 0.4);
}
.messages-fab-badge.hidden { display: none; }

.messages-fab-panel {
  position: fixed;
  bottom: 92px;
  right: 24px;
  width: 380px;
  max-width: calc(100vw - 32px);
  height: 560px;
  max-height: calc(100vh - 120px);
  max-height: calc(100dvh - 120px);
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(52, 85, 120, 0.25);
  z-index: 1180;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform-origin: bottom right;
  transform: translateY(8px) scale(0.96);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.18s ease, opacity 0.18s ease;
}
.messages-fab-panel.open {
  transform: translateY(0) scale(1);
  opacity: 1;
  pointer-events: auto;
}
.messages-fab-panel.hidden { display: none; }
.messages-fab-head {
  padding: 12px 14px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  background: linear-gradient(180deg, #fff, #fafbfc);
  flex-shrink: 0;
}
.messages-fab-head-text h2 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-900);
}
.messages-fab-sub {
  margin: 1px 0 0;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}
.messages-fab-head-actions { display: inline-flex; gap: 4px; }
.messages-fab-icon-btn {
  background: transparent;
  border: 1px solid transparent;
  width: 28px; height: 28px;
  border-radius: 6px;
  color: var(--ink-muted, #64748b);
  cursor: pointer;
  font-size: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.messages-fab-icon-btn:hover { background: var(--cream, #faf6f0); color: var(--navy-900); }

.messages-fab-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.messages-fab-view.hidden { display: none; }

.messages-fab-list-head {
  padding: 8px 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  display: flex;
  justify-content: flex-end;
}
.messages-fab-conv-list {
  flex: 1;
  overflow-y: auto;
}
/* Conv rows reuse the .messages-conv-row styles from the full page —
   nothing extra needed. */

.messages-fab-thread-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
}
.messages-fab-back {
  background: transparent;
  border: 0;
  color: var(--navy-700);
  cursor: pointer;
  padding: 0 6px;
  display: inline-flex;
  align-items: center;
}
.messages-fab-back .ic { width: 18px; height: 18px; }
.messages-fab-back:hover { color: var(--navy-900); }
.messages-fab-thread-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: #f7f9fc;
}
.messages-fab-composer {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  padding: 8px 10px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  flex-shrink: 0;
}
.messages-fab-composer textarea {
  flex: 1;
  resize: none;
  font-family: inherit;
  font-size: 14px;
  padding: 6px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  min-height: 36px;
  max-height: 120px;
  line-height: 1.4;
}
.messages-fab-composer textarea:focus {
  outline: none;
  border-color: var(--navy-700);
}

@media (max-width: 720px) {
  .messages-fab-panel {
    right: 12px;
    left: 12px;
    width: auto;
    max-width: none;
    bottom: 88px;
    height: calc(100vh - 140px);
    height: calc(100dvh - 140px);
  }
  /* Stack the FABs vertically on narrow screens — messages on top */
  .messages-fab { right: 16px; bottom: 84px; }
}

.assistant-fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 0;
  background: linear-gradient(135deg, var(--navy-800), var(--red-600));
  color: #fff;
  cursor: pointer;
  /* Above the sticky header + Leaflet, below modals + toasts. */
  z-index: 1150;
  box-shadow: 0 6px 20px rgba(52, 85, 120, 0.35);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.18s, box-shadow 0.18s;
}
.assistant-fab:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 10px 28px rgba(52, 85, 120, 0.4); }
.assistant-fab-icon { display: inline-flex; }
.assistant-fab-icon .ic { width: 26px; height: 26px; stroke-width: 1.5; }
.assistant-fab.hidden { display: none; }

.assistant-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 100vw;
  background: #fff;
  border-left: 1px solid var(--navy-100, #DCE7ED);
  box-shadow: -8px 0 30px rgba(52, 85, 120, 0.18);
  /* Above the sticky header (1100) so the panel covers it cleanly when open. */
  z-index: 1200;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.22s ease;
}
.assistant-panel.open { transform: translateX(0); }
.assistant-panel.hidden { display: none; }
.assistant-head {
  padding: 14px 16px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  background: linear-gradient(180deg, #fff, #fafbfc);
}
.assistant-head h2 { margin: 0; font-size: 15px; color: var(--navy-900); text-transform: uppercase; letter-spacing: 0.04em; }
.assistant-sub { margin: 2px 0 0; font-size: 12px; color: var(--ink-muted, #64748b); }
.assistant-head-actions { display: inline-flex; gap: 4px; }
.assistant-icon-btn {
  background: transparent;
  border: 1px solid transparent;
  width: 30px; height: 30px;
  border-radius: 6px;
  color: var(--ink-muted, #64748b);
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.assistant-icon-btn:hover { background: var(--cream, #faf6f0); color: var(--navy-900); border-color: var(--navy-100, #DCE7ED); }
.assistant-icon-btn .ic { width: 14px; height: 14px; }

.assistant-thread {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: #fafbfc;
}
.assistant-thread .a-empty {
  color: var(--ink-muted, #64748b);
  font-size: 13px;
  text-align: center;
  margin-top: 24px;
  line-height: 1.55;
}
.assistant-thread .a-empty strong { color: var(--navy-800); display: block; margin-bottom: 4px; font-size: 14px; }
.assistant-thread .a-empty ul { margin: 12px auto 0; max-width: 280px; padding: 0; list-style: none; text-align: left; }
.assistant-thread .a-empty li {
  font-size: 12px;
  padding: 6px 10px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: border-color 0.12s;
}
.assistant-thread .a-empty li:hover { border-color: var(--navy-700); }

.a-msg {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 88%;
}
.a-msg.user { align-self: flex-end; }
.a-msg.assistant { align-self: flex-start; }
.a-msg.system { align-self: center; max-width: 100%; }
.a-bubble {
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.a-msg.user .a-bubble { background: var(--navy-800); color: #fff; border-bottom-right-radius: 3px; }
.a-msg.assistant .a-bubble { background: #fff; color: var(--navy-900); border: 1px solid var(--navy-100, #DCE7ED); border-bottom-left-radius: 3px; }
.a-msg.system .a-bubble {
  background: rgba(180, 83, 9, 0.10);
  color: #92400e;
  border: 1px solid rgba(180, 83, 9, 0.25);
  font-size: 12px;
  font-style: italic;
}
.a-meta {
  font-size: 10px;
  color: var(--ink-muted, #64748b);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
}
.a-msg.user .a-meta { text-align: right; }
.a-tool {
  background: rgba(76, 115, 133, 0.06);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  color: var(--navy-800);
}
.a-tool .a-tool-name {
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
  margin-bottom: 2px;
}
.a-tool pre { margin: 4px 0 0; font-size: 11px; white-space: pre-wrap; word-break: break-all; max-height: 120px; overflow: auto; background: #fff; border-radius: 4px; padding: 4px 6px; border: 1px solid var(--navy-100, #DCE7ED); }
.a-attach-pip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  background: var(--cream, #faf6f0);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  font-size: 11px;
  color: var(--navy-800);
}
.a-thinking {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  font-style: italic;
}
.a-thinking::after {
  content: '';
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--ink-muted, #64748b);
  animation: aPulse 1.2s ease-in-out infinite;
  margin-left: 4px;
}
@keyframes aPulse {
  0%, 100% { opacity: 0.3; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.4); }
}

.assistant-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 16px;
}
.assistant-attachments:empty { padding: 0; }

.assistant-input {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
}
.assistant-attach-btn {
  width: 36px; height: 36px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: #fff;
  flex-shrink: 0;
  color: var(--navy-700);
  transition: border-color 0.16s var(--ease-precise), background 0.16s var(--ease-precise);
}
.assistant-attach-btn .ic { width: 16px; height: 16px; }
.assistant-attach-btn:hover { border-color: var(--navy-700); }
.assistant-attach-btn input { display: none; }
.assistant-input textarea {
  flex: 1;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 9px 12px;
  font: inherit;
  font-size: 13px;
  resize: none;
  outline: none;
  max-height: 120px;
  font-family: var(--sans);
}
.assistant-input textarea:focus { border-color: var(--navy-700); }
.assistant-send-btn {
  width: 36px; height: 36px;
  border: 0;
  border-radius: 8px;
  background: var(--navy-800);
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.16s var(--ease-precise);
}
.assistant-send-btn .ic { width: 16px; height: 16px; }
.assistant-send-btn:hover { background: var(--red-600); }
.assistant-send-btn:disabled { background: var(--ink-muted, #94a3b8); cursor: not-allowed; }

.assistant-foot {
  margin: 0;
  padding: 6px 16px 10px;
  font-size: 10px;
  color: var(--ink-muted, #94a3b8);
  text-align: center;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
}

@media (max-width: 720px) {
  .assistant-panel { width: 100vw; border-left: 0; }
  .assistant-fab { bottom: 16px; right: 16px; width: 52px; height: 52px; }
}

/* ============================================================
   MASTER CALENDAR  (reusable component — embedded on #/crew-tracker
   with leave-only filter, full version on #/calendar)
   ============================================================ */
.calendar-shell {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  overflow: hidden;
}
.calendar-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  flex-wrap: wrap;
}
.calendar-nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.calendar-nav button {
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  border-radius: 6px;
  width: 32px;
  height: 32px;
  cursor: pointer;
  font-size: 16px;
  color: var(--navy-800);
}
.calendar-nav button:hover { border-color: var(--navy-700); }
.calendar-title {
  font-weight: 700;
  color: var(--navy-900);
  font-size: 15px;
  min-width: 140px;
  text-align: center;
}
.calendar-today-btn {
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  font-size: 13px;
  color: var(--navy-800);
}
.calendar-today-btn:hover { border-color: var(--navy-700); }
.calendar-add-btn {
  border: 1px solid var(--navy-900, #38617A);
  background: var(--navy-900, #38617A);
  color: #fff;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.calendar-add-btn:hover { background: var(--navy-700, #5C8AA4); border-color: var(--navy-700, #5C8AA4); }
.calendar-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-left: auto;
}
.calendar-filter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  font-size: 12px;
  color: var(--navy-800);
  cursor: pointer;
  user-select: none;
  font-weight: 500;
  transition: background 0.12s, border-color 0.12s;
}
.calendar-filter input { accent-color: var(--navy-700); margin: 0; }
.calendar-filter .cf-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}
.calendar-filter:hover { border-color: var(--navy-700); }
.calendar-filter.disabled { opacity: 0.45; }

.calendar-body {
  display: grid;
  grid-template-columns: 1fr 280px;
  min-height: 480px;
}
.calendar-grid-wrap { padding: 12px 12px 12px 16px; }
.calendar-day-headers {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
  margin-bottom: 6px;
}
.calendar-day-headers > div { padding: 4px; text-align: center; }
/* R56 (2026-05-12) — Calendar rebuilt to render multi-day events
   as continuous bars (macOS Calendar style). Each week is a
   self-contained 7-column CSS grid with day-numbers in row 1 and
   event bars overlaid in rows 2..N. Bars use grid-column: A / span
   N to flow horizontally across days; CSS variables on the row
   feed the slot count so the row height adapts to how many event
   tiers it carries. */
.calendar-grid {
  display: flex;
  flex-direction: column;
  gap: 0;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  border-left: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}
.cal-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  /* Row 1 = day number, rows 2..(slot+1) = event bars,
     final row = vertical filler so each week has consistent min height. */
  grid-template-rows: 26px repeat(var(--slot-count, 0), 22px) 1fr;
  min-height: 96px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  position: relative;
}
.cal-week:last-child { border-bottom: 0; }

.cal-cell {
  /* Day cells span all rows so the column has a clickable bg under
     the event bars. Bars sit on top via z-index. */
  background: #fff;
  border: 0;
  border-right: 1px solid var(--navy-100, #DCE7ED);
  padding: 4px 6px 6px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  position: relative;
  z-index: 1;
  transition: background 0.12s;
  min-width: 0;
}
.cal-cell:last-child { border-right: 0; }
.cal-cell:hover { background: var(--cream, #faf6f0); }
.cal-cell.other-month { background: #fafbfc; }
.cal-cell.other-month .cal-day-num { color: var(--ink-muted, #94a3b8); }
.cal-cell.today { background: rgba(76, 115, 133, 0.04); }
.cal-cell.today .cal-day-num {
  background: var(--navy-900, #284558);
  color: #fff;
  border-radius: 999px;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px;
  margin-left: -4px;
}
.cal-cell.selected { background: rgba(225, 29, 46, 0.06); box-shadow: inset 0 0 0 2px var(--red-500, #e11d2e); }
.cal-day-num {
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-800);
  letter-spacing: 0.01em;
}

/* Event bar — placed in the grid via inline grid-column / grid-row.
   --evt-color comes from the event-type colour table. Rounded
   corners by default; clip-start / clip-end square the matching
   edge to signal "this event continues from / to the next week". */
.cal-event-bar {
  --evt-color: #475569;
  align-self: stretch;
  margin: 1px 3px;
  background: var(--evt-color);
  color: #fff;
  border-radius: 4px;
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.55;
  padding: 1px 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  z-index: 3;
  display: flex;
  align-items: center;
  transition: filter 0.12s, transform 0.05s;
  letter-spacing: 0.01em;
  min-width: 0;
}
.cal-event-bar:hover { filter: brightness(1.06); }
.cal-event-bar:active { transform: translateY(0.5px); }
.cal-event-bar.clip-start {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-left: 0;
  padding-left: 6px;
}
.cal-event-bar.clip-end {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  margin-right: 0;
  padding-right: 6px;
}
.cal-event-bar-inner {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1;
}
/* Single-day events get a small leading dot for visual parity with
   macOS — keeps a 1-day bar from looking too "loud" next to long
   running spans of the same colour. */
.cal-event-bar.is-single {
  background: transparent;
  color: var(--ink, #38617A);
  padding-left: 6px;
  font-weight: 600;
}
.cal-event-bar.is-single::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--evt-color);
  margin-right: 6px;
  flex-shrink: 0;
}
.cal-event-bar.is-single .cal-event-bar-inner { color: inherit; }

/* Overflow indicator — a small "+N" badge in the day's bottom
   corner when more events exist than fit in the visible slot count. */
.cal-more {
  position: absolute;
  right: 6px;
  bottom: 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-muted, #64748b);
  background: rgba(52, 85, 120, 0.06);
  padding: 1px 6px;
  border-radius: 999px;
}

/* Day detail panel */
.calendar-day-panel {
  border-left: 1px solid var(--navy-100, #DCE7ED);
  background: #fafbfc;
  padding: 14px 16px;
  overflow-y: auto;
  min-height: 0;
}
.calendar-day-panel .cdp-date {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.calendar-day-panel .cdp-day {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy-900);
  margin: 2px 0 12px;
}
.calendar-day-panel .cdp-empty { font-size: 13px; color: var(--ink-muted, #64748b); }
.cdp-event {
  display: block;
  padding: 8px 10px;
  border-left: 3px solid var(--navy-700);
  background: #fff;
  border-radius: 6px;
  margin-bottom: 8px;
  text-decoration: none;
  color: var(--navy-900);
  font-size: 13px;
  cursor: pointer;
  transition: transform 0.12s;
}
.cdp-event:hover { transform: translateX(2px); }
.cdp-event-type {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  display: inline-block;
  padding: 2px 6px;
  border-radius: 3px;
  color: #fff;
  margin-bottom: 4px;
}
.cdp-event-title { font-weight: 600; }
.cdp-event-meta { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 2px; }

@media (max-width: 900px) {
  .calendar-body { grid-template-columns: 1fr; }
  .calendar-day-panel { border-left: 0; border-top: 1px solid var(--navy-100, #DCE7ED); max-height: 320px; }
}
@media (max-width: 540px) {
  .calendar-grid { grid-auto-rows: minmax(56px, 1fr); }
  .cal-day-num { font-size: 11px; }
  .cal-event-pip { font-size: 9px; padding: 1px 3px; }
  .calendar-toolbar { padding: 10px 12px; gap: 8px; }
}

/* ============================================================
   MY PROFILE  (self-service editor)
   ============================================================ */
.profile-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 24px;
  align-items: start;
}
@media (max-width: 720px) { .profile-shell { grid-template-columns: 1fr; } }
.profile-photo-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 18px;
  text-align: center;
  position: sticky;
  top: 20px;
}
.profile-photo {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  margin: 0 auto 12px;
  background: var(--navy-700);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 56px;
  font-weight: 700;
  font-family: var(--display);
  overflow: hidden;
  position: relative;
}
.profile-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.profile-photo-name { font-weight: 700; color: var(--navy-900); font-size: 16px; }
.profile-photo-role { font-size: 12px; color: var(--ink-muted, #64748b); margin-bottom: 12px; }
.profile-photo-actions { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; }
.profile-photo-actions input[type="file"] { display: none; }

.profile-sections { display: flex; flex-direction: column; gap: 14px; }
.profile-section {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  overflow: hidden;
}
.profile-section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 18px;
  cursor: pointer;
  user-select: none;
}
.profile-section-head h3 {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--navy-700);
}
.profile-section-head .ps-status {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}
.profile-section-head .ps-toggle {
  font-size: 14px;
  color: var(--ink-muted, #64748b);
  transition: transform 0.18s;
}
.profile-section.open .ps-toggle { transform: rotate(180deg); }
.profile-section-body {
  display: none;
  padding: 0 18px 18px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
}
.profile-section.open .profile-section-body { display: block; }
.profile-section-body .form-row { margin-top: 12px; }
.profile-section-body .field { margin-top: 12px; }
.profile-section-body .modal-actions {
  border-top: 1px solid var(--navy-100, #DCE7ED);
  padding-top: 12px;
  margin-top: 16px;
}
.profile-section.locked .profile-section-body input,
.profile-section.locked .profile-section-body select,
.profile-section.locked .profile-section-body textarea {
  background: #f8fafc;
  cursor: not-allowed;
}
.profile-locked-note {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  background: rgba(76, 115, 133, 0.04);
  padding: 8px 10px;
  border-radius: 6px;
  margin: 12px 0;
}
.profile-bank-note {
  font-size: 12px;
  background: rgba(180, 83, 9, 0.10);
  color: #92400e;
  padding: 10px 12px;
  border-radius: 6px;
  margin: 12px 0;
  border: 1px solid rgba(180, 83, 9, 0.25);
}

/* ============================================================
   HOURS OF WORK & REST
   ============================================================ */
.hours-shell {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 18px;
}
.hours-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.hours-toolbar h3 {
  margin: 0;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
}
.hours-grid {
  display: grid;
  /* 48 half-hour cells per day, plus a 100 px row label on the left.
     Hour-label header cells span 2 columns each (see .hg-hour-head). */
  grid-template-columns: 100px repeat(48, 1fr);
  gap: 1px;
  background: var(--navy-100, #DCE7ED);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  overflow: hidden;
  margin-top: 8px;
  font-size: 11px;
  /* Disable native touch scrolling within the grid so drag-to-paint works
     reliably on iPad/iPhone. */
  touch-action: none;
  user-select: none;
}
.hours-grid .hg-hour-head { grid-column: span 2; }
.hours-grid .hg-cell.start-of-hour { box-shadow: inset 1px 0 0 var(--navy-700); }
.hours-grid .hg-headcell,
.hours-grid .hg-rowlabel,
.hours-grid .hg-cell {
  background: #fff;
  padding: 4px 2px;
  text-align: center;
  min-height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hours-grid .hg-headcell {
  background: #f8fafc;
  color: var(--ink-muted, #64748b);
  font-size: 10px;
  font-weight: 600;
}
.hours-grid .hg-rowlabel {
  background: #f8fafc;
  color: var(--navy-900);
  font-weight: 600;
  font-size: 11px;
  justify-content: flex-start;
  padding-left: 8px;
  cursor: pointer;
}
.hours-grid .hg-rowlabel small {
  display: block;
  font-weight: 400;
  font-size: 10px;
  color: var(--ink-muted, #64748b);
}
.hours-grid .hg-cell {
  cursor: pointer;
  transition: background 0.08s;
  font-size: 0;
  position: relative;
}
.hours-grid .hg-cell.work { background: var(--red-500); }
.hours-grid .hg-cell.work:hover { background: var(--red-600); }
.hours-grid .hg-cell.rest { background: rgba(22, 101, 52, 0.18); }
.hours-grid .hg-cell.rest:hover { background: rgba(22, 101, 52, 0.30); }
.hours-grid .hg-cell.violation::after {
  content: '!';
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  background: rgba(0,0,0,0.4);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hours-legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 14px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
}
.hours-legend .hl-swatch {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  display: inline-block;
  margin-right: 4px;
  vertical-align: -3px;
}
.hours-legend .hl-rest { background: rgba(22, 101, 52, 0.18); }
.hours-legend .hl-work { background: var(--red-500); }
.hours-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-top: 14px;
}
.hours-summary-tile {
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 12px;
}
.hours-summary-tile.violation {
  border-color: var(--red-700);
  background: rgba(225, 29, 46, 0.06);
}
.hours-summary-tile .hst-label {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  font-weight: 600;
}
.hours-summary-tile .hst-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy-900);
  margin-top: 2px;
}
.hours-summary-tile.violation .hst-value { color: var(--red-700); }
.hours-summary-tile .hst-sub { font-size: 11px; color: var(--ink-muted, #64748b); }
.hours-violations {
  margin-top: 14px;
  font-size: 13px;
  color: var(--red-700);
  background: rgba(225, 29, 46, 0.06);
  border: 1px solid rgba(225, 29, 46, 0.25);
  border-radius: 8px;
  padding: 12px 14px;
}
.hours-violations h4 {
  margin: 0 0 6px;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--red-700);
}
.hours-violations ul { margin: 0; padding-left: 18px; }

@media (max-width: 720px) {
  .hours-grid { font-size: 9px; grid-template-columns: 60px repeat(48, 1fr); }
  .hours-grid .hg-cell, .hours-grid .hg-headcell, .hours-grid .hg-rowlabel { min-height: 22px; padding: 2px 0; }
}

/* Monthly submission banner + HOD approval panel */
.hours-month-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 8px;
  margin-bottom: 12px;
  font-size: 13px;
  flex-wrap: wrap;
}
.hours-month-banner.draft     { background: rgba(76, 115, 133, 0.05);  color: var(--navy-800); border: 1px solid var(--navy-100, #DCE7ED); }
.hours-month-banner.submitted { background: rgba(245, 158, 11, 0.12); color: #92400e;       border: 1px solid rgba(245, 158, 11, 0.4); }
.hours-month-banner.approved  { background: rgba(22, 101, 52, 0.10);  color: var(--success); border: 1px solid rgba(22, 101, 52, 0.30); }
.hours-month-banner.rejected  { background: rgba(225, 29, 46, 0.08);  color: var(--red-700); border: 1px solid rgba(225, 29, 46, 0.30); }
.hours-month-banner strong { display:block; font-size: 13px; }
.hours-month-banner small { display:block; font-size: 11px; opacity: 0.85; margin-top: 2px; }
.hours-month-banner .actions { display: inline-flex; gap: 8px; }
.hours-shell.locked .hours-grid .hg-cell { cursor: not-allowed; opacity: 0.95; }
.hours-shell.locked .hours-grid .hg-cell:hover { background-color: inherit; }

.hours-hod-panel {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 16px 18px;
  margin-top: 18px;
}
.hours-hod-panel h2 {
  margin: 0 0 10px;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--navy-700);
}
.hours-hod-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 10px 14px;
  padding: 10px 0;
  align-items: center;
  border-top: 1px solid var(--navy-100, #DCE7ED);
}
.hours-hod-row:first-of-type { border-top: 0; }
.hours-hod-row .hh-name { font-weight: 600; color: var(--navy-900); font-size: 14px; }
.hours-hod-row .hh-meta { font-size: 12px; color: var(--ink-muted, #64748b); }
.hours-hod-row .hh-actions { display: inline-flex; gap: 6px; }

/* ============================================================
   LEAVE SCHEDULE GRID (deck-spreadsheet style)
   ============================================================ */
.schedule-shell {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  overflow: hidden;
}
.schedule-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  flex-wrap: wrap;
}
.schedule-toolbar select { padding: 5px 8px; border: 1px solid var(--navy-100, #DCE7ED); border-radius: 6px; font: inherit; }
.btn-toggle-stats {
  font: inherit; font-size: 12px;
  padding: 5px 10px;
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff; color: var(--navy-800);
  border-radius: 6px; cursor: pointer;
  white-space: nowrap;
}
.btn-toggle-stats:hover { border-color: var(--navy-700); background: #f8fafc; }
.schedule-legend {
  display: flex;
  gap: 10px 14px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  margin-left: auto;
}
.schedule-legend-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  margin-right: 4px;
  vertical-align: -3px;
  font-size: 9px;
  text-align: center;
  line-height: 14px;
  font-weight: 700;
  color: rgba(0,0,0,0.6);
}
.schedule-scroll {
  overflow-x: auto;
  max-width: 100%;
  /* iOS momentum + visible scrollbar feedback */
  -webkit-overflow-scrolling: touch;
}
.schedule-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 11px;
  white-space: nowrap;
  font-family: var(--sans);
}
.schedule-table th, .schedule-table td {
  padding: 0;
  border-right: 1px solid var(--navy-100, #DCE7ED);
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  vertical-align: middle;
  text-align: center;
  height: 26px;
  font-weight: 500;
  color: var(--navy-900);
}
.schedule-table thead th {
  background: #f8fafc;
  font-size: 10px;
  letter-spacing: 0.02em;
  font-weight: 600;
  text-transform: uppercase;
  position: sticky;
  top: 0;
  z-index: 3;
  color: var(--navy-700);
}
/* Sticky left columns: No / Rank / First / Surname  */
.schedule-table th.sched-stick,
.schedule-table td.sched-stick {
  position: sticky;
  background: #fff;
  z-index: 2;
  text-align: left;
  padding: 4px 8px;
  font-size: 11px;
}
.schedule-table thead th.sched-stick { z-index: 4; background: #f8fafc; }
.schedule-table th.sched-stick.col-no, .schedule-table td.sched-stick.col-no { left: 0; min-width: 36px; max-width: 36px; }
.schedule-table th.sched-stick.col-rank, .schedule-table td.sched-stick.col-rank { left: 36px; min-width: 110px; max-width: 110px; color: var(--ink-muted, #64748b); font-size: 10px; }
.schedule-table th.sched-stick.col-first, .schedule-table td.sched-stick.col-first { left: 146px; min-width: 80px; max-width: 80px; }
.schedule-table th.sched-stick.col-surname, .schedule-table td.sched-stick.col-surname {
  left: 226px;
  min-width: 100px;
  max-width: 100px;
  font-weight: 600;
  /* R146 — hyphenated surnames (e.g. "Worsley-Worswick") overflow.
     Clip with ellipsis; tooltip on hover already shows the full name. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* R114 — stat columns are now part of the frozen left section so HOD
   always sees the live totals while the day grid scrolls behind. */
.schedule-table th.sched-stick.col-hire,    .schedule-table td.sched-stick.col-hire    { left: 326px; min-width: 92px; max-width: 92px; }
.schedule-table th.sched-stick.col-alloc,   .schedule-table td.sched-stick.col-alloc   { left: 418px; min-width: 60px; max-width: 60px; }
.schedule-table th.sched-stick.col-carry,   .schedule-table td.sched-stick.col-carry   { left: 478px; min-width: 60px; max-width: 60px; }
.schedule-table th.sched-stick.col-worked,  .schedule-table td.sched-stick.col-worked  { left: 538px; min-width: 46px; max-width: 46px; }
.schedule-table th.sched-stick.col-h,       .schedule-table td.sched-stick.col-h       { left: 584px; min-width: 46px; max-width: 46px; }
.schedule-table th.sched-stick.col-s,       .schedule-table td.sched-stick.col-s       { left: 630px; min-width: 56px; max-width: 56px; }
.schedule-table th.sched-stick.col-accrued, .schedule-table td.sched-stick.col-accrued { left: 686px; min-width: 56px; max-width: 56px; }
.schedule-table th.sched-stick.col-balance, .schedule-table td.sched-stick.col-balance { left: 742px; min-width: 60px; max-width: 60px; border-right: 2px solid var(--navy-700); }

.schedule-table th.sched-month {
  /* R146 — month band is now the only top header row, so give it
     room to breathe. Bigger font + tracking + taller padding. */
  background: var(--navy-800);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-right: 1px solid var(--navy-700);
  padding: 10px 0;
}
.schedule-table th.sched-week {
  font-size: 9px;
  color: var(--ink-muted, #64748b);
  min-width: 16px;
  max-width: 16px;
  font-weight: 500;
  padding: 2px 0;
}
.schedule-table th.sched-week.first-of-month { border-left: 2px solid var(--navy-700); }

.schedule-table td.sched-cell {
  min-width: 16px;
  max-width: 16px;
  width: 16px;
  font-size: 8px;
  font-weight: 700;
  cursor: pointer;
  color: rgba(0,0,0,0.7);
  transition: filter 0.08s, transform 0.08s;
  user-select: none;
  padding: 2px 0;
}
.schedule-table td.sched-cell.first-of-month { border-left: 2px solid var(--navy-700); }
.schedule-table td.sched-cell:hover { filter: brightness(1.06); }
.schedule-table td.sched-cell { touch-action: none; }
.schedule-table td.sched-cell.locked { cursor: not-allowed; opacity: 0.85; }
.schedule-table td.sched-cell.painting {
  box-shadow: inset 0 0 0 2px var(--navy-700);
  filter: brightness(1.08);
}
.schedule-table tbody tr.dept-divider td {
  background: #f1f5f9;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 11px;
  color: var(--navy-800);
  text-align: left;
  padding: 6px 12px;
}
/* Only the LABEL cell of the dept divider gets pinned to left:0.
   Each .dept-stats-head cell uses its own col-* class for its sticky
   left value, matching the body row's column layout below it. */
.schedule-table tbody tr.dept-divider td.dept-label-cell { left: 0 !important; position: sticky; z-index: 2; }
.schedule-table tbody tr.dept-divider td.dept-stats-head { position: sticky; z-index: 2; }
.schedule-table tbody tr.dept-divider td.dept-stats-head {
  background: #e2e8f0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--navy-800);
  text-align: center;
  padding: 6px 4px;
  text-transform: uppercase;
}
/* Day-of-month sub-header carried inside the dept divider. R146:
   width MUST match .sched-cell (16px) exactly — anything else
   shifts the column geometry and the red is-today inset shows
   as a double line because the dept header's column edge sits a
   pixel or two off the body cells' column edges below it. */
.schedule-table tbody tr.dept-divider td.dept-day-head {
  background: #e2e8f0;
  font-size: 8px;
  font-weight: 700;
  color: var(--navy-800);
  text-align: center;
  padding: 2px 0;
  min-width: 16px;
  max-width: 16px;
  width: 16px;
}
.schedule-table tbody tr.dept-divider td.dept-day-head.first-of-month {
  border-left: 2px solid var(--navy-700);
}
.schedule-table tbody tr.dept-divider td.dept-day-head.is-today {
  box-shadow: inset 2px 2px 0 #dc2626, inset -2px 0 0 #dc2626;
  color: #dc2626;
}
.schedule-table tbody tr.dept-divider td.dept-day-head.is-past {
  opacity: 0.45;
}

/* R146 — collapsible dept rows.
   Click the header → toggles is-collapsed. CSS hides every
   .crew-row whose data-dept matches a collapsed dept (via the
   .dept-hidden class applied by toggleDept). The chevron in the
   header flips between ▾ (open) and ▸ (collapsed). */
.schedule-table tbody tr.dept-divider { cursor: pointer; user-select: none; }
.schedule-table tbody tr.dept-divider:hover td { background: #e2e8f0; }
.schedule-table tbody tr.dept-divider .dept-chevron {
  display: inline-block;
  width: 14px;
  font-size: 12px;
  color: var(--navy-700);
  margin-right: 4px;
}
.schedule-table tbody tr.dept-divider .dept-count {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-muted, #64748b);
  margin-left: 8px;
  font-size: 10px;
}
.schedule-table tbody tr.sched-crew-row.dept-hidden { display: none; }

/* R146 — suppress the blue first-of-month border when it lands
   immediately after today's red column, OR when today IS the
   last day of the month (its right red edge runs against the
   next cell's blue left border, producing the visual clash
   Captain reported). */
.schedule-table td.sched-cell.is-today + td.first-of-month,
.schedule-table th.sched-week.is-today + th.first-of-month,
.schedule-table tbody tr.dept-divider td.dept-day-head.is-today + td.first-of-month {
  border-left: none;
}

/* R146 — travel-day glyphs. Make ✈️ / 🛬 slightly larger and
   centered on a W background. The has-travel-glyph class is on
   the cell; the glyph itself is the cell's text content. */
.schedule-table td.sched-cell.has-travel-glyph {
  font-size: 11px;
  text-align: center;
  /* keep the W green background but boost contrast */
  font-weight: 700;
}

/* R114 — stat columns live inside the sticky left frame so HOD sees
   the live totals next to each crew member's name without scrolling.
   Cells are plain table-cells (no display:flex — that broke the table
   layout). Number + label sit inline so the row stays single-height. */
.schedule-table th.sched-stick.stat-head {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--navy-900, #0b2545);
  text-align: center;
  padding: 6px 4px;
}
/* R146 — top-left cover. Replaces the 12 individual sticky label
   cells that used to hold No / Rank / First / Surname / Hire date / …
   / Balance. Captain wanted that space cleared and the month bands
   visible "sliding under" it on horizontal scroll. Translucent white
   + backdrop-filter blur achieves the frosted-glass effect on
   browsers that support it; the fallback colour stays readable
   elsewhere. */
.schedule-table thead th.sched-stick.top-header-cover {
  position: sticky;
  z-index: 4;
  background: rgba(248, 250, 252, 0.55);
  backdrop-filter: blur(8px) saturate(1.2);
  -webkit-backdrop-filter: blur(8px) saturate(1.2);
  border-bottom: 1px solid var(--navy-overlay-12, rgba(40,69,88,0.12));
  /* No internal border — the two cover cells merge into one frosted band */
  border-right: 0;
}
/* Static cover (No+Rank+First+Surname). Always visible. */
.schedule-table thead th.sched-stick.top-header-cover-static {
  left: 0;
}
/* Stats cover (Hire date → Balance). Hides via .stat-head rule when
   the table has .stats-collapsed. While visible, sits just after the
   static cover and carries the heavy navy boundary on its right. */
.schedule-table thead th.sched-stick.top-header-cover-stats {
  left: 326px; /* immediately after Surname column end */
  border-right: 2px solid var(--navy-700);
}
/* When stats are collapsed, the static cover OWNS the right boundary */
.schedule-table.stats-collapsed thead th.sched-stick.top-header-cover-static {
  border-right: 2px solid var(--navy-700);
}
.schedule-table td.stat-cell {
  text-align: center;
  vertical-align: middle;
  padding: 2px 4px;
  font-size: 11px;
  background: #f8fafc;
  color: var(--navy-800);
  white-space: nowrap;
  overflow: hidden;            /* clip any descenders that try to escape */
}
.schedule-table td.stat-cell small {
  font-size: 8px;
  text-transform: uppercase;
  color: var(--ink-muted, #64748b);
  letter-spacing: 0.02em;
  margin-left: 2px;
}
/* Cells with an input/select sit on two lines: control on top, the
   sub-label underneath. Keeps the cell narrow without the label
   bleeding into the neighbour. */
.schedule-table td.col-hire,
.schedule-table td.col-alloc,
.schedule-table td.col-carry {
  line-height: 1.05;
  padding: 1px 3px;
}
.schedule-table td.col-hire small,
.schedule-table td.col-alloc small,
.schedule-table td.col-carry small {
  display: block;
  margin-left: 0;
  margin-top: 1px;
}
.schedule-table td.stat-cell .stat-input,
.schedule-table td.stat-cell select.stat-input {
  font: inherit; font-size: 10px; padding: 1px 2px;
  border: 1px solid transparent; background: transparent;
  color: inherit; width: 100%; text-align: center;
  min-width: 0;
  display: block;
}
.schedule-table td.stat-cell .stat-input:hover,
.schedule-table td.stat-cell .stat-input:focus {
  border-color: var(--navy-100, #DCE7ED); background: #fff;
}
.schedule-table td.stat-num { font-weight: 700; font-size: 13px; }
.schedule-table td.stat-num small { font-weight: 500; }
.schedule-table td.stat-cell.stat-neg { color: var(--danger); }
.schedule-table td.stat-cell.stat-pos { color: #065f46; }
/* Expanded mode — left-rail divider after Balance so the boundary
   between stats and the day grid is obvious. */
.schedule-table:not(.stats-collapsed) td.col-balance,
.schedule-table:not(.stats-collapsed) th.col-balance {
  border-right: 2px solid var(--navy-700);
}
/* Collapsed mode — hide all stat columns; let Surname own the boundary.
   R146 — also catches the new .stat-head td cells inside dept dividers
   (without this, the dept-row's Hire date → Balance cells stayed at
   full width while the body rows hid theirs, stretching the layout). */
.schedule-table.stats-collapsed th.stat-head,
.schedule-table.stats-collapsed td.stat-head,
.schedule-table.stats-collapsed td.stat-cell { display: none; }
.schedule-table.stats-collapsed td.col-surname,
.schedule-table.stats-collapsed th.col-surname {
  border-right: 2px solid var(--navy-700);
}
/* Legacy .sched-meta (right-side panel) — keep for any other table
   variant in the codebase; the duty sheet no longer uses it. */
.schedule-table th.sched-meta, .schedule-table td.sched-meta {
  background: #f8fafc;
  border-left: 1px solid var(--navy-100, #DCE7ED);
  min-width: 64px;
  max-width: 96px;
  padding: 2px 6px;
  font-size: 11px;
  color: var(--navy-800);
  text-align: center;
  vertical-align: middle;
}

/* Status code colours — used both in cells and the legend swatch. */
/* R114 — primary duty-sheet codes (W / H / S). */
.sc-W      { background: #d1fae5; color: #065f46; }  /* green  — Working   */
.sc-H      { background: #fde68a; color: #78350f; }  /* yellow — Holiday   */
.sc-S      { background: #ddd6fe; color: #4c1d95; }  /* purple — Sick leave */
.sc-empty  { background: #fff;    color: #94a3b8; }

/* R146 — past vs today on the leave-schedule grid.
   Past days fade so the eye lands on what's ahead. Today gets a
   2px red inset on every cell in its column (header + body) plus
   a top inset on the day-number header, creating a continuous
   red bracket the eye reads as "right now". */
.sched-cell.is-past,
.sched-week.is-past {
  opacity: 0.45;
  filter: saturate(0.65);
}
.sched-cell.is-today,
.sched-week.is-today {
  box-shadow:
    inset  2px 0 0 #dc2626,
    inset -2px 0 0 #dc2626;
  position: relative;
  z-index: 1;
}
.sched-week.is-today {
  /* extra top border on the day-number header to close the box */
  box-shadow:
    inset  2px  2px 0 #dc2626,
    inset -2px  0 0 #dc2626;
  color: #dc2626;
  font-weight: 700;
}
/* Legacy classes kept so unmigrated rows still render until the SQL
   remap (ops/fixes/INSERT_codes_to_W_H_S.sql) runs in production. */
.sc-x      { background: #d1fae5; color: #065f46; }
.sc-xplus  { background: #6ee7b7; color: #064e3b; }
.sc-l      { background: #fde68a; color: #78350f; }
.sc-T      { background: #bfdbfe; color: #1e3a8a; }
.sc-B      { background: #cbd5e1; color: #38617A; }
.sc-On     { background: #34d399; color: #064e3b; }
.sc-Off    { background: #fca5a5; color: #7f1d1d; }
.sc-FL     { background: #93c5fd; color: #0c4a6e; }
.sc-tbd    { background: #fef08a; color: #713f12; }

/* Cell picker popover */
.sched-picker {
  position: fixed;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(52, 85, 120, 0.18);
  padding: 8px;
  z-index: 1000;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  min-width: 220px;
}
.sched-picker button {
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #fff;
  padding: 8px 0;
  border-radius: 4px;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}
.sched-picker button:hover { border-color: var(--navy-700); }

/* ===== My Leave donut modal (R114) ===== */
.my-leave-card { max-width: 460px; width: 92vw; }
.my-leave-body { padding: 16px 20px 20px; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.my-leave-greeting { text-align: center; }
.my-leave-name { font-size: 18px; font-weight: 700; color: var(--navy-800); }
.my-leave-meta { font-size: 12px; color: var(--ink-muted, #64748b); margin-top: 2px; }
.my-leave-sea { font-size: 11px; color: var(--ink-muted, #64748b); margin-top: 1px; letter-spacing: 0.02em; }
.my-leave-chart { display: flex; justify-content: center; }
.my-leave-donut { width: 180px; height: 180px; }
.my-leave-donut .donut-title { font: 700 18px var(--font-body, sans-serif); fill: var(--navy-800); }
.my-leave-donut .donut-sub   { font: 500 10px var(--font-body, sans-serif); fill: var(--ink-muted, #64748b); text-transform: uppercase; letter-spacing: 0.08em; }
.my-leave-legend { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; width: 100%; max-width: 360px; }
.my-leave-legend li { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--navy-800); }
.my-leave-legend .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.my-leave-legend b { font-weight: 700; }
.my-leave-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; width: 100%; max-width: 360px; }
.my-leave-stats > div { background: #f8fafc; border-radius: 8px; padding: 8px 10px; }
.my-leave-stats label { font-size: 10px; color: var(--ink-muted, #64748b); text-transform: uppercase; letter-spacing: 0.04em; }
.my-leave-num { font-size: 18px; font-weight: 700; color: var(--navy-800); }
.my-leave-num small { font-size: 11px; color: var(--ink-muted, #64748b); font-weight: 500; }
.my-leave-num.pos { color: #065f46; }
.my-leave-num.neg { color: var(--danger); }
.my-leave-note { font-size: 11px; color: var(--ink-muted, #64748b); margin: 4px 0 0; text-align: center; }

@media (max-width: 720px) {
  .schedule-legend { width: 100%; margin-left: 0; }
  .schedule-table th.sched-stick.col-rank,
  .schedule-table td.sched-stick.col-rank { display: none; }
  .schedule-table th.sched-stick.col-first,
  .schedule-table td.sched-stick.col-first { left: 36px; }
  .schedule-table th.sched-stick.col-surname,
  .schedule-table td.sched-stick.col-surname { left: 126px; }
}


/* ============================================================
   CHANGE-PASSWORD VIEW (force-on-first-login gate)
   Standalone shell, shown when state.user.password_change_required.
   Visual language matches the public auth screens — same wordmark,
   same card width, same brand restraint.
   ============================================================ */
#change-password-view {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--cream);
  display: flex;
}
/* Password strength meter (R25c — used by force-change, recovery,
   and the voluntary My Profile change). Five segments tinted from
   red → amber → green based on the score returned by
   PasswordStrength.score(). */
.pw-meter { margin-top: 8px; }
.pw-meter-bar {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  margin-bottom: 6px;
}
.pw-meter-bar .pw-seg {
  height: 5px;
  border-radius: 3px;
  background: rgba(40, 69, 88, 0.10);
  transition: background 160ms ease;
}
.pw-meter-bar .pw-seg.on.s0 { background: #c93030; }
.pw-meter-bar .pw-seg.on.s1 { background: #d96a2c; }
.pw-meter-bar .pw-seg.on.s2 { background: #c98c14; }
.pw-meter-bar .pw-seg.on.s3 { background: #4a8f3c; }
.pw-meter-bar .pw-seg.on.s4 { background: #14785a; }
.pw-meter-meta {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px;
  line-height: 1.4;
}
.pw-meter-label { font-weight: 700; letter-spacing: 0.04em; }
.pw-meter-label.s0 { color: #c93030; }
.pw-meter-label.s1 { color: #d96a2c; }
.pw-meter-label.s2 { color: #c98c14; }
.pw-meter-label.s3 { color: #4a8f3c; }
.pw-meter-label.s4 { color: #14785a; }
.pw-meter-hint { color: var(--ink-muted, #5d6f82); text-align: right; flex: 1; }

.cp-shell {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 32px 22px;
}
.cp-card {
  width: 100%;
  max-width: 420px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  padding: 34px 32px;
  box-shadow: var(--shadow-md);
}
.cp-wordmark { display: block; height: 32px; margin: 0 auto 14px; }
.cp-h1 {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  margin: 4px 0 8px;
  color: var(--navy-900);
  text-align: center;
}
.cp-lede {
  font-size: 13px;
  color: var(--ink-muted);
  line-height: 1.55;
  text-align: center;
  margin: 0 0 22px;
}
.cp-foot {
  font-size: 12px;
  color: var(--ink-muted);
  text-align: center;
  margin-top: 14px;
  line-height: 1.5;
}
.cp-foot a { color: var(--navy-700); text-decoration: underline; }

/* ============================================================
   TWO-FACTOR AUTH  (security S1, item 1)
   Reuses .cp-* shell styling. Adds the QR + secret display and
   a wider card so the QR doesn't squash on phones.
   ============================================================ */
.mfa-card { max-width: 520px; }
.mfa-qr-row {
  display: grid;
  grid-template-columns: 168px 1fr;
  gap: 16px;
  align-items: start;
  margin: 0 0 16px;
}
@media (max-width: 480px) {
  .mfa-qr-row { grid-template-columns: 1fr; }
  .mfa-qr { margin: 0 auto; }
}
.mfa-qr {
  width: 168px; height: 168px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 8px;
  display: grid;
  place-items: center;
}
.mfa-qr svg, .mfa-qr img { width: 100%; height: 100%; display: block; }
.mfa-qr-skeleton {
  font-size: 12px; color: var(--ink-muted);
}
.mfa-secret {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  font-size: 12px;
  color: var(--ink-muted);
  flex-wrap: wrap;
}
.mfa-secret code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 4px;
  padding: 2px 6px;
  word-break: break-all;
  color: var(--navy-900);
}


/* ============================================================
   GUEST CONSENT MODAL  (security S2, item 8)
   Lightweight overlay used inside the guest portal. Built outside
   of guest-view markup so it doesn't fight the existing styles.
   ============================================================ */
.guest-consent-overlay {
  position: fixed; inset: 0;
  background: rgba(52, 85, 120, 0.55);
  display: grid; place-items: center;
  z-index: 5000;
  padding: 16px;
}
.guest-consent-card {
  background: #fff;
  border-radius: 14px;
  max-width: 520px;
  width: 100%;
  padding: 28px 26px;
  box-shadow: 0 20px 60px rgba(52, 85, 120, 0.25);
  font-family: var(--body, system-ui);
  color: var(--ink, #1f2937);
  max-height: min(640px, 92vh);
  display: flex; flex-direction: column;
}
.guest-consent-card h2 {
  font-family: var(--display, system-ui);
  margin: 0 0 16px;
  font-size: 20px;
  color: var(--navy-900, #38617A);
}
.guest-consent-body {
  font-size: 13px;
  line-height: 1.55;
  overflow-y: auto;
  margin-bottom: 18px;
  padding-right: 4px;
}
.guest-consent-body p { margin: 0 0 10px; }
.guest-consent-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  flex-wrap: wrap;
}

/* Guest portal video tile badge — small play indicator on top of
   the video thumbnail in the guest gallery grid. */
.guest-photo-tile { position: relative; }
.guest-photo-tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.guest-photo-vbadge {
  position: absolute; top: 8px; right: 8px;
  background: rgba(52, 85, 120, 0.75);
  color: #fff;
  font-size: 14px;
  width: 28px; height: 28px;
  border-radius: 50%;
  display: grid; place-items: center;
}
.guest-lightbox video { max-width: 92vw; max-height: 80vh; border-radius: 6px; }


/* ============================================================
   CHARTER PLANNER (R20)
   List + detail views of itineraries with map + timeline.
   ============================================================ */
/* R146 — Captain's spec: itineraries now stack full-width in
   chronological order (already sorted in render). The horizontal
   card lets the title + dates + ports + principal sit on one row
   on wide screens, falling back to a stack on narrow ones. */
.charter-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 6px;
}
.charter-card {
  position: relative;
  width: 100%;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 18px;
  text-align: left;
  cursor: pointer;
  font-family: var(--sans);
  display: grid;
  grid-template-columns: minmax(180px, 220px) minmax(160px, 200px) 1fr auto;
  align-items: center;
  gap: 18px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.charter-card:hover {
  border-color: var(--navy-700);
  box-shadow: 0 1px 4px rgba(40, 69, 88, 0.08);
}
.charter-card-status {
  /* Status pill sits in its own grid column (right-most), no longer absolute */
  position: static;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.charter-card-title {
  font-family: var(--display, sans-serif);
  font-size: 16px;
  font-weight: 600;
  color: var(--navy-900);
  margin-right: 0;
  line-height: 1.3;
}
.charter-card-sub {
  font-size: 13px;
  color: var(--ink-soft, #475569);
  line-height: 1.4;
}
.charter-card-dates {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink, #1A2332);
  white-space: nowrap;
}
.charter-card-sub-col {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.charter-card-sub-col:empty { display: none; }
.charter-card-principal { font-size: 12px; color: var(--ink-muted); }

/* Narrower viewports — collapse to a vertical stack inside the card */
@media (max-width: 820px) {
  .charter-card {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      'title  status'
      'dates  dates'
      'subcol subcol';
    gap: 6px;
  }
  .charter-card-title   { grid-area: title; }
  .charter-card-status  { grid-area: status; }
  .charter-card-dates   { grid-area: dates; }
  .charter-card-sub-col { grid-area: subcol; }
}

/* R61 — Past itineraries are de-emphasised in the list. The card
   stays clickable so historical trips can still be opened, but the
   colour is washed out and the title weight reduced so the eye lands
   on upcoming/current trips first. */
.charter-card.is-past {
  background: #f7f8fa;
  border-color: #e3e7ec;
  opacity: 0.62;
}
.charter-card.is-past:hover { opacity: 0.88; border-color: var(--navy-100, #DCE7ED); transform: none; }
.charter-card.is-past .charter-card-title { color: var(--ink-muted, #5e6b7a); }
.charter-card.is-past .charter-card-status .finance-pill { filter: grayscale(0.5); }
.charter-card-past {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(40, 69, 88, 0.10);
  color: #475569;
  padding: 2px 8px;
  border-radius: 999px;
  margin-right: 6px;
  vertical-align: middle;
}

/* R61 — Current itineraries (today between start and end) get a
   green outline + pulsing "LIVE" dot so they jump off the page. */
.charter-card.is-current {
  border-color: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.10);
}
.charter-card-live {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #047857;
  background: rgba(16, 185, 129, 0.14);
  padding: 2px 8px;
  border-radius: 999px;
  margin-right: 6px;
  vertical-align: middle;
}
.charter-card-live::before {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #10b981;
  animation: charter-live-pulse 1.6s ease-in-out infinite;
}
@keyframes charter-live-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.45; }
}

.charter-detail-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}
.charter-cover {
  background: linear-gradient(135deg, var(--navy-900, #38617A), var(--navy-700, #5C8AA4));
  color: #fff;
  border-radius: 14px;
  padding: 28px 24px;
  margin-bottom: 18px;
}
.charter-cover-title {
  font-family: var(--display, sans-serif);
  font-size: 28px;
  margin: 0 0 8px;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.charter-cover-subtitle {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.78);
  margin: 0 0 10px;
}
.charter-cover-meta {
  display: flex; flex-wrap: wrap;
  gap: 10px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.65);
  align-items: center;
}

.charter-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
@media (max-width: 900px) {
  .charter-layout { grid-template-columns: 1fr; }
}
.charter-timeline { display: flex; flex-direction: column; gap: 14px; }
.charter-stop {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 16px 18px;
  transition: transform 100ms ease-out, box-shadow 100ms ease-out;
}
/* R34 P2 — drag-and-drop reorder visuals */
.charter-stop[draggable="true"] { cursor: default; }
.charter-stop.is-dragging {
  opacity: 0.55;
  transform: scale(0.98);
}
.charter-stop.is-drop-target {
  box-shadow: 0 0 0 2px var(--red-500, #E11D2E), 0 4px 14px rgba(225, 29, 46, 0.15);
}
.charter-drag-handle {
  background: transparent;
  border: 0;
  padding: 0 4px;
  margin-right: 6px;
  cursor: grab;
  color: var(--ink-muted, #8A94A6);
  font-size: 14px;
  letter-spacing: -2px;
  user-select: none;
  flex-shrink: 0;
}
.charter-drag-handle:hover { color: var(--ink, #1A1A1A); }
.charter-drag-handle:active { cursor: grabbing; }
/* Sea-miles / ETA / fuel line between consecutive stops with lat/lng */
.charter-leg {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -2px 0 -2px 32px;
  padding: 4px 0;
  font-size: 11px;
  color: var(--ink-muted, #8A94A6);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.charter-leg-line {
  display: inline-block;
  width: 18px;
  border-top: 1px dashed var(--navy-100, #DCE7ED);
  position: relative;
}
.charter-leg-line::before,
.charter-leg-line::after {
  content: '';
  position: absolute;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--navy-100, #DCE7ED);
  top: -3px;
}
.charter-leg-line::before { left: -2px; }
.charter-leg-line::after  { right: -2px; }
.charter-leg-text { white-space: nowrap; }
.charter-leg-edit {
  background: transparent;
  border: 1px solid var(--navy-100, #DCE7ED);
  color: var(--navy-700, #4A7791);
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 100ms ease-out;
  margin-left: 8px;
}
.charter-leg-edit:hover {
  background: var(--navy-700, #4A7791);
  color: #fff;
  border-color: var(--navy-700, #4A7791);
}
.charter-leg.is-warn .charter-leg-text { color: var(--danger, #B91C1C); }
.charter-leg-warn { color: var(--danger, #B91C1C); margin-right: 4px; }

/* R34 P4 — Leg-route editor mini-map */
.charter-leg-map {
  width: 100%;
  height: 480px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  overflow: hidden;
}
.charter-leg-stats {
  display: inline-block;
  margin-bottom: 8px;
  padding: 4px 10px;
  background: var(--cream, #FAF7F2);
  border: 1px solid var(--line, #E5E0D5);
  border-radius: 6px;
  font-size: 12px;
  color: var(--ink-soft, #4A5568);
  font-variant-numeric: tabular-nums;
}
.charter-wp-pin { background: transparent; border: 0; }
.charter-wp-dot {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--red-500, #E11D2E);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(159, 18, 32, 0.4);
  cursor: grab;
}
.charter-wp-pin:active .charter-wp-dot { cursor: grabbing; }

/* R34 P4 — Per-stop weather chip. Color-coded against captain
   thresholds (≤2m/25kt calm, ≤3m/35kt moderate, beyond rough). */
.charter-stop-wx { margin: 4px 0 6px; min-height: 18px; }
.charter-wx {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  background: var(--navy-50, #EEF2F8);
  color: var(--ink-soft, #4A5568);
  border: 1px solid var(--navy-100, #DCE7ED);
}
.charter-wx.is-calm  { background: #ECFDF5; color: #166534; border-color: #BBF7D0; }
.charter-wx.is-mod   { background: #FFF7E6; color: #8A5A05; border-color: #FACC8A; }
.charter-wx.is-rough { background: #FEF2F2; color: #9F1220; border-color: #FCA5A5; }
.charter-wx.is-na    { color: var(--ink-muted, #8A94A6); }
/* Brochure export modal layout. */
.charter-export-fset {
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 14px 12px;
  margin: 0 0 14px;
}
.charter-export-fset legend {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-soft, #4A5568);
  padding: 0 6px;
}
.charter-export-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
  font-size: 14px;
  cursor: pointer;
}
.charter-export-row.inline { align-items: center; }
.charter-export-row input { margin-top: 2px; }
.charter-export-hint { font-size: 12px; color: var(--ink-muted, #8A94A6); }
/* Sunrise / sunset chip — sits next to the weather chip on day cards. */
.charter-sun {
  display: inline-block;
  padding: 2px 8px;
  margin-left: 4px;
  border-radius: 999px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  background: #FEF6E0;
  color: #8A5A05;
  border: 1px solid #F8E1A0;
}
/* Numbered day pin for the Itinerary Planner map (R22). Reads like a chart
   annotation: navy bubble with the day number, small triangular tail. */
.charter-pin { background: transparent; border: none; }
.charter-pin-bubble {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 13px;
  box-shadow: 0 2px 6px rgba(40, 69, 88, 0.35);
  border: 2px solid #fff;
  position: relative;
}
.charter-pin-bubble::after {
  content: ''; position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 7px solid #284558;
}
/* R37b — Embarkation / Disembarkation marker. Uses the yacht silhouette PNG
   as a CSS mask so the colour comes from `background` and we get a crisp
   tinted boat at any zoom. The label sits underneath in red small-caps,
   echoing the chart-style typography of the reference. */
.charter-pin-vessel { background: transparent; border: none; }
.charter-pin-vessel-shape {
  width: 72px; height: 22px;
  background: var(--red-500, #E11D2E);
  -webkit-mask: url('/assets/yacht-silhouette.png') no-repeat center / contain;
          mask: url('/assets/yacht-silhouette.png') no-repeat center / contain;
  margin: 0 auto;
  filter: drop-shadow(0 1px 2px rgba(40, 69, 88, 0.30));
}
.charter-pin-vessel-label {
  display: block;
  margin-top: 2px;
  text-align: center;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  font-weight: 700;
  color: var(--red-500, #E11D2E);
  text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.9);
  font-family: Georgia, 'Times New Roman', serif;
  font-style: italic;
}
/* Chevron arrow rendered at each route-segment midpoint, rotated to the
   bearing from day N to day N+1 so the line reads as direction-of-travel. */
.charter-arrow { background: transparent; border: none; pointer-events: none; }
.charter-arrow-shape {
  font-size: 14px; line-height: 1;
  color: #284558;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.9);
  transform-origin: center;
}

/* R38 — Wind & wave overlays */
.charter-wind-heatmap { z-index: 440; opacity: 0.7; }
.charter-wind-streams { z-index: 451; }
.charter-wind-legend { z-index: 1000; }
.charter-wave-canvas { z-index: 440; opacity: 0.75; }
.charter-wave-legend { z-index: 1000; }

/* R37 — Voyage playback simulator */
.charter-boat-icon { background: none !important; border: none !important; }
.charter-boat-wrap {
  transition: transform 0.3s ease;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
}
.charter-voyage-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  background: var(--navy-900, #284558);
  border-radius: 10px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.charter-voyage-bar .btn { color: #fff; }
.charter-speed-btns { display: flex; gap: 2px; }
.charter-speed-btn {
  min-width: 36px; text-align: center;
  border-radius: 6px; font-size: 12px; font-weight: 700;
  color: rgba(255,255,255,0.6) !important;
  background: rgba(255,255,255,0.08);
}
.charter-speed-btn.active {
  color: #fff !important;
  background: rgba(255,255,255,0.22);
}
.charter-voyage-day {
  color: #fff; font-size: 13px; font-weight: 600;
  white-space: nowrap; min-width: 100px;
}
.charter-voyage-scrubber {
  flex: 1; min-width: 120px;
  accent-color: #3B82F6;
  cursor: pointer;
}
.charter-instrument-cluster.voyage-cluster {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px; margin-top: 10px;
}
@media (max-width: 640px) {
  .charter-instrument-cluster.voyage-cluster { grid-template-columns: repeat(2, 1fr); }
  .charter-voyage-bar { gap: 6px; padding: 8px 10px; }
}

.charter-stop-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.charter-stop-head h2 {
  font-size: 15px;
  font-family: var(--display, sans-serif);
  margin: 0;
  color: var(--navy-900);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.charter-stop-meta {
  font-size: 12px;
  color: var(--ink-muted);
  margin-bottom: 6px;
}
.charter-stop-summary {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
  margin: 6px 0 10px;
}
.charter-crew-notes {
  background: #fffbeb;
  border-left: 3px solid #b45309;
  padding: 8px 12px;
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  color: #78350f;
  margin: 8px 0;
}
.charter-crew-notes.is-provisioning {
  background: #eef8f0;
  border-left-color: #166534;
  color: #14532d;
}
.charter-crew-notes.is-berth {
  background: #eef2ff;
  border-left-color: #1e3a8a;
  color: #1e2a6c;
}

.charter-activities {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex; flex-direction: column;
  gap: 8px;
}
.charter-activity {
  background: var(--navy-50, #F2F5F8);
  border-radius: 6px;
  padding: 8px 12px;
}
.charter-activity-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
  flex-wrap: wrap;
}
.charter-activity-time {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--navy-700);
  background: #fff;
  padding: 2px 8px;
  border-radius: 4px;
  min-width: 56px;
  text-align: center;
}
.charter-activity-title { font-weight: 600; color: var(--navy-900); }
.charter-activity-meta {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 4px;
}
.charter-activity-desc {
  font-size: 13px;
  color: var(--ink);
  margin-top: 4px;
  line-height: 1.45;
}

.charter-map {
  position: sticky;
  top: 80px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px;
}

/* ============================================================
   R36 — Itinerary Planner upgrades:
   instrument cluster (HUD), sea-day badge, leg toolbar,
   discovery panel, stop-card action affordance.
   ============================================================ */
.charter-hud {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 14px;
}
@media (max-width: 1100px) { .charter-hud { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .charter-hud { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } }
.charter-hud-tile {
  background: linear-gradient(180deg, #4A7791, #38617A);
  color: #fff;
  border-radius: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 4px 14px rgba(11,37,69,0.18);
  position: relative;
  overflow: hidden;
}
.charter-hud-tile[role="button"] { cursor: pointer; }
.charter-hud-tile[role="button"]:hover { background: linear-gradient(180deg, #2D515F, #38617A); }
.charter-hud-tile::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
}
.charter-hud-label {
  font-family: Inter, var(--sans, sans-serif);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  margin-bottom: 6px;
}
.charter-hud-value {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 22px;
  font-weight: 600;
  color: #FAFCFF;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.charter-hud-sub {
  margin-top: 4px;
  font-size: 11px;
  color: rgba(255,255,255,0.55);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

.charter-toolbar {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 8px 12px;
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  margin: 0 0 14px;
}
.charter-toolbar .btn-sm { font-size: 12px; }

.charter-stop.is-sea {
  background: repeating-linear-gradient(135deg, #F8FAFC 0 12px, #F1F5F9 12px 24px);
  border-style: dashed;
}
.charter-stop.is-sea .charter-stop-head h2 { color: #1F4068; font-style: italic; }
/* R62 — multi-stop day grouping. The card preceding another stop on the
   same day keeps its bottom corners sharp and loses its bottom margin; the
   continuation card sits flush underneath with sharp top corners and a
   slightly indented header so it clearly belongs to the parent day. */
.charter-stop.has-day-continuation {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  margin-bottom: 0;
  border-bottom: 1px dashed rgba(40, 69, 88, 0.18);
}
.charter-stop.is-day-continuation {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-top: 0;
  margin-top: 0;
  padding-left: 18px;
  background: rgba(40, 69, 88, 0.025);
}
.charter-stop.is-day-continuation .charter-stop-head h2 {
  font-size: 14px;
  font-weight: 600;
  color: #1F4068;
}
.charter-sea-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: #1F4068;
  color: #E2ECFB;
  border-radius: 999px;
  vertical-align: middle;
}
.charter-berth-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  vertical-align: middle;
}
.charter-berth-badge.berth-port   { background: var(--navy-50, #E2ECFB); color: var(--navy-700, #1F4068); }
.charter-berth-badge.berth-anchor { background: #E8F5E9; color: #2E7D32; }
.charter-berth-badge.berth-mooring { background: #FFF3E0; color: #E65100; }

.charter-stop-head { gap: 10px; }
.charter-stop-head-actions {
  display: flex; gap: 4px; align-items: center; flex-wrap: wrap;
}
.charter-stop-actions { display: flex; gap: 4px; }
.charter-discover-cta {
  background: rgba(40, 69, 88, 0.06);
  border: 1px solid rgba(40, 69, 88, 0.12);
}
.charter-discover-cta:hover {
  background: rgba(40, 69, 88, 0.12);
}

/* Discovery modal (per-port restaurants / marinas / sights) */
.charter-discover-body {
  padding: 10px 24px 18px;
  max-height: 70vh;
  overflow-y: auto;
}
.charter-discover-loading {
  display: flex; align-items: center; gap: 10px;
  padding: 28px 8px;
  color: var(--ink-muted);
  font-size: 13px;
}
.charter-discover-loading .spin-dot {
  width: 14px; height: 14px;
  border: 2px solid var(--navy-100, #DCE7ED);
  border-top-color: var(--navy-700, #4A7791);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
.charter-discover-error {
  padding: 14px;
  background: #FEF2F2;
  border: 1px solid #FCA5A5;
  border-radius: 8px;
  color: #9F1220;
  font-size: 13px;
}
.charter-discover-section { margin-bottom: 18px; }
.charter-discover-section.is-empty { opacity: 0.7; }
.charter-discover-section h4 {
  margin: 0 0 6px;
  font-family: Inter, var(--sans, sans-serif);
  font-size: 13px;
  letter-spacing: 0.05em;
  color: var(--navy-900, #38617A);
}
.charter-discover-count {
  font-size: 11px;
  color: var(--ink-muted);
  font-weight: 400;
}
.charter-discover-list {
  list-style: none; padding: 0; margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
}
.charter-discover-item {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13px;
}
.charter-discover-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
}
.charter-discover-dist {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--ink-muted);
}
.charter-discover-meta {
  margin-top: 4px;
  font-size: 11px;
  color: var(--ink-muted);
  word-break: break-word;
}
.charter-discover-meta a { color: var(--navy-700); text-decoration: none; }
.charter-discover-meta a:hover { text-decoration: underline; }
.charter-discover-actions { margin-top: 6px; }
.charter-discover-ask {
  margin-top: 14px;
  padding: 14px;
  background: linear-gradient(135deg, #FFF4E5, #FAF7F2);
  border: 1px solid #FACC8A;
  border-radius: 10px;
  text-align: center;
}
.charter-discover-ask-sub {
  margin: 8px 0 0;
  font-size: 12px;
  color: #8A5A05;
  line-height: 1.5;
}

/* ============================================================
   R37 — Photography (cover hero, stop gallery, activity thumb,
   lightbox, file pickers) + activity search.
   ============================================================ */
.charter-cover.has-photo {
  color: #fff;
  position: relative;
  min-height: 240px;
}
.charter-cover.has-photo .charter-cover-title { color: #fff; text-shadow: 0 2px 18px rgba(40, 69, 88, 0.45); }
.charter-cover.has-photo .charter-cover-subtitle,
.charter-cover.has-photo .charter-cover-meta { color: rgba(255, 255, 255, 0.85); }
.charter-cover-photo-btns {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.charter-cover-photo-btn {
  background: rgba(255, 255, 255, 0.14) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, 0.32) !important;
}
.charter-cover-photo-btn:hover {
  background: rgba(255, 255, 255, 0.22) !important;
}

/* Stop card photo strip */
.charter-stop-gallery {
  display: flex;
  gap: 6px;
  margin: 8px 0 4px;
  flex-wrap: nowrap;
  overflow-x: auto;
  padding-bottom: 4px;
}
.charter-stop-gallery-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 96px;
  height: 64px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  background: #fff;
  overflow: hidden;
  transition: transform 100ms ease-out, box-shadow 100ms ease-out;
}
.charter-stop-gallery-thumb.is-hero {
  border-color: #D4A04C;
  box-shadow: 0 0 0 1px #D4A04C inset;
}
.charter-stop-gallery-thumb-btn {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}
.charter-stop-gallery-thumb-btn img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.charter-stop-gallery-thumb:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(40, 69, 88, 0.18);
}
.charter-stop-gallery-thumb.is-hero:hover {
  box-shadow: 0 4px 14px rgba(40, 69, 88, 0.18), 0 0 0 1px #D4A04C inset;
}
.charter-stop-gallery-hero {
  position: absolute;
  top: 4px;
  left: 4px;
  padding: 2px 6px;
  background: #D4A04C;
  color: #fff;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-radius: 3px;
  pointer-events: none;
  font-weight: 600;
}
.charter-stop-gallery-sethero {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(40, 69, 88, 0.7);
  color: #fff;
  font-size: 12px;
  line-height: 22px;
  text-align: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms ease-out, background 120ms ease-out;
}
.charter-stop-gallery-thumb:hover .charter-stop-gallery-sethero,
.charter-stop-gallery-sethero:focus {
  opacity: 1;
}
.charter-stop-gallery-sethero:hover {
  background: #D4A04C;
}
.charter-stop-gallery-more {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border: 1px dashed var(--navy-100, #DCE7ED);
  background: transparent;
  border-radius: 6px;
  color: var(--ink-muted, #8A94A6);
  font-size: 13px;
  cursor: zoom-in;
}

.charter-stop-foot-actions {
  display: flex;
  gap: 14px;
  margin-top: 6px;
  flex-wrap: wrap;
  align-items: center;
}
.charter-photo-add {
  position: relative;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.charter-photo-input { display: none; }

/* Activity thumb on the stop card */
.charter-activity {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.charter-activity-body { flex: 1 1 auto; min-width: 0; }
.charter-activity-thumb {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 6px;
  cursor: zoom-in;
  flex: 0 0 auto;
  border: 1px solid var(--navy-100, #DCE7ED);
}
.charter-activity-actions {
  display: flex;
  gap: 2px;
  margin-left: auto;
  flex: 0 0 auto;
}

/* Stop editor photo grid */
.charter-stop-photos-pick {
  display: inline-block;
  margin: 6px 0;
}
.charter-stop-photos-pick input[type="file"] { display: none; }
.charter-stop-photos-pick-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 6px;
  font-size: 12px;
  color: var(--navy-700);
  cursor: pointer;
}
.charter-stop-photos-pick-cta .ic { width: 14px; height: 14px; }
.charter-stop-photos-pick-cta:hover {
  background: var(--navy-50, #F2F5F8);
}
.charter-stop-photos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  gap: 6px;
  margin-top: 6px;
}
.charter-stop-photos-empty {
  font-size: 11px;
  color: var(--ink-muted);
  font-style: italic;
  padding: 8px 0 4px;
}
.charter-photo-thumb {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--navy-100, #DCE7ED);
  aspect-ratio: 4 / 3;
}
.charter-photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: zoom-in;
}
.charter-photo-thumb-rm {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(40, 69, 88, 0.78);
  color: #fff;
  border: 0;
  font-size: 14px;
  cursor: pointer;
  line-height: 1;
}

/* Activity editor — search + photo */
.charter-activity-search {
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 10px;
}
.charter-activity-search .field { margin-bottom: 6px; }
.charter-activity-search-results {
  max-height: 240px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.charter-activity-search-row {
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  padding: 8px 10px;
  cursor: pointer;
  font-size: 13px;
}
.charter-activity-search-row:hover {
  background: var(--navy-50, #F2F5F8);
  border-color: var(--navy-700, #4A7791);
}
.charter-activity-search-ico { font-size: 16px; flex: 0 0 auto; }
.charter-activity-search-main { flex: 1 1 auto; min-width: 0; }
.charter-activity-search-name {
  display: block;
  font-weight: 600;
  color: var(--navy-900);
}
.charter-activity-search-sub {
  display: block;
  font-size: 11px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.charter-activity-search-dist {
  flex: 0 0 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--ink-muted);
}
.charter-activity-search-loading,
.charter-activity-search-empty,
.charter-activity-search-applied {
  font-size: 12px;
  color: var(--ink-muted);
  padding: 10px;
  text-align: center;
}
.charter-activity-search-applied {
  color: #166534;
  background: #ECFDF5;
  border: 1px solid #BBF7D0;
  border-radius: 6px;
}
.charter-activity-search-ask { text-align: right; margin-top: 4px; }

.charter-activity-photo-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.charter-activity-photo-preview {
  width: 64px;
  height: 64px;
  background: var(--navy-50, #F2F5F8);
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 6px;
  overflow: hidden;
  flex: 0 0 auto;
}
.charter-activity-photo-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Lightbox */
.charter-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(11, 14, 22, 0.92);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: charterLbIn 140ms ease-out;
}
@keyframes charterLbIn { from { opacity: 0; } to { opacity: 1; } }
.charter-lb-img {
  max-width: 92vw;
  max-height: 88vh;
  border-radius: 4px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.charter-lb-close, .charter-lb-prev, .charter-lb-next {
  position: absolute;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 0;
  font-size: 22px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  cursor: pointer;
  line-height: 1;
}
.charter-lb-close { top: 18px; right: 18px; }
.charter-lb-prev  { top: 50%; left: 18px; transform: translateY(-50%); }
.charter-lb-next  { top: 50%; right: 18px; transform: translateY(-50%); }
.charter-lb-close:hover, .charter-lb-prev:hover, .charter-lb-next:hover { background: rgba(255, 255, 255, 0.22); }
.charter-lb-counter {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.7);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

/* R38 — Wikimedia Commons photo search modal */
.charter-photo-search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}
.charter-photo-search-bar input[type="text"] {
  flex: 1 1 auto;
  padding: 8px 12px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  font-size: 14px;
}
.charter-photo-search-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
  max-height: 60vh;
  overflow-y: auto;
}
.charter-photo-search-card {
  position: relative;
  background: var(--navy-50, #F2F5F8);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  transition: transform 100ms ease-out, box-shadow 100ms ease-out;
}
.charter-photo-search-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(40, 69, 88, 0.18);
  border-color: var(--navy-700, #4A7791);
}
.charter-photo-search-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.charter-photo-search-card-meta {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 4px 8px;
  background: linear-gradient(180deg, transparent, rgba(11,37,69,0.78));
  color: #fff;
  font-size: 10px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.charter-photo-search-loading,
.charter-photo-search-empty {
  font-size: 13px;
  color: var(--ink-muted);
  padding: 28px 16px;
  text-align: center;
  grid-column: 1 / -1;
}


/* ============================================================
   MY DOCUMENTS (R19) — list inside My Profile.
   ============================================================ */
.my-docs-list {
  display: flex; flex-direction: column;
  gap: 8px;
}
.my-doc-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex; align-items: center; gap: 12px;
}
.my-doc-main { flex: 1; min-width: 0; }
.my-doc-title { font-size: 14px; color: var(--navy-900); font-weight: 600; }
.my-doc-sub   { font-size: 12px; color: var(--ink-muted); margin-top: 2px; }
.my-doc-meta  { font-size: 11px; color: var(--ink-muted); margin-top: 4px; display: flex; gap: 10px; flex-wrap: wrap; }
.my-doc-actions { display: flex; gap: 4px; flex-wrap: wrap; }


/* ============================================================
   FINANCE & REIMBURSEMENTS  (R18)
   Crew claim list + captain detail modal.
   ============================================================ */
.finance-list {
  display: flex; flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}
.finance-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-left: 3px solid var(--navy-200, #C2CDDD);
  border-radius: 8px;
  padding: 12px 14px;
  text-align: left;
  cursor: pointer;
  display: flex; align-items: center; gap: 14px;
  font-family: var(--sans);
  width: 100%;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.finance-row:hover {
  border-left-color: var(--navy-700);
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.06);
}
.finance-row.finance-status-submitted { border-left-color: #b45309; }
.finance-row.finance-status-approved  { border-left-color: #2563eb; }
.finance-row.finance-status-rejected  { border-left-color: var(--red-500, var(--danger)); opacity: 0.85; }
.finance-row.finance-status-paid      { border-left-color: var(--ok, #137a40); }

/* R37 — left side: crew name (when shown), description, code/vendor/date meta */
.finance-row-main { flex: 1; min-width: 0; }
.finance-row-name {
  font-size: 13px; font-weight: 700;
  color: var(--navy-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 2px;
}
.finance-row-name .finance-name-slot { color: var(--navy-900); }
.finance-row-title {
  font-size: 13px;
  color: var(--ink, #1f2937);
  margin: 2px 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.finance-row-meta {
  font-size: 12px; color: var(--ink-muted, #667085);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.finance-row-meta-aux {
  font-size: 11px; color: var(--ink-muted, #667085);
  margin-top: 2px;
}

/* R37 — right side: amount + status pill, stacked */
.finance-row-right {
  display: flex; flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
  margin-left: auto;
  text-align: right;
}
.finance-row-amount {
  font-family: var(--display, sans-serif);
  font-size: 18px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.1;
  white-space: nowrap;
}
.finance-row-ccy {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted, #667085);
  letter-spacing: 0.04em;
  margin-left: 2px;
}

@media (max-width: 640px) {
  .finance-row { padding: 10px 12px; gap: 10px; }
  .finance-row-amount { font-size: 16px; }
}

/* Status pills shared by row + detail modal */
.finance-pill {
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 999px;
  white-space: nowrap;
}
.finance-pill-submitted { background: #fffbeb; color: #b45309; }
.finance-pill-approved  { background: #eff6ff; color: #2563eb; }
.finance-pill-rejected  { background: #fef2f2; color: var(--danger); }
.finance-pill-paid      { background: #ecfdf5; color: #047857; }

/* Detail modal layout */
.finance-detail-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px;
}
.finance-detail-amount {
  font-family: var(--display, sans-serif);
  font-size: 28px;
  font-weight: 700;
  color: var(--navy-900);
}
.finance-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  font-size: 13px;
  margin-bottom: 12px;
}
.finance-detail-grid .lbl {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
  margin-bottom: 2px;
}
.finance-detail-grid > div { color: var(--ink); }
.finance-detail-grid small { color: var(--ink-muted); }
.finance-detail-note {
  background: var(--navy-50, #F2F5F8);
  border-left: 3px solid var(--navy-200);
  padding: 8px 12px;
  border-radius: 6px;
  margin: 10px 0;
  font-size: 13px;
}

.finance-receipts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin: 8px 0;
}
.finance-receipt-tile {
  border: 1px solid var(--navy-100);
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
}
.finance-receipt-thumb {
  width: 100%; aspect-ratio: 1;
  display: grid; place-items: center;
  background: var(--navy-50, #F2F5F8);
  cursor: pointer;
  padding: 8px;
  word-break: break-all;
  text-align: center;
}
.finance-receipt-thumb img {
  width: 100%; height: 100%; object-fit: cover;
  display: block;
}
.finance-receipt-meta {
  font-size: 11px; padding: 6px 8px;
  color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* v1.7 — inline receipt preview.  Thumb is the click target; image or
   PDF first page renders inside it; an ⤢ button at top-right pops the
   full-size lightbox.  position:relative so the button can absolute
   over the bottom of the thumb. */
.finance-receipt-thumb {
  position: relative;
}
.finance-receipt-thumb .finance-receipt-pdf {
  width: 100%; height: 100%;
  display: block;
  border: 0;
  /* <embed>'s built-in pointer interactions would otherwise swallow the
     slot's click handler — block them so a tile-click reliably opens
     the lightbox. */
  pointer-events: none;
}
.finance-receipt-expand {
  position: absolute;
  bottom: 4px; right: 4px;
  width: 22px; height: 22px;
  border: none; border-radius: 4px;
  background: rgba(52, 85, 120, 0.65);
  color: #fff;
  cursor: pointer;
  font-size: 14px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  z-index: 3;
  transition: background 0.12s;
}
.finance-receipt-expand:hover { background: rgba(52, 85, 120, 0.9); }

/* v1.7 — full-screen receipt viewer triggered from the expand button
   or a thumb click.  Pure CSS overlay; no framework. */
.finance-receipt-lightbox {
  position: fixed; inset: 0;
  background: rgba(52, 85, 120, 0.88);
  z-index: 10000;
  display: flex; flex-direction: column;
}
.finance-receipt-lightbox-bar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
}
.finance-receipt-lightbox-name {
  flex: 1 1 auto;
  font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.finance-receipt-lightbox-open,
.finance-receipt-lightbox-close {
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  cursor: pointer;
  font-size: 18px; line-height: 1;
  width: 32px; height: 32px;
  border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  text-decoration: none;
}
.finance-receipt-lightbox-open:hover,
.finance-receipt-lightbox-close:hover { background: rgba(255, 255, 255, 0.25); }
.finance-receipt-lightbox-body {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  padding: 12px;
  overflow: auto;
}
.finance-receipt-lightbox-body img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  background: #fff;
  border-radius: 4px;
}
.finance-receipt-lightbox-body iframe {
  width: 100%; height: 100%;
  border: 0;
  background: #fff;
  border-radius: 4px;
}

/* R112 — per-receipt remove button overlay on the card-txn detail
   modal. Sits top-right of the tile and hovers above the thumb. */
.receipt-tile-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border: none; border-radius: 50%;
  background: rgba(52, 85, 120, 0.55);
  color: #fff;
  cursor: pointer;
  font-size: 14px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  z-index: 2;
  transition: background 0.12s;
}
.receipt-tile-remove:hover { background: rgba(180, 30, 30, 0.9); }

/* Upload progress rows in the file modal */
.finance-up-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 0; font-size: 12px;
}
.finance-up-name {
  flex: 1; min-width: 0; margin-right: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink);
}
.finance-up-status { color: var(--ink-muted); white-space: nowrap; }

/* Multi-receipt accumulator (2026-05-20) — chip list showing the
   files queued for this claim. Each chip has an × to drop it before
   submit, so crew can curate the batch (e.g. accidentally picked
   the wrong photo) without re-opening the picker from scratch. */
.finance-pending-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.finance-pending-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--cream, #faf6f0);
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  padding: 4px 6px 4px 10px;
  font-size: 12px;
  color: var(--navy-800);
  max-width: 100%;
}
.finance-pending-icon { font-size: 14px; line-height: 1; }
.finance-pending-name {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.finance-pending-size { color: var(--ink-muted); font-size: 11px; }
.finance-pending-x {
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0 4px;
  border-radius: 999px;
}
.finance-pending-x:hover { background: rgba(225, 29, 46, 0.10); color: var(--danger); }

/* R98 — Multi-line claim file-modal styling
   Header section is the standard form. Below it sits the line-items
   repeater (one card per purchase) and the bank-details snapshot
   collapsible. Wider modal (760px) to fit per-line vendor + code
   + amount inputs comfortably on desktop; on mobile the .form-row
   stacks vertically per the existing pattern. */
.finance-lines-section {
  margin: 16px 0;
  padding: 12px;
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
}
.finance-lines-head { margin-bottom: 10px; }
.finance-lines-head h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--navy-900);
}
.finance-lines-sub {
  display: block;
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 2px;
}
#finance-lines { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }

.finance-line-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 12px;
  position: relative;
}
.finance-line-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dashed #e3e6eb;
}
.finance-line-no {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy-700);
  background: #eef2f7;
  padding: 3px 8px;
  border-radius: 999px;
}
.finance-line-summary {
  flex: 1;
  font-size: 12px;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.finance-line-remove {
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 0 6px;
  border-radius: 999px;
}
.finance-line-remove:hover { background: rgba(225, 29, 46, 0.10); color: var(--danger); }
.finance-line-receipts-block {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed #e3e6eb;
}
.finance-line-receipts-block .finance-pending-grid { margin-top: 6px; }
.finance-line-existing {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 6px; font-size: 12px; color: var(--ink-muted);
}
.finance-line-existing-chip {
  background: #eef2f7; padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--navy-100, #DCE7ED);
}

.finance-lines-total {
  margin-top: 12px;
  text-align: right;
  font-size: 14px;
  font-weight: 700;
  color: var(--navy-900);
}

/* Bank-details snapshot section — collapsed by default for clean
   visual hierarchy; expands when crew want to edit the pre-fill. */
.finance-payee-section {
  margin: 16px 0;
  padding: 12px 14px;
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
}
.finance-payee-section > summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--navy-900);
  font-size: 14px;
  list-style: none;
  position: relative;
  padding-right: 24px;
}
.finance-payee-section > summary::after {
  content: '▾';
  position: absolute;
  right: 0; top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: var(--ink-muted);
}
.finance-payee-section[open] > summary::after { transform: translateY(-50%) rotate(180deg); }
.finance-payee-note {
  margin: 8px 0 12px;
  font-size: 12px;
  color: var(--ink-muted);
  padding: 6px 10px;
  background: #fff8e9;
  border: 1px solid #e9d99c;
  border-radius: 6px;
  color: #5d4914;
}

/* Detail / review modal — multi-line breakdown */
.finance-detail-sub {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-muted);
  margin-top: 2px;
}
.finance-detail-lines {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.finance-detail-line {
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 12px;
}
.finance-detail-line-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.finance-detail-line-amt {
  font-weight: 700;
  color: var(--navy-900);
  font-variant-numeric: tabular-nums;
}
.finance-detail-payee {
  margin-top: 16px;
  padding: 10px 14px;
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
}
.finance-detail-payee > summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--navy-900);
  font-size: 13px;
  list-style: none;
  position: relative;
  padding-right: 24px;
}
.finance-detail-payee > summary::after {
  content: '▾';
  position: absolute;
  right: 0; top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: var(--ink-muted);
}
.finance-detail-payee[open] > summary::after { transform: translateY(-50%) rotate(180deg); }

/* R-reviewer-edit (2026-05-20) — inline account-code re-categorise
   select sitting in the detail-grid cell. Sized to match the
   surrounding read-only text so the layout stays tidy. */
.finance-detail-code-select {
  width: 100%;
  font: inherit;
  font-size: 13px;
  padding: 4px 6px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  background: #fff;
  color: var(--ink);
  max-width: 100%;
}
.finance-detail-code-select:disabled { opacity: 0.6; }
.finance-detail-code-status {
  display: block;
  font-size: 11px;
  margin-top: 4px;
  min-height: 14px;
}


/* ============================================================
   MEDIA GALLERY  (R17)
   Photo / video grid + lightbox. CSS-grid masonry-ish layout.
   Tiles size by their declared aspect ratio when available.
   ============================================================ */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
  margin-top: 4px;
}
.media-tile {
  position: relative;
  background: var(--navy-100, #DCE7ED);
  border: 0;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  padding: 0;
  display: block;
  width: 100%;
  aspect-ratio: 1.5;
  transition: transform 0.15s ease;
}
.media-tile:hover { transform: scale(1.01); }
.media-tile:focus-visible { outline: 2px solid var(--navy-700); outline-offset: 2px; }
.media-tile-thumb {
  position: absolute; inset: 0;
  background: var(--navy-50, #F2F5F8);
}
.media-tile-thumb img,
.media-tile-thumb video {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.media-tile-badge {
  position: absolute;
  bottom: 8px; left: 8px;
  background: rgba(52, 85, 120, 0.75);
  color: #fff;
  font-size: 11px;
  padding: 2px 7px;
  border-radius: 4px;
  font-family: var(--display, sans-serif);
}
.media-tile-cap {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  background: linear-gradient(to top, rgba(15,27,45,0.75) 0%, transparent 100%);
  color: #fff;
  font-size: 12px;
  padding: 18px 10px 8px;
  text-align: left;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Upload progress list inside the modal. */
.gallery-up-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 0;
  font-size: 12px;
}
.gallery-up-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-right: 12px;
  color: var(--ink);
}
.gallery-up-status { color: var(--ink-muted); white-space: nowrap; }

/* Lightbox — fullscreen overlay. */
.gallery-lightbox {
  position: fixed; inset: 0;
  background: rgba(52, 85, 120, 0.92);
  z-index: 6000;
  display: grid; place-items: center;
  padding: 16px;
}
.gallery-lightbox.hidden { display: none; }
.gallery-lightbox-close,
.gallery-lightbox-prev,
.gallery-lightbox-next {
  position: absolute;
  background: rgba(255, 255, 255, 0.12);
  border: 0;
  color: #fff;
  width: 44px; height: 44px;
  border-radius: 50%;
  font-size: 24px;
  cursor: pointer;
  z-index: 1;
  display: grid; place-items: center;
}
.gallery-lightbox-close { top: 16px; right: 16px; }
.gallery-lightbox-prev  { left: 16px;  top: 50%; transform: translateY(-50%); }
.gallery-lightbox-next  { right: 16px; top: 50%; transform: translateY(-50%); }
.gallery-lightbox-close:hover,
.gallery-lightbox-prev:hover,
.gallery-lightbox-next:hover { background: rgba(255, 255, 255, 0.22); }
.gallery-lightbox-stage {
  max-width: 92vw; max-height: 92vh;
  display: flex; flex-direction: column; align-items: center;
  gap: 12px;
}
.gallery-lightbox-stage img,
.gallery-lightbox-stage video {
  display: block;
  max-width: 92vw; max-height: 80vh;
  border-radius: 6px;
}
.gallery-lightbox-caption {
  color: rgba(255, 255, 255, 0.92);
  font-size: 14px;
  text-align: center;
  max-width: 600px;
}
.gallery-lightbox-skeleton { color: rgba(255, 255, 255, 0.6); font-size: 14px; }


/* ============================================================
   AUDIT LOG  (security S1, item 3 — Office viewer)
   ============================================================ */
.audit-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}
.audit-row {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13px;
  border-left: 3px solid var(--navy-200, #C2CDDD);
}
.audit-row.ok   { border-left-color: var(--ok, #137a40); }
.audit-row.warn { border-left-color: #b45309; background: #fffbeb; }
.audit-row-head {
  display: flex; align-items: baseline; gap: 12px;
  font-size: 12px;
}
.audit-action {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 600;
  color: var(--navy-900);
}
.audit-actor { color: var(--ink); }
.audit-time { margin-left: auto; color: var(--ink-muted); font-size: 11px; }
.audit-row-body {
  display: flex; gap: 14px; margin-top: 4px;
  font-size: 12px; color: var(--ink-muted);
  flex-wrap: wrap;
}
.audit-meta {
  margin: 8px 0 0;
  padding: 8px 10px;
  background: var(--navy-50, #F2F5F8);
  border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
}
.audit-missing {
  margin: 0;
  padding-left: 18px;
  font-size: 13px;
  line-height: 1.6;
}

/* ============================================================
   COMMS HUB  (Round 12)
   Cross-org workspace shell. Same brand as the crew portal but
   noticeably calmer — wider whitespace, lighter weights, grayer
   surfaces. Designed for someone reading on a phone in a taxi.
   ============================================================ */

/* Hub-view sits below the global portal-header now (was full-viewport
   overlay before the 2026-04-29 polish round). Plain block flow keeps
   it neatly stacked under whichever portal page is visible — except
   in the hub case Hub.show hides every .page so only the hub appears. */
#hub-view {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 64px);
  min-height: calc(100dvh - 64px);
  background: #f6f7f9;
  color: var(--ink, #38617A);
  font-family: var(--sans);
}
#hub-view.hidden { display: none; }

/* Sub-bar — replaces the old hub-header. Holds only All Hands-specific
   controls now; the global brand/nav/notifications/user menu lives in
   the portal-header above this. */
.hub-subbar {
  background: #fff;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  padding: 18px 0 0;
}
.hub-subbar-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 22px;
}
.hub-subbar-title {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.hub-subbar-title h1 {
  font-family: var(--display, sans-serif);
  font-size: 22px;
  margin: 0;
  color: var(--navy-900);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.hub-subbar-me {
  font-size: 13px;
  color: var(--ink, #1f2937);
  font-weight: 600;
}
.hub-subbar .hub-search {
  margin: 0 0 14px;
  max-width: 420px;
}
.hub-subbar .hub-nav {
  border-top: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  gap: 4px;
  padding-top: 4px;
}
.hub-subbar .hub-nav button {
  background: transparent;
  border: 0;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.hub-subbar .hub-nav button.is-active,
.hub-subbar .hub-nav button:hover {
  color: var(--navy-900);
  border-bottom-color: var(--navy-900);
}

/* Legacy class kept so any leftover references don't break — but no
   styling so it's effectively a no-op. */
.hub-header {
  position: sticky;
  top: 0;
  z-index: 1100;
  background: #fff;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.hub-header-inner {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 12px 22px;
}
.hub-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--navy-900);
}
.hub-wordmark { height: 22px; }
.hub-network-name {
  font-family: var(--display);
  font-size: 14px;
  letter-spacing: 0.04em;
  color: var(--navy-800);
  border-left: 1px solid var(--navy-100);
  padding-left: 12px;
}
.hub-search { flex: 1; max-width: 420px; margin: 0 auto; }
.hub-search input {
  width: 100%;
  padding: 8px 14px;
  border: 1px solid var(--navy-100);
  border-radius: 999px;
  font: inherit;
  font-size: 13px;
  background: #f6f7f9;
}
.hub-search input:focus { outline: none; border-color: var(--navy-700); background: #fff; }

.hub-me {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px;
  color: var(--ink-muted);
}
.hub-me-tz {
  font-size: 11px;
  background: #f1f5f9;
  padding: 3px 8px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.hub-exit {
  background: transparent; border: 1px solid var(--navy-100);
  color: var(--navy-700);
  width: 32px; height: 32px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
}
.hub-exit:hover { background: #f1f5f9; }

.hub-nav {
  display: flex;
  gap: 4px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 4px 22px 8px;
  overflow-x: auto;
}
.hub-nav button {
  background: transparent;
  border: 0;
  padding: 8px 16px;
  border-radius: 8px 8px 0 0;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
  cursor: pointer;
  position: relative;
  border-bottom: 2px solid transparent;
}
.hub-nav button:hover { color: var(--ink); }
.hub-nav button.active {
  color: var(--navy-900);
  border-bottom-color: var(--red-700);
}

.hub-main {
  flex: 1;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 22px 60px;
}

/* ---------- Section headings ---------- */
.hub-h1 {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  margin: 4px 0 4px;
  color: var(--navy-900);
  letter-spacing: -0.01em;
}
.hub-lede {
  color: var(--ink-muted);
  font-size: 13px;
  margin: 0 0 18px;
}
.hub-section-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.hub-pill {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
  cursor: pointer;
}
.hub-pill.active { background: var(--navy-900); color: #fff; border-color: var(--navy-900); }
.hub-pill .count {
  display: inline-block;
  margin-left: 6px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(0,0,0,0.08);
  font-size: 11px;
}
.hub-pill.active .count { background: rgba(255,255,255,0.18); }

/* ---------- Tasks list ---------- */
.hub-task-group {
  margin-bottom: 24px;
}
.hub-task-group-h {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  margin: 0 4px 8px;
}
.hub-task-row {
  display: grid;
  grid-template-columns: 8px 1fr auto auto;
  gap: 14px;
  align-items: center;
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: box-shadow 0.12s, border-color 0.12s, transform 0.06s;
}
.hub-task-row:hover { border-color: var(--navy-700); box-shadow: 0 4px 14px rgba(15,27,45,0.06); }
.hub-task-row:active { transform: scale(0.998); }
.hub-task-row.is-owner { border-left: 4px solid var(--red-700); padding-left: 14px; }
.hub-task-row.is-done { opacity: 0.5; }
.hub-task-row.is-done .hub-task-title { text-decoration: line-through; }

.hub-task-bar {
  width: 4px;
  align-self: stretch;
  border-radius: 2px;
  background: #cbd5e1;
}
.hub-task-bar.priority-high   { background: #f59e0b; }
.hub-task-bar.priority-owner  { background: var(--red-700); }
.hub-task-bar.priority-normal { background: #2563eb; }
.hub-task-bar.priority-low    { background: #94a3b8; }

/* Screen-reader-only utility — used by Hub task rows to spell out
   indicators that would otherwise be conveyed by colour alone
   (priority bar, overdue due-date). */
.hub-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;
}

.hub-task-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--navy-900);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.hub-task-meta {
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 3px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.hub-task-meta strong { color: var(--navy-800); }
.hub-task-source-tag {
  display: inline-block;
  font-size: 10px;
  background: rgba(178, 34, 52, 0.10);
  color: var(--red-700);
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.hub-task-source-tag.tag-pa { background: rgba(37, 99, 235, 0.10); color: #1d4ed8; }
.hub-task-source-tag.tag-other { background: rgba(0,0,0,0.05); color: var(--ink-muted); }

.hub-assignee-stack {
  display: flex;
  gap: 4px;
}
.hub-avatar {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--navy-700);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  display: grid; place-items: center;
  border: 2px solid #fff;
  margin-left: -8px;
  letter-spacing: 0.02em;
}
.hub-avatar.org-yacht     { background: #1e3a5f; }
.hub-avatar.org-office    { background: #b22234; }
.hub-avatar.org-household { background: #0f766e; }
.hub-avatar.org-jet       { background: #7c2d12; }
.hub-avatar.org-security  { background: #4c1d95; }
.hub-avatar.org-external  { background: #6b7280; }
.hub-avatar:first-child { margin-left: 0; }

.hub-task-due {
  font-size: 11px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.hub-task-due.is-overdue { color: var(--danger); font-weight: 700; }

.hub-private-icon {
  font-size: 11px;
  color: var(--ink-muted);
  margin-left: 4px;
}

/* ---------- Task side-panel ---------- */
.hub-task-panel {
  position: fixed;
  top: 0; right: 0;
  width: 100%;
  max-width: 460px;
  height: 100vh;
  height: 100dvh;
  z-index: 1200;
  background: #fff;
  border-left: 1px solid var(--navy-100);
  box-shadow: -16px 0 40px rgba(52, 85, 120, 0.10);
  overflow-y: auto;
  transform: translateX(0);
  transition: transform 0.18s ease-out;
}
.hub-task-panel.hidden { display: block; transform: translateX(110%); pointer-events: none; }
.hub-task-panel-inner { padding: 22px 24px 80px; }
.hub-task-panel-close {
  position: absolute; top: 12px; right: 14px;
  background: transparent; border: 0; font-size: 22px; color: var(--ink-muted); cursor: pointer;
  width: 32px; height: 32px; border-radius: 50%;
}
.hub-task-panel-close:hover { background: #f1f5f9; }
.hub-task-panel h2 {
  font-family: var(--display);
  font-size: 20px;
  margin: 6px 30px 8px 0;
  color: var(--navy-900);
}
.hub-task-detail-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.hub-detail-tag {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  background: #f1f5f9;
  color: var(--navy-800);
}
.hub-detail-tag.is-owner { background: rgba(178, 34, 52, 0.10); color: var(--red-700); font-weight: 700; }

.hub-detail-section {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--navy-100);
}
.hub-detail-h3 {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-muted); margin: 0 0 8px;
}
.hub-detail-body {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
  white-space: pre-wrap;
}
.hub-detail-count {
  display: inline-block;
  margin-left: 6px;
  background: #eef1f5;
  color: var(--ink-muted);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 10px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  vertical-align: middle;
}

/* R41 — Notes editor on the task panel */
.hub-task-desc-editor {
  width: 100%;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  padding: 10px 12px;
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  resize: vertical;
  min-height: 84px;
  background: #fff;
  color: var(--ink);
}
.hub-task-desc-editor:focus {
  outline: none;
  border-color: var(--navy-700);
  box-shadow: 0 0 0 3px rgba(11, 35, 64, 0.08);
}
.hub-task-desc-status {
  font-size: 11px;
  color: var(--ink-muted);
  min-height: 14px;
  margin-top: 4px;
}

/* R41 — Attachments */
.hub-attachments {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}
.hub-attachment-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
  background: #f6f7f9;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  padding: 8px 12px;
}
.hub-attachment-icon { font-size: 18px; line-height: 1; }
.hub-attachment-meta { min-width: 0; }
.hub-attachment-name {
  display: block;
  font-size: 13px;
  color: var(--navy-900);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hub-attachment-name:hover { text-decoration: underline; }
.hub-attachment-sub {
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 2px;
}
.hub-attachment-upload {
  display: inline-block;
  cursor: pointer;
  margin-top: 4px;
}
.hub-attachment-upload input[type=file] {
  display: none;
}

/* R41 — Migrate-to-cloud banner on the directory */
.hub-migrate-banner {
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  background: rgba(196, 30, 30, 0.04);
  border: 1px solid rgba(196, 30, 30, 0.18);
  border-left: 4px solid var(--red-700, #c41e1e);
  border-radius: 10px;
  padding: 12px 16px;
  margin: 14px 0 18px;
  font-size: 13px;
  color: var(--ink);
  flex-wrap: wrap;
}
.hub-migrate-banner strong { color: var(--navy-900); }

/* R41 — Danger zone (delete task) at the bottom of the panel */
.hub-danger-zone {
  border-top: 1px dashed var(--navy-100);
  margin-top: 18px;
  padding-top: 14px;
}
.hub-danger-zone .btn-ghost {
  color: var(--danger, #c0392b);
}

.hub-assignees-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.hub-assignee-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: #f1f5f9;
  border-radius: 999px;
  padding: 4px 10px 4px 4px;
  font-size: 12px;
}
.hub-assignee-chip .hub-avatar { margin: 0; width: 20px; height: 20px; font-size: 9px; border: 0; }
.hub-assignee-chip .x {
  border: 0; background: none; color: var(--ink-muted); cursor: pointer; padding: 0 2px;
}

.hub-status-bar {
  display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 14px;
}
.hub-status-bar button {
  background: #f6f7f9;
  border: 1px solid var(--navy-100);
  border-radius: 6px;
  padding: 6px 12px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  color: var(--ink-muted);
}
.hub-status-bar button.active {
  background: var(--navy-900);
  color: #fff;
  border-color: var(--navy-900);
}

.hub-comments { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.hub-comment {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 10px;
}
.hub-comment .hub-avatar { margin: 0; }
.hub-comment-bubble {
  background: #f6f7f9;
  border-radius: 10px;
  padding: 8px 12px;
}
.hub-comment-head {
  display: flex; gap: 8px; align-items: baseline; margin-bottom: 2px;
}
.hub-comment-head strong { font-size: 12px; color: var(--navy-900); }
.hub-comment-head time { font-size: 10px; color: var(--ink-muted); }
.hub-comment-body { font-size: 13px; color: var(--ink); line-height: 1.45; white-space: pre-wrap; }

.hub-comment-form {
  display: flex; gap: 8px; margin-top: 12px;
}
.hub-comment-form textarea {
  flex: 1;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  padding: 8px 10px;
  font: inherit;
  font-size: 13px;
  resize: vertical;
  min-height: 56px;
}
.hub-comment-form button {
  align-self: flex-end;
  background: var(--red-700);
  color: #fff;
  border: 0;
  border-radius: 8px;
  padding: 8px 16px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

/* ---------- Duplicate warning at create time ---------- */
.hub-dupe-warn {
  background: rgba(245, 158, 11, 0.10);
  border: 1px solid rgba(245, 158, 11, 0.30);
  color: #92400e;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 12px;
  margin-top: 6px;
  margin-bottom: 4px;
}
.hub-dupe-warn strong { color: #78350f; }
.hub-dupe-link {
  display: inline-block; margin-top: 4px; font-size: 11px;
  color: #92400e; text-decoration: underline; cursor: pointer;
}

/* ---------- Assignee picker (chip-style toggle) ---------- */
.hub-assignee-picker {
  display: flex; gap: 6px; flex-wrap: wrap;
  background: #f6f7f9;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  padding: 8px;
  max-height: 160px;
  overflow-y: auto;
}
.hub-assignee-pick {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  user-select: none;
}
.hub-assignee-pick.is-on { background: var(--navy-900); color: #fff; border-color: var(--navy-900); }
.hub-assignee-pick.is-on .hub-avatar { border-color: var(--navy-900); }
.hub-assignee-pick .hub-avatar { margin: 0; width: 18px; height: 18px; font-size: 8px; border: 0; }

.hub-private-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-muted);
}

/* ---------- Directory ---------- */
.hub-dir-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 4px;
}
.hub-dir-card {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 12px;
  padding: 16px;
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 12px;
  align-items: start;
}
.hub-dir-card .hub-avatar { width: 48px; height: 48px; font-size: 16px; margin: 0; border: 0; }
.hub-dir-name { font-weight: 700; font-size: 14px; color: var(--navy-900); margin-bottom: 2px; }
.hub-dir-title { font-size: 12px; color: var(--ink-muted); margin-bottom: 6px; }
.hub-dir-org-tag {
  display: inline-block;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: #f1f5f9;
  color: var(--navy-800);
  padding: 3px 8px;
  border-radius: 999px;
  margin-bottom: 8px;
}
.hub-dir-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.hub-dir-action {
  font-size: 11px;
  color: var(--navy-700);
  background: #f6f7f9;
  border: 1px solid var(--navy-100);
  border-radius: 6px;
  padding: 4px 10px;
  text-decoration: none;
}
.hub-dir-action:hover { background: var(--navy-700); color: #fff; }
.hub-dir-tz {
  font-size: 11px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  margin-top: 4px;
}
.hub-dir-ooo {
  background: rgba(245, 158, 11, 0.12);
  color: #92400e;
  font-size: 11px;
  padding: 6px 8px;
  border-radius: 6px;
  margin-top: 8px;
  grid-column: 1 / -1;
}

/* ---------- Channel (#general) ---------- */
.hub-channel {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 12px;
  padding: 18px 22px;
}
.hub-channel-h {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 12px;
}
.hub-channel-h h2 {
  font-family: var(--display);
  font-size: 20px;
  color: var(--navy-900);
  margin: 0;
}
.hub-channel-h .sub { font-size: 12px; color: var(--ink-muted); }
.hub-channel-feed {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 8px 0;
  max-height: 60vh;
  overflow-y: auto;
  padding-right: 4px;
}
.hub-msg {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 10px;
}
.hub-msg .hub-avatar { margin: 0; }
.hub-msg-head {
  display: flex; gap: 8px; align-items: baseline; margin-bottom: 2px;
}
.hub-msg-head strong { font-size: 13px; color: var(--navy-900); }
.hub-msg-head time { font-size: 11px; color: var(--ink-muted); }
.hub-msg-body { font-size: 14px; color: var(--ink); line-height: 1.5; white-space: pre-wrap; }
.hub-msg-thread { margin-top: 6px; padding-left: 14px; border-left: 2px solid var(--navy-100); display: flex; flex-direction: column; gap: 8px; }

.hub-compose {
  display: flex; gap: 8px; padding-top: 12px;
  border-top: 1px solid var(--navy-100);
}
.hub-compose textarea {
  flex: 1;
  border: 1px solid var(--navy-100);
  border-radius: 10px;
  padding: 10px 12px;
  font: inherit;
  font-size: 13px;
  resize: vertical;
  min-height: 44px;
}
.hub-compose button {
  align-self: flex-end;
  background: var(--red-700);
  color: #fff;
  border: 0;
  border-radius: 10px;
  padding: 10px 18px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.hub-mention {
  display: inline-block;
  background: rgba(178, 34, 52, 0.08);
  color: var(--red-700);
  font-weight: 600;
  padding: 0 4px;
  border-radius: 4px;
}

/* ---------- Empty / gate states ---------- */
.hub-gate {
  max-width: 480px;
  margin: 64px auto;
  padding: 32px;
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 14px;
  text-align: center;
}
.hub-gate h2 {
  font-family: var(--display);
  font-size: 22px;
  margin: 8px 0 6px;
  color: var(--navy-900);
}
.hub-gate p { color: var(--ink-muted); font-size: 13px; line-height: 1.5; }

/* ---------- Mobile tightening ---------- */
@media (max-width: 720px) {
  .hub-header-inner { flex-wrap: wrap; gap: 10px; padding: 10px 14px; }
  .hub-search { order: 3; flex: 1 1 100%; max-width: none; }
  .hub-network-name { display: none; }
  .hub-main { padding: 16px 14px 60px; }
  .hub-task-row { grid-template-columns: 8px 1fr auto; }
  .hub-task-due { grid-column: 1 / -1; text-align: left; padding-left: 22px; }
  .hub-task-panel { max-width: 100%; }
}


/* ============================================================
   INVENTORY  (Round 13)
   Two-pane layout — folder tree on the left, items grid on the right.
   Inspired by general inventory-app conventions (folders + photos +
   quantity + low-stock alerts). All visual language is our own.
   ============================================================ */
.inv-toolbar {
  display: flex;
  gap: 10px;
  align-items: center;
  margin: 12px 0 14px;
  flex-wrap: wrap;
}
.inv-toolbar input[type="search"] {
  flex: 1;
  min-width: 220px;
  padding: 8px 14px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 999px;
  font: inherit;
  font-size: 13px;
  background: #fff;
}
.inv-toolbar input[type="search"]:focus { outline: none; border-color: var(--navy-700); }

.inv-shell {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 18px;
  align-items: start;
}
/* R129 — phone: stack tree on top, content below. The sticky tree pane
   becomes a collapsible header row at narrow widths. */
@media (max-width: 720px) {
  .inv-shell { grid-template-columns: 1fr; }
  .inv-tree-pane { position: static; max-height: 220px; overflow-y: auto; }
}
.inv-tree-pane {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 10px;
  padding: 10px 8px;
  position: sticky;
  top: 80px;
  max-height: calc(100vh - 100px);
  max-height: calc(100dvh - 100px);
  overflow-y: auto;
}
.inv-crumbs {
  font-size: 11px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 4px 8px 8px;
  border-bottom: 1px solid var(--navy-100);
  margin-bottom: 6px;
  word-break: break-word;
}
.inv-crumbs a { color: var(--navy-700); cursor: pointer; }
.inv-crumbs a:hover { text-decoration: underline; }

.inv-tree { display: flex; flex-direction: column; gap: 1px; }
.inv-tree-node {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  font-size: 13px;
  border-radius: 6px;
  cursor: pointer;
  user-select: none;
  color: var(--ink);
}
.inv-tree-node:hover { background: var(--cream); }
.inv-tree-node.is-active { background: rgba(76, 115, 133, 0.08); color: var(--navy-900); font-weight: 600; }
.inv-tree-toggle {
  width: 14px;
  display: inline-block;
  text-align: center;
  font-size: 10px;
  color: var(--ink-muted);
  flex-shrink: 0;
}
.inv-tree-icon { font-size: 14px; flex-shrink: 0; }
.inv-tree-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inv-tree-count {
  font-size: 11px;
  color: var(--ink-muted);
  background: #f1f5f9;
  border-radius: 999px;
  padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.inv-tree-low {
  font-size: 10px;
  background: rgba(225, 29, 46, 0.12);
  color: var(--red-700);
  border-radius: 999px;
  padding: 1px 6px;
  font-weight: 700;
}
.inv-tree-children { padding-left: 14px; display: none; }
.inv-tree-children.is-open { display: flex; flex-direction: column; gap: 1px; }

/* Items pane */
.inv-items-pane { min-width: 0; }
.inv-items-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 4px 4px 12px;
  flex-wrap: wrap;
  gap: 8px;
}
.inv-items-head h2 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  color: var(--navy-900);
}
.inv-items-head .sub { font-size: 12px; color: var(--ink-muted); }

.inv-items-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}
.inv-item-card {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  transition: box-shadow 0.12s, border-color 0.12s, transform 0.06s;
  display: flex;
  flex-direction: column;
}
.inv-item-card:hover { border-color: var(--navy-700); box-shadow: 0 4px 14px rgba(15,27,45,0.08); }
.inv-item-card:active { transform: scale(0.998); }
.inv-item-card.is-low { border-left: 3px solid var(--red-700); }
.inv-item-card.is-out { border-left: 3px solid var(--red-700); opacity: 0.85; }

.inv-thumb {
  aspect-ratio: 4 / 3;
  background: #f1f5f9;
  display: grid;
  place-items: center;
  font-size: 28px;
  color: var(--navy-700);
  overflow: hidden;
}
.inv-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.inv-item-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; }
.inv-item-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy-900);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inv-item-meta { font-size: 11px; color: var(--ink-muted); }
.inv-item-qty-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 4px;
  gap: 6px;
}
.inv-qty-pill {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: #f1f5f9;
  padding: 4px 10px;
  border-radius: 999px;
}
.inv-qty-pill.is-low { background: rgba(225, 29, 46, 0.10); color: var(--red-700); }
.inv-qty-pill.is-out { background: rgba(225, 29, 46, 0.18); color: var(--red-700); }
.inv-qty-controls { display: inline-flex; gap: 4px; }
.inv-qty-btn {
  width: 26px; height: 26px;
  border-radius: 6px;
  border: 1px solid var(--navy-100);
  background: #fff;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  color: var(--navy-700);
  line-height: 1;
}
.inv-qty-btn:hover { background: var(--navy-700); color: #fff; border-color: var(--navy-700); }
.inv-qty-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Side panel (item detail) */
.inv-detail-panel {
  position: fixed;
  top: 0; right: 0;
  width: 100%;
  max-width: 460px;
  height: 100vh;
  height: 100dvh;
  z-index: 1200;
  background: #fff;
  border-left: 1px solid var(--navy-100);
  box-shadow: -16px 0 40px rgba(15,27,45,0.10);
  overflow-y: auto;
  transform: translateX(0);
  transition: transform 0.18s ease-out;
}
.inv-detail-panel.hidden { display: block; transform: translateX(110%); pointer-events: none; }
.inv-detail-inner { padding: 22px 24px 80px; }
.inv-detail-close {
  position: absolute; top: 12px; right: 14px;
  background: transparent; border: 0; font-size: 22px; color: var(--ink-muted); cursor: pointer;
  width: 32px; height: 32px; border-radius: 50%;
}
.inv-detail-close:hover { background: #f1f5f9; }
.inv-detail-photo {
  aspect-ratio: 4/3;
  background: #f1f5f9;
  border-radius: 8px;
  overflow: hidden;
  display: grid;
  place-items: center;
  font-size: 36px;
  color: var(--navy-700);
  margin-bottom: 12px;
}
.inv-detail-photo img { width: 100%; height: 100%; object-fit: cover; }
.inv-detail-name {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  color: var(--navy-900);
  margin: 0 30px 4px 0;
}
.inv-detail-meta {
  font-size: 12px;
  color: var(--ink-muted);
  margin-bottom: 14px;
}
.inv-detail-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 8px;
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px solid var(--navy-100);
}
.inv-detail-row .lbl { color: var(--ink-muted); text-transform: uppercase; font-size: 10px; letter-spacing: 0.06em; padding-top: 2px; }
.inv-detail-row .val { color: var(--ink); }
.inv-detail-actions {
  display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap;
}
.inv-detail-h3 {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-muted); margin: 16px 0 8px;
}

/* Photo preview inside the modal */
.inv-photo-preview {
  margin-top: 8px;
  width: 140px;
  aspect-ratio: 4/3;
  background: #f1f5f9;
  border-radius: 6px;
  overflow: hidden;
}
.inv-photo-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Mobile */
@media (max-width: 720px) {
  .inv-shell { grid-template-columns: 1fr; }
  .inv-tree-pane { position: static; max-height: 220px; }
  .inv-detail-panel { max-width: 100%; }
}


/* ============================================================
   STANDING ORDERS  (Round 11)
   ============================================================ */
.so-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 22px 26px;
  margin-bottom: 14px;
}
.so-meta {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.so-h2 { margin: 0 0 4px; font-size: 18px; color: var(--navy-900); font-family: var(--display); }
.so-h3 { margin: 0 0 12px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); }
.so-version { font-size: 12px; color: var(--ink-muted); }
.so-body {
  background: #fafbfc;
  border-left: 3px solid var(--navy-700);
  padding: 16px 20px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
  border-radius: 0 8px 8px 0;
  white-space: pre-wrap;
}
.so-ack-zone { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--navy-100); }
.so-ack-mine { background: rgba(22, 101, 52, 0.08); color: #166534; padding: 10px 14px; border-radius: 8px; font-size: 13px; }
.so-ack-tick { font-weight: 700; margin-right: 6px; }
.so-ack-form { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.so-ack-form .field { flex: 1 1 200px; min-width: 200px; }
.so-ack-list { display: flex; flex-direction: column; gap: 4px; }
.so-ack-row {
  display: grid;
  grid-template-columns: 1.5fr 1.2fr 1fr;
  gap: 12px;
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px solid var(--navy-100);
}
.so-ack-row:last-child { border-bottom: 0; }
.so-ack-name { font-weight: 600; color: var(--navy-900); }
.so-ack-when { color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.so-ack-slot { color: var(--ink-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }


/* ============================================================
   BUNKERING LOG  (Round 11)
   ============================================================ */
#bunker-list { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.bunker-row {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 12px;
  padding: 14px 18px;
}
.bunker-row.is-flag { border-left: 4px solid var(--danger, #b91c1c); }
.bunker-row-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: baseline;
  margin-bottom: 6px;
}
.bunker-port { color: var(--navy-700); font-size: 13px; }
.bunker-supplier { color: var(--ink-muted); font-size: 13px; }
.bunker-row-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 13px;
  color: var(--ink);
}
.bunker-row-meta strong { color: var(--navy-900); }
.bunker-variance {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 6px;
}
.bunker-variance.is-flag { color: var(--danger); font-weight: 700; }
.bunker-notes { font-size: 12px; color: var(--ink-muted); font-style: italic; margin-top: 6px; }


/* ============================================================
   MARPOL LOGS  (Round 11)
   ============================================================ */
#marpol-list { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.marpol-row {
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 12px;
  padding: 14px 18px;
  border-left: 3px solid var(--navy-700);
}
.marpol-row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.marpol-code {
  font-size: 12px;
  background: var(--navy-100);
  padding: 4px 10px;
  border-radius: 999px;
  color: var(--navy-800);
  font-weight: 600;
}
.marpol-row-meta {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--ink-muted);
  margin-bottom: 6px;
}
.marpol-row-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
}


/* ============================================================
   TO-DO LISTS  (Round 10 — Module C)
   ============================================================ */

.todo-quickadd {
  display: flex;
  gap: 8px;
  margin: 8px 0 14px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 10px 12px;
  align-items: center;
}
.todo-quickadd input[type="text"] {
  flex: 1;
  border: 0;
  font: inherit;
  font-size: 14px;
  padding: 6px 4px;
  background: transparent;
  outline: none;
}
.todo-readonly-note {
  font-size: 12px;
  color: var(--ink-muted);
  font-style: italic;
  background: #f8fafc;
  border: 1px dashed var(--navy-100);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 8px 0 14px;
}

#todos-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.todo-row {
  display: grid;
  grid-template-columns: 14px 22px 1fr auto auto auto;
  gap: 12px;
  align-items: center;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 14px;
  transition: box-shadow 0.12s, border-color 0.12s;
}
.todo-row:hover { border-color: var(--navy-700); box-shadow: 0 4px 14px rgba(15,27,45,0.06); }
.todo-row.is-done { opacity: 0.55; }
.todo-row.is-done .todo-title-btn { text-decoration: line-through; color: var(--ink-muted); }

.todo-priority-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--ink-muted, #94a3b8);
}
.todo-priority-dot.priority-high   { background: var(--danger); box-shadow: 0 0 0 3px rgba(185,28,28,0.12); }
.todo-priority-dot.priority-normal { background: #2563eb; }
.todo-priority-dot.priority-low    { background: #94a3b8; }

.todo-check {
  width: 18px; height: 18px;
  cursor: pointer;
  accent-color: var(--red-700, #b22234);
}
.todo-check:disabled { cursor: not-allowed; opacity: 0.5; }

.todo-title-btn {
  background: transparent;
  border: 0;
  text-align: left;
  font: inherit;
  font-size: 14px;
  color: var(--ink, #38617A);
  cursor: pointer;
  padding: 4px 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.todo-title-btn:hover { color: var(--red-700); }

.todo-recur {
  display: inline-block;
  font-size: 12px;
  color: var(--ink-muted);
  background: #f1f5f9;
  border-radius: 50%;
  width: 18px; height: 18px;
  text-align: center;
  line-height: 18px;
}

.todo-assignee {
  font-size: 12px;
  font-weight: 600;
  background: #f1f5f9;
  border-radius: 999px;
  padding: 4px 10px;
  color: var(--navy-800);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}
.todo-assignee-dept { background: #fef3c7; color: #78350f; }

.todo-due {
  font-size: 12px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.todo-due.is-overdue { color: var(--danger, #b91c1c); font-weight: 700; }
.todo-due-none { font-style: italic; }

.todo-status {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.todo-status-open        { background: #e0e7ff; color: #3730a3; }
.todo-status-in_progress { background: #d1fae5; color: #065f46; }
.todo-status-done        { background: #f1f5f9; color: var(--ink-muted); }
.todo-status-cancelled   { background: #fee2e2; color: #7f1d1d; }

/* Home widget card wrapper */
.home-todos-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 14px;
  /* Same overflow trap as .bridge-card — without min-width:0 a long
     task title forces this grid column past its fr-ratio share. */
  min-width: 0;
  overflow: hidden;
}
.home-todo-row { min-width: 0; }

/* Home widget — "My tasks today" */
#home-my-todos {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.home-todo-row {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  background: #fff;
  border: 1px solid var(--navy-100);
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.12s;
}
.home-todo-row:hover { border-color: var(--navy-700); }
.home-todo-row.is-overdue { border-left: 3px solid var(--danger, #b91c1c); }
.home-todo-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-todo-due {
  font-size: 11px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.home-todo-due.is-overdue { color: var(--danger); font-weight: 700; }
.home-todo-empty {
  font-size: 13px;
  color: var(--ink-muted);
  background: #f8fafc;
  border: 1px dashed var(--navy-100);
  border-radius: 8px;
  padding: 16px;
  text-align: center;
}

@media (max-width: 720px) {
  .todo-row {
    grid-template-columns: 14px 22px 1fr;
    gap: 10px;
    row-gap: 6px;
  }
  .todo-row .todo-assignee,
  .todo-row .todo-due,
  .todo-row .todo-status {
    grid-column: 3 / -1;
    justify-self: flex-start;
  }
}


/* ============================================================
   GUEST PORTAL  (Round 10 — Module B)
   The trip-specific guest view. Standalone shell — sits parallel
   to the crew #portal-view and the #kiosk-view; routed via #/guest.
   Visual language: lighter, warmer, less dense than the crew portal.
   ============================================================ */

#guest-view {
  /* Same pattern as #kiosk-view: raw display:flex, .hidden with !important
     wins when the view is off-screen. App.show()/hide() toggles .hidden. */
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  background: linear-gradient(180deg, #f7f5f0 0%, #ecf2f7 100%);
  color: var(--ink, #38617A);
}

/* --- Public landing (code entry) ------------------------------ */
.guest-landing {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  background:
    radial-gradient(1200px 600px at 50% -100px, rgba(178, 34, 52, 0.08), transparent 70%),
    linear-gradient(180deg, #fff 0%, #f7f5f0 100%);
}
.guest-landing-card {
  width: 100%;
  max-width: 480px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 16px;
  box-shadow: 0 16px 40px rgba(52, 85, 120, 0.10);
  padding: 36px 32px;
  text-align: center;
}
.guest-landing-card .wordmark {
  height: 38px;
  margin-bottom: 18px;
}
.guest-landing-card h1 {
  font-family: var(--display);
  font-size: 26px;
  margin: 4px 0 6px;
  color: var(--navy-900, #38617A);
  letter-spacing: 0.02em;
}
.guest-landing-card .lede {
  color: var(--ink-muted, #64748b);
  font-size: 14px;
  margin-bottom: 22px;
  line-height: 1.5;
}
.guest-code-form { display: grid; gap: 12px; }
.guest-code-form input {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  font: inherit;
  font-size: 18px;
  letter-spacing: 0.18em;
  text-align: center;
  text-transform: uppercase;
  background: #fafbfc;
}
.guest-code-form input:focus {
  outline: none;
  border-color: var(--navy-700);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(52, 85, 120, 0.08);
}
.guest-code-form button {
  padding: 14px 16px;
  border-radius: 10px;
  border: 0;
  background: var(--red-700, #b22234);
  color: #fff;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  transition: filter 0.12s, transform 0.06s;
}
.guest-code-form button:hover { filter: brightness(1.06); }
.guest-code-form button:active { transform: scale(0.98); }
.guest-code-error {
  color: var(--danger, #b91c1c);
  font-size: 13px;
  margin-top: 6px;
  min-height: 1.2em;
}
.guest-landing-foot {
  margin-top: 22px;
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  line-height: 1.5;
}
.guest-landing-foot a { color: inherit; text-decoration: underline; }

/* --- Authenticated guest shell -------------------------------- */
.guest-header {
  position: sticky;
  top: 0;
  z-index: 1100;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 22px;
  background: var(--navy-900, #38617A);
  color: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.18);
}
.guest-header .wordmark { height: 26px; }
.guest-header .guest-trip-name {
  font-family: var(--display);
  font-size: 16px;
  letter-spacing: 0.02em;
  margin-left: 6px;
}
.guest-header .guest-trip-dates {
  margin-left: auto;
  font-size: 12px;
  opacity: 0.78;
  letter-spacing: 0.02em;
}
.guest-header .guest-exit {
  margin-left: 12px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.16);
  color: #fff;
  font: inherit;
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 8px;
  cursor: pointer;
}
.guest-header .guest-exit:hover { background: rgba(255,255,255,0.16); }

.guest-nav {
  position: sticky;
  top: 50px;
  z-index: 1099;
  display: flex;
  gap: 4px;
  padding: 6px 14px;
  background: rgba(255,255,255,0.96);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  overflow-x: auto;
}
.guest-nav button {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  padding: 10px 14px;
  border-radius: 8px;
  color: var(--ink-muted, #64748b);
  font: inherit;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.guest-nav button:hover { background: rgba(15,27,45,0.05); color: var(--ink); }
.guest-nav button.active {
  background: var(--navy-900);
  color: #fff;
}

.guest-main {
  flex: 1;
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 28px 22px 60px;
}
.guest-page-title {
  font-family: var(--display);
  font-size: 26px;
  letter-spacing: 0.02em;
  color: var(--navy-900);
  margin: 4px 0 18px;
}
.guest-page-lede {
  color: var(--ink-muted);
  font-size: 14px;
  line-height: 1.55;
  margin-bottom: 22px;
  max-width: 720px;
}

/* --- Welcome / Home page -------------------------------------- */
.guest-hero {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  margin-bottom: 22px;
  background: linear-gradient(135deg, #1e3a5f 0%, #b22234 100%);
  color: #fff;
  padding: 36px 32px;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  box-shadow: 0 8px 24px rgba(15,27,45,0.18);
}
.guest-hero::before {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(800px 400px at 80% 20%, rgba(255,255,255,0.18), transparent 70%),
    radial-gradient(500px 300px at 10% 90%, rgba(0,0,0,0.18), transparent 70%);
  pointer-events: none;
}
.guest-hero h2 {
  position: relative;
  font-family: var(--display);
  font-size: 32px;
  margin: 0 0 6px;
  letter-spacing: 0.02em;
}
.guest-hero .guest-hero-sub {
  position: relative;
  font-size: 14px;
  opacity: 0.92;
}

.guest-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
  margin-bottom: 28px;
}
.guest-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  padding: 18px;
  cursor: pointer;
  transition: transform 0.08s, box-shadow 0.12s, border-color 0.12s;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.guest-card:hover {
  border-color: var(--navy-700);
  box-shadow: 0 6px 20px rgba(15,27,45,0.10);
  transform: translateY(-1px);
}
.guest-card .icon {
  font-size: 22px;
  line-height: 1;
  margin-bottom: 4px;
}
.guest-card h3 {
  font-size: 15px;
  font-weight: 700;
  margin: 0;
  color: var(--navy-900);
}
.guest-card p {
  font-size: 13px;
  color: var(--ink-muted);
  margin: 0;
  line-height: 1.45;
}

/* --- Preferences form ---------------------------------------- */
.guest-form {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  padding: 22px 24px;
  display: grid;
  gap: 16px;
}
.guest-form-row {
  display: grid;
  gap: 6px;
}
.guest-form-row.two {
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.guest-form-row label {
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-800);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.guest-form-row input,
.guest-form-row textarea,
.guest-form-row select {
  width: 100%;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  padding: 10px 12px;
  font: inherit;
  font-size: 14px;
  background: #fafbfc;
  color: var(--ink);
}
.guest-form-row textarea { min-height: 80px; resize: vertical; }
.guest-form-row input:focus,
.guest-form-row textarea:focus,
.guest-form-row select:focus {
  outline: none;
  border-color: var(--navy-700);
  background: #fff;
}
.guest-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
}
.guest-form-actions .save-btn {
  background: var(--red-700, #b22234);
  color: #fff;
  border: 0;
  border-radius: 8px;
  padding: 10px 20px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.guest-form-actions .save-btn:hover { filter: brightness(1.08); }
.guest-save-flash {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--success, #15803d);
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.2s;
}
.guest-save-flash.is-show { opacity: 1; }

/* --- Itinerary timeline -------------------------------------- */
.guest-itin {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  padding: 6px 0;
  overflow: hidden;
}
.guest-itin-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 16px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.guest-itin-row:last-child { border-bottom: 0; }
.guest-itin-date {
  font-weight: 700;
  color: var(--navy-900);
  font-size: 14px;
  line-height: 1.3;
}
.guest-itin-date .day {
  display: block;
  font-size: 11px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.guest-itin-body { font-size: 14px; line-height: 1.55; color: var(--ink); }
.guest-itin-body strong { color: var(--navy-900); }

/* --- Crew page ----------------------------------------------- */
.guest-crew-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
}
.guest-crew-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 14px;
  padding: 18px 14px;
  text-align: center;
}
.guest-crew-avatar {
  width: 76px;
  height: 76px;
  border-radius: 50%;
  margin: 0 auto 10px;
  background: var(--navy-100, #DCE7ED);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 22px;
  color: var(--navy-700);
  letter-spacing: 0.02em;
  overflow: hidden;
}
.guest-crew-avatar img {
  width: 100%; height: 100%; object-fit: cover;
}
.guest-crew-name {
  font-weight: 700;
  font-size: 14px;
  color: var(--navy-900);
  margin: 0 0 2px;
}
.guest-crew-position {
  font-size: 12px;
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* --- Photos gallery ------------------------------------------ */
.guest-photos-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.guest-photos-toolbar .count {
  font-size: 13px;
  color: var(--ink-muted);
}
.guest-photos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}
.guest-photo-tile {
  position: relative;
  aspect-ratio: 1;
  background: var(--navy-100, #DCE7ED);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.08s, box-shadow 0.12s;
}
.guest-photo-tile:hover { transform: scale(1.02); box-shadow: 0 8px 18px rgba(15,27,45,0.16); }
.guest-photo-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.guest-photo-tile .caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 10px 8px;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.55) 100%);
  color: #fff;
  font-size: 12px;
  line-height: 1.3;
}
.guest-photo-empty {
  background: #fff;
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 36px 22px;
  text-align: center;
  color: var(--ink-muted);
  font-size: 14px;
}
.guest-photo-empty .icon { font-size: 28px; margin-bottom: 6px; opacity: 0.4; }

/* Photo lightbox */
.guest-lightbox {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.85);
  z-index: 2400;
  display: grid;
  place-items: center;
  padding: 24px;
}
.guest-lightbox img {
  max-width: 90vw;
  max-height: 80vh;
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
.guest-lightbox .close {
  position: absolute; top: 16px; right: 16px;
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.24);
  color: #fff;
  font-size: 22px;
  width: 40px; height: 40px;
  border-radius: 50%;
  cursor: pointer;
}
.guest-lightbox .caption {
  position: absolute; left: 0; right: 0; bottom: 16px;
  text-align: center;
  color: #fff;
  font-size: 13px;
  padding: 0 24px;
}

/* --- Captain-side: invite drawer ------------------------------ */
.invite-list {
  display: grid;
  gap: 8px;
  margin: 12px 0;
}
.invite-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: #f8fafc;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  font-size: 13px;
}
.invite-row .name { font-weight: 600; }
.invite-row .name small {
  display: block;
  font-weight: 400;
  color: var(--ink-muted);
  font-size: 11px;
  letter-spacing: 0.06em;
}
.invite-row .code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  padding: 4px 8px;
  border-radius: 6px;
  color: var(--navy-900);
  cursor: pointer;
}
.invite-row .copy-btn {
  background: var(--navy-700);
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: 6px 10px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.invite-row.is-revoked { opacity: 0.5; text-decoration: line-through; }

/* --- Mobile tightening --------------------------------------- */
@media (max-width: 640px) {
  .guest-header { flex-wrap: wrap; padding: 10px 14px; gap: 8px; }
  .guest-header .guest-trip-dates { width: 100%; margin-left: 0; opacity: 0.7; }
  .guest-header .guest-exit { margin-left: auto; }
  .guest-main { padding: 18px 14px 50px; }
  .guest-page-title { font-size: 22px; }
  .guest-hero { padding: 22px; min-height: 160px; }
  .guest-hero h2 { font-size: 24px; }
  .guest-form-row.two { grid-template-columns: 1fr; gap: 16px; }
  .guest-itin-row { grid-template-columns: 80px 1fr; padding: 14px 16px; }
  .guest-crew-grid { grid-template-columns: repeat(2, 1fr); }
  .guest-photos-grid { grid-template-columns: repeat(2, 1fr); }
  .guest-landing-card { padding: 28px 22px; }
}


/* ============================================================
   MOBILE RESPONSIVENESS SWEEP (Round 12 follow-up, 2026-04-29)
   Catches everything the per-module @media blocks missed when the
   audit ran. Two breakpoints in play here:
     720px — "phone or narrow tablet": stack the most aggressive
              two-column grids.
     440px — "small phone (iPhone SE / 375px)": flatten more layouts
              and cap modal width.
   These intentionally come last in the file so they win the cascade
   without needing higher-specificity selectors.
   ============================================================ */

@media (max-width: 720px) {
  /* Most form rows are 2 cols on desktop. On a phone, stack. */
  .form-row { grid-template-columns: 1fr; gap: 8px; }

  /* Standing orders ack list — 3-column grid on desktop, stack on phone */
  .so-ack-row {
    grid-template-columns: 1fr;
    gap: 2px;
    padding: 8px 0;
  }
  .so-ack-when, .so-ack-slot { font-size: 11px; }

  /* Bunkering log row head: stack supplier and port under date */
  .bunker-row-head { flex-direction: column; align-items: flex-start; gap: 4px; }

  /* MARPOL row head: stack the code badge under the timestamp */
  .marpol-row-head { flex-direction: column; align-items: flex-start; gap: 6px; }

  /* Captain-side guest-invite list (Cruises modal): stack name / code / button */
  .invite-row {
    grid-template-columns: 1fr;
    gap: 8px;
    align-items: flex-start;
  }
  .invite-row .code,
  .invite-row .copy-btn { justify-self: flex-start; }
}

@media (max-width: 440px) {
  /* Cap modal cards so they never paint outside the viewport. The default
     `max-width: 560px` was wider than an iPhone SE viewport. */
  .modal-card { max-width: 92vw; }

  /* Hub task row: at the very smallest widths, the assignee stack still
     pinches — fold it under the title. */
  .hub-task-row { grid-template-columns: 8px 1fr; row-gap: 6px; }
  .hub-assignee-stack { grid-column: 2 / -1; }
  .hub-task-due { grid-column: 2 / -1; text-align: left; padding-left: 0; }

  /* To-do assignee chip max-width vs phone width — keep it small */
  .todo-assignee { max-width: 110px; }
}

/* ============================================================
   R34 P3 — Reusable skeleton loaders + empty states
   ============================================================
   Skeletons replace the harsh blank-then-content flash on async
   pages. Apply `.skeleton` to any block to make it pulse with a
   navy-cream gradient. Helper shapes: .skeleton-line (text bar),
   .skeleton-card (full panel), .skeleton-thumb (inventory tile).
   ============================================================ */
@keyframes skeleton-pulse {
  0%   { opacity: 0.55; }
  50%  { opacity: 1; }
  100% { opacity: 0.55; }
}
.skeleton {
  position: relative;
  background:
    linear-gradient(90deg,
      rgba(222, 229, 238, 0.45) 0%,
      rgba(222, 229, 238, 0.85) 50%,
      rgba(222, 229, 238, 0.45) 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 6px;
}
@keyframes skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.skeleton-line {
  display: block;
  height: 12px;
  margin: 6px 0;
  border-radius: 4px;
}
.skeleton-line.is-short { width: 35%; }
.skeleton-line.is-medium { width: 60%; }
.skeleton-line.is-long { width: 90%; }
.skeleton-card {
  height: 120px;
  border-radius: 10px;
  margin-bottom: 12px;
}
.skeleton-thumb {
  aspect-ratio: 1;
  border-radius: 8px;
}

/* Empty state — module-empty-v2 — refined visual treatment with a
   centered icon zone, larger headline, friendlier copy, and an
   optional CTA. Adopt module-by-module without disturbing the old
   .module-empty / .empty-state classes still in use elsewhere. */
.module-empty-v2 {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 60px 24px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 12px;
  margin: 16px 0;
}
.module-empty-v2 .empty-glyph {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1px var(--hairline);
  display: flex; align-items: center; justify-content: center;
  color: var(--navy-700, #4A7791);
}
.module-empty-v2 .empty-glyph .ic { width: 24px; height: 24px; stroke-width: 1.4; opacity: 0.85; }
.module-empty-v2 h2 {
  margin: 0;
  font: var(--type-h2);
  color: var(--navy-900, #284558);
}
.module-empty-v2 p {
  margin: 0;
  max-width: 460px;
  font: var(--type-body);
  color: var(--ink-soft, #4A5568);
}
.module-empty-v2 .empty-cta {
  margin-top: 6px;
}

/* ============================================================
   LAUNDRY TRACKER (R39 — Interior team)
   Status board for guest laundry. Reuses .cert-kpi / .cert-chip
   from the certs module so KPI tiles + filter chips look identical
   to Drills, Cruises, etc.
   ============================================================ */

/* The cabin chip row sits below the stage filters. Smaller, pill-shaped,
   distinct hue so the user reads it as a SECONDARY filter. */
.laundry-cabin-toolbar {
  margin: -8px 0 16px;
  padding: 0;
}
.laundry-cabin-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.laundry-cabin-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--navy-100, #DCE7ED);
  background: #F8FAFC;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft, #475569);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.laundry-cabin-chip:hover {
  background: #fff;
  border-color: var(--navy-700, #1F3A60);
  color: var(--navy-900, #38617A);
}
.laundry-cabin-chip.active {
  background: var(--navy-900, #38617A);
  color: #fff;
  border-color: var(--navy-900, #38617A);
}

/* The status-board grid is responsive auto-fill cards. On phone we
   collapse to a single column so each card is comfortably tappable. */
.laundry-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 14px;
}

/* Individual item card. The left border is colour-coded by stage so
   the eye groups them quickly even when the chips aren't filtered. */
.laundry-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-left: 4px solid #B7791F;
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: 0 1px 3px rgba(52, 85, 120, 0.04);
  transition: box-shadow 0.15s, transform 0.15s;
}
.laundry-card:hover {
  box-shadow: 0 4px 14px rgba(52, 85, 120, 0.08);
  transform: translateY(-1px);
}
.laundry-card.stage-received    { border-left-color: #B7791F; }
.laundry-card.stage-sorting     { border-left-color: #6B46C1; }
.laundry-card.stage-washing     { border-left-color: #1F6FB2; }
.laundry-card.stage-drycleaning { border-left-color: #2F6E3B; }
.laundry-card.stage-refresh     { border-left-color: #1B7A6E; }
.laundry-card.stage-pressing    { border-left-color: #A4452A; }
.laundry-card.stage-ready       { border-left-color: #246C2E; background: #F4FBF6; }
.laundry-card.stage-returned    { border-left-color: #54667A; opacity: 0.72; }
.laundry-card.stage-damaged     { border-left-color: #A02525; background: #FFF6F6; }
.laundry-card.stage-lost        { border-left-color: #1A1A1A; background: #F2F2F2; }

/* Pulsing red halo when an in-house item has been here >24h. */
.laundry-card.is-overdue {
  animation: laundryOverdueHalo 2.4s ease-in-out infinite;
}
@keyframes laundryOverdueHalo {
  0%, 100% { box-shadow: 0 1px 3px rgba(52, 85, 120, 0.04); }
  50%      { box-shadow: 0 0 0 3px rgba(160, 37, 37, 0.16), 0 4px 12px rgba(160, 37, 37, 0.10); }
}

.laundry-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.laundry-cabin-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--navy-900, #38617A);
  background: var(--navy-50, #F2F5F9);
  padding: 3px 8px;
  border-radius: 6px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.laundry-cabin-emoji { font-size: 13px; line-height: 1; }
.laundry-stage-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: #1A1A1A;
}
.laundry-stage-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  display: inline-block;
}

.laundry-item-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--navy-900, #38617A);
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.laundry-qty {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft, #475569);
  background: #F1F5F9;
  padding: 2px 6px;
  border-radius: 4px;
}
.laundry-item-desc {
  font-size: 13px;
  color: var(--ink-soft, #475569);
  line-height: 1.4;
}
.laundry-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.laundry-svc-pill, .laundry-principal-pill, .laundry-meta-tag {
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
  background: #F1F5F9;
  color: var(--navy-900, #38617A);
  white-space: nowrap;
}
.laundry-svc-pill { font-weight: 600; }
.laundry-principal-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 10px;
}
.laundry-care     { background: #FFF7E6; color: #7A5500; }
.laundry-overdue-tag {
  background: #FDE2E2;
  color: #A02525;
  font-weight: 600;
}
.laundry-deadline-tag {
  background: #FDF1E6;
  color: #7A4A00;
  font-weight: 600;
}
.laundry-deadline-tag.is-overdue {
  background: #FDE2E2;
  color: #A02525;
  animation: laundryDeadlinePulse 1.4s ease-in-out infinite;
}
@keyframes laundryDeadlinePulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.04); }
}
.laundry-damaged-tag {
  background: #1A1A1A;
  color: #fff;
  font-weight: 600;
}

/* Card-level deadline-overdue tint (stronger than aged) */
.laundry-card.is-deadline-overdue {
  border-left-color: #A02525;
  background: #FFF6F6;
}

/* Cabin tag becomes clickable — adds the affordance */
.laundry-cabin-tag[role="button"] {
  cursor: pointer;
  user-select: none;
}
.laundry-cabin-tag[role="button"]:hover {
  background: var(--navy-100, #DCE7ED);
}

/* ---------- Cabin wash-history drawer ---------- */
.laundry-history-drawer {
  position: fixed;
  inset: 0;
  z-index: 940;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.laundry-history-drawer.is-open {
  pointer-events: auto;
  opacity: 1;
}
.laundry-history-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(52, 85, 120, 0.32);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.laundry-history-panel {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 420px;
  max-width: 92vw;
  background: #fff;
  box-shadow: -8px 0 30px rgba(52, 85, 120, 0.18);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.24s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.laundry-history-drawer.is-open .laundry-history-panel { transform: translateX(0); }
.laundry-history-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
}
.laundry-history-head h3 {
  margin: 0;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.laundry-history-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.laundry-history-empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--ink-soft, #475569);
  font-size: 13px;
}
.laundry-history-row {
  background: #F8FAFC;
  border: 1px solid #E2E8F0;
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.laundry-history-row:hover {
  background: #fff;
  border-color: var(--navy-700, #1F3A60);
}
.laundry-history-row-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}
.laundry-history-row-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 13px;
}
.laundry-history-row-body strong {
  color: var(--navy-900, #38617A);
}
.laundry-history-meta {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}
.laundry-history-notes {
  font-size: 11px;
  color: var(--ink-soft, #475569);
  font-style: italic;
}
.laundry-history-row-actions {
  flex-shrink: 0;
}
body.laundry-drawer-open { overflow: hidden; }

@media (max-width: 640px) {
  .laundry-history-panel {
    width: 100%;
    max-width: 100%;
  }
}

.laundry-item-notes {
  font-size: 12px;
  color: var(--ink-muted, #64748b);
  font-style: italic;
  border-top: 1px dashed #E2E8F0;
  padding-top: 6px;
  line-height: 1.4;
}

.laundry-card-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.laundry-age {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
  letter-spacing: 0.02em;
}
.laundry-card-actions {
  display: flex;
  gap: 6px;
}

/* ---------- Batch modal ---------- */
.laundry-batch-card {
  max-width: 720px;
  width: 100%;
}
.laundry-scratch-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin: 18px 0 6px;
  padding-top: 16px;
  border-top: 1px solid #E2E8F0;
}
.laundry-scratch-head h4 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-900, #38617A);
}
.laundry-scratch-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}
/* The Smart Scan trigger is a <label> wrapping a hidden file input
   so the iOS native camera picker fires on tap. Style it like a btn. */
.laundry-scan-trigger {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
.laundry-scan-status {
  font-size: 12px;
  color: var(--navy-700, #1F3A60);
  font-style: italic;
  padding: 4px 0;
  min-height: 16px;
}
.laundry-scratch {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 420px;
  overflow-y: auto;
  padding: 6px 2px;
}
.laundry-scratch-empty {
  padding: 18px;
  text-align: center;
  background: #F8FAFC;
  border-radius: 8px;
  color: var(--ink-soft, #475569);
  font-size: 13px;
  border: 1px dashed #E2E8F0;
}
.laundry-scratch-row {
  background: #F8FAFC;
  border: 1px solid #E2E8F0;
  border-radius: 10px;
  padding: 10px 12px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.laundry-scratch-grid {
  display: grid;
  grid-template-columns: 1.4fr 0.6fr 0.8fr 1fr;
  gap: 8px;
}
.laundry-scratch-row .field {
  font-size: 12px;
}
.laundry-scratch-row .field span {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted, #64748b);
}
.laundry-scratch-row .field input,
.laundry-scratch-row .field select {
  font-size: 13px;
  padding: 6px 8px;
}
.laundry-scratch-remove {
  align-self: flex-end;
  margin-top: 4px;
  color: #A02525;
}

.laundry-item-context {
  font-size: 13px;
  color: var(--ink-soft, #475569);
  padding: 8px 0 14px;
  border-bottom: 1px solid #E2E8F0;
  margin-bottom: 14px;
}

/* Mobile: collapse the scratch grid + tighten the card footer */
@media (max-width: 640px) {
  .laundry-board {
    grid-template-columns: 1fr;
  }
  .laundry-scratch-grid {
    grid-template-columns: 1fr 1fr;
  }
  .laundry-batch-card {
    max-width: 100%;
  }
  .laundry-card-foot {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
  }
  .laundry-card-actions {
    justify-content: stretch;
  }
  .laundry-card-actions .btn {
    flex: 1;
    min-height: 40px;
  }
}

/* =============================================================
   BOOK OF KNOWLEDGE  (R40)
   Two-pane wiki: sticky sidebar TOC + scrolling content. Drops
   to a slide-in drawer for the TOC at ≤900px. Sensitive content
   uses .bok-secret pills that mask values until clicked.
   ============================================================= */
#page-book .bok-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 16px;
  justify-content: space-between;
}
#page-book .bok-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.bok-search-input {
  width: 260px;
  max-width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 8px;
  background: var(--surface, #ffffff);
  font: inherit;
  font-size: 14px;
  color: var(--ink, #284558);
}
.bok-search-input:focus {
  outline: none;
  border-color: var(--accent, #d63438);
  box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.18);
}
#bok-toc-toggle { display: none; }

.bok-shell {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 24px;
  align-items: stretch;
  margin-top: 16px;
  /* Lock the inner scroll to roughly the visible viewport so the
     TOC stays sticky while content scrolls. Account for the portal
     header (~60px) + page header (~110px) + breathing room. */
  min-height: calc(100vh - 220px);
  min-height: calc(100dvh - 220px);
}
.bok-toc {
  position: sticky;
  top: 80px;
  align-self: start;
  height: calc(100vh - 110px);
  height: calc(100dvh - 110px);
  overflow-y: auto;
  background: var(--surface, #ffffff);
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 12px;
  padding: 14px 12px;
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.04);
}
.bok-toc-inner { display: flex; flex-direction: column; gap: 6px; }
.bok-toc-group { display: flex; flex-direction: column; gap: 2px; }
.bok-toc a {
  display: block;
  text-decoration: none;
  color: var(--ink, #284558);
  padding: 7px 10px;
  border-radius: 7px;
  font-size: 13.5px;
  line-height: 1.35;
  transition: background 120ms ease, color 120ms ease;
}
.bok-toc a:hover { background: rgba(40, 69, 88, 0.06); }
.bok-toc a.active {
  background: rgba(214, 52, 56, 0.10);
  color: var(--accent, #d63438);
  font-weight: 600;
}
.bok-toc a.dim { opacity: 0.35; }
.bok-toc-top { font-weight: 600; letter-spacing: 0.01em; }
.bok-toc-children {
  list-style: none;
  margin: 0 0 4px 12px;
  padding: 0;
  border-left: 2px solid var(--line, #e2e8ec);
}
.bok-toc-children li { margin: 0; padding: 0; }
.bok-toc-children a { font-size: 13px; padding-left: 14px; font-weight: 500; }

.bok-toc-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(40, 69, 88, 0.42);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 60;
  display: none;
}

.bok-content {
  background: var(--surface, #ffffff);
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 12px;
  padding: 8px 28px 32px;
  overflow-y: auto;
  max-height: calc(100vh - 110px);
  max-height: calc(100dvh - 110px);
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.04);
  scroll-behavior: smooth;
}

.bok-section {
  padding: 28px 0 12px;
  border-bottom: 1px solid var(--line, #eef0f3);
  scroll-margin-top: 24px;
}
.bok-section:last-child { border-bottom: 0; }
.bok-section.is-child { padding-left: 18px; border-left: 3px solid var(--line, #eef0f3); }
.bok-section.bok-hidden { display: none; }

.bok-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  justify-content: space-between;
  margin-bottom: 8px;
}
.bok-section-head h2 {
  margin: 0;
  font-size: 22px;
  letter-spacing: 0.01em;
  color: var(--ink, #284558);
}
.bok-section.is-child .bok-section-head h2 { font-size: 18px; }
.bok-section-sensitive {
  display: inline-block;
  margin-left: 10px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #b03030;
  background: rgba(214, 52, 56, 0.10);
  border: 1px solid rgba(214, 52, 56, 0.25);
  border-radius: 999px;
  vertical-align: middle;
}
.bok-section-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: var(--ink-muted, #5f7385);
}
.bok-edit-btn {
  background: transparent;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 7px;
  padding: 5px 10px;
  font: inherit;
  font-size: 12.5px;
  color: var(--ink, #284558);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.bok-edit-btn:hover {
  background: rgba(40, 69, 88, 0.05);
  border-color: var(--ink, #284558);
}

.bok-section-body {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink, #284558);
}
.bok-section-body p { margin: 0 0 12px; }
.bok-section-body h3 {
  margin: 22px 0 8px;
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #5f7385);
}
.bok-section-body ul,
.bok-section-body ol { margin: 0 0 14px 22px; padding: 0; }
.bok-section-body li { margin: 4px 0; }
.bok-section-body code {
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace;
  font-size: 13px;
  background: rgba(40, 69, 88, 0.06);
  padding: 1px 6px;
  border-radius: 5px;
}
.bok-section-body a { color: var(--accent, #d63438); text-decoration: underline; }
.bok-contact-list { list-style: none; margin: 0 0 14px; padding: 0; }
.bok-contact-list li { padding: 3px 0; font-size: 14px; }

.bok-table {
  width: 100%;
  border-collapse: collapse;
  margin: 10px 0 20px;
  font-size: 13.5px;
}
.bok-table th,
.bok-table td {
  border: 0;
  border-bottom: 1px solid var(--line, #eef0f3);
  padding: 9px 12px;
  text-align: left;
  vertical-align: top;
}
.bok-table thead th {
  background: transparent;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted, #5f7385);
  border-bottom: 1.5px solid var(--line, #d8e0e6);
}
.bok-table tbody tr:last-child td { border-bottom: 0; }
.bok-table tbody tr:hover td { background: rgba(40, 69, 88, 0.025); }

/* Interactive checklist (build-date milestones etc.) */
.bok-checklist .bok-check-cell { text-align: center; vertical-align: middle; }
.bok-check {
  -webkit-appearance: none;
  appearance: none;
  width: 19px;
  height: 19px;
  margin: 0;
  border: 1.5px solid var(--line, #c2ccd4);
  border-radius: 5px;
  background: #fff;
  cursor: pointer;
  vertical-align: middle;
  position: relative;
  transition: background 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}
.bok-check:hover { border-color: var(--accent, #d63438); }
.bok-check:checked {
  background: var(--ink, #284558);
  border-color: var(--ink, #284558);
}
.bok-check:checked::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.bok-check:disabled { opacity: 0.5; cursor: progress; }
.bok-check:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.30);
}
/* Completed rows read slightly calmer */
.bok-checklist tbody tr:has(.bok-check:checked) td { color: var(--ink-muted, #5f7385); }

.bok-callout {
  border-left: 4px solid var(--accent, #d63438);
  background: rgba(214, 52, 56, 0.07);
  padding: 10px 14px;
  border-radius: 6px;
  margin: 10px 0 14px;
  font-size: 14px;
}

/* Cover image at the top of the first section */
.bok-cover {
  margin: 4px 0 18px;
  padding: 0;
}
.bok-cover img {
  display: block;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(40, 69, 88, 0.10);
}

/* Thumbnail grid for inline photos */
.bok-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  margin: 10px 0 18px;
}
.bok-photo {
  display: block;
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--line, #e2e8ec);
  background: rgba(40, 69, 88, 0.04);
  aspect-ratio: 4 / 3;
  cursor: zoom-in;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.bok-photo:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(40, 69, 88, 0.14);
  border-color: var(--accent, #d63438);
}
.bok-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.bok-callout.warn  { border-left-color: #d6a000; background: rgba(214, 160, 0, 0.10); }
.bok-callout.danger { border-left-color: #b03030; background: rgba(176, 48, 48, 0.10); }
.bok-note { font-size: 13px; color: var(--ink-muted, #5f7385); }

.bok-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 8px 18px;
  padding: 14px;
  margin: 10px 0 18px;
  background: rgba(40, 69, 88, 0.03);
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 10px;
}
.bok-fact {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 0;
}
.bok-fact-k {
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted, #5f7385);
}
.bok-fact-v { font-size: 14px; color: var(--ink, #284558); font-weight: 500; }
.bok-fact-empty { color: #b8c2cc; font-weight: 400; }

/* Sensitive value pill */
.bok-secret {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace;
  font-size: 13px;
  background: rgba(40, 69, 88, 0.08);
  border: 1px dashed rgba(40, 69, 88, 0.3);
  border-radius: 6px;
  cursor: pointer;
  user-select: none;
  transition: background 120ms ease, border-color 120ms ease;
}
/* Lock / eye glyphs are CSS pseudo-elements, so they can't hold an
   inline <svg>. We use mask-image with an inline SVG data-URI so the
   icon picks up `currentColor` and re-tints when .revealed flips. */
.bok-secret::before {
  content: '';
  display: inline-block;
  width: 11px;
  height: 11px;
  background-color: currentColor;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M7.5 11V7.5a4.5 4.5 0 0 1 9 0V11'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M7.5 11V7.5a4.5 4.5 0 0 1 9 0V11'/></svg>");
  -webkit-mask-size: contain;          mask-size: contain;
  -webkit-mask-repeat: no-repeat;      mask-repeat: no-repeat;
  -webkit-mask-position: center;       mask-position: center;
  opacity: 0.7;
}
.bok-secret.revealed {
  background: rgba(214, 52, 56, 0.10);
  border-style: solid;
  border-color: rgba(214, 52, 56, 0.45);
  user-select: text;
}
.bok-secret.revealed::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z'/><circle cx='12' cy='12' r='3'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z'/><circle cx='12' cy='12' r='3'/></svg>");
  width: 13px;
  height: 13px;
  opacity: 0.85;
}
.bok-secret:hover { background: rgba(40, 69, 88, 0.14); }
.bok-secret.revealed:hover { background: rgba(214, 52, 56, 0.18); }

/* Editor flip */
.bok-editor {
  margin: 14px 0 10px;
  padding: 14px;
  background: rgba(255, 251, 230, 0.55);
  border: 1px solid #e6d18a;
  border-radius: 10px;
}
.bok-editor-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid rgba(40, 69, 88, 0.12);
}
.bok-editor-toolbar button {
  background: var(--surface, #fff);
  border: 1px solid var(--line, #d8e0e6);
  padding: 5px 10px;
  border-radius: 6px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  min-width: 32px;
}
.bok-editor-toolbar button:hover { background: rgba(40, 69, 88, 0.06); }
.bok-editor-body {
  background: var(--surface, #fff);
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 8px;
  padding: 14px 16px;
  min-height: 220px;
  max-height: 60vh;
  overflow-y: auto;
  font-size: 14.5px;
  line-height: 1.6;
}
.bok-editor-body:focus { outline: none; border-color: var(--accent, #d63438); box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.15); }
.bok-edit-facts { margin-top: 14px; }
.bok-edit-facts h4 { margin: 0 0 8px; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-muted, #5f7385); }
.bok-edit-fact-row {
  display: grid;
  grid-template-columns: 1fr 1.6fr 32px;
  gap: 8px;
  margin-bottom: 6px;
}
.bok-edit-fact-row input {
  padding: 7px 10px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 6px;
  font: inherit;
  font-size: 13.5px;
}
.bok-fact-del {
  background: transparent;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 6px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-muted, #5f7385);
}
.bok-fact-del:hover { color: #b03030; border-color: #b03030; }
.bok-editor-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}

/* Hide rendered body/facts while editing */
.bok-editing > .bok-section-body.hidden,
.bok-editing > .bok-facts.hidden { display: none; }

/* ============================================================
   R57 — Categories, breadcrumb, import, settings strip
   ============================================================ */
.bok-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }

/* Loading + empty states */
.bok-loading, .bok-empty {
  padding: 40px 24px;
  color: var(--muted, #5e6b7a);
  font-size: 14px;
  text-align: center;
}
.bok-empty { font-style: italic; }

/* Category groups in the TOC use <details>/<summary> for native
   keyboard a11y. The chevron rotates on open via :first-child. */
.bok-toc-cat {
  margin: 2px 0 10px;
  border-radius: 8px;
  background: transparent;
  border: 0;
}
.bok-toc-cat[open] {
  background: transparent;
  border-color: transparent;
}
.bok-toc-cat > summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 8px 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted, #5f7385);
  border-radius: 6px;
  transition: color 120ms ease;
}
.bok-toc-cat > summary::-webkit-details-marker { display: none; }
.bok-toc-cat > summary::before {
  content: '';
  display: inline-block;
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  margin-right: 6px;
  background: currentColor;
  -webkit-mask: no-repeat center / 9px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6 4l4 4-4 4' stroke='black' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask: no-repeat center / 9px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6 4l4 4-4 4' stroke='black' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  opacity: 0.55;
  transition: transform 140ms ease;
}
.bok-toc-cat[open] > summary::before { transform: rotate(90deg); }
.bok-toc-cat > summary:hover { color: var(--accent, #d63438); }
.bok-toc-cat-count {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-muted, #5f7385);
  background: rgba(40, 69, 88, 0.07);
  border-radius: 999px;
  padding: 1px 7px;
  min-width: 18px;
  text-align: center;
}
.bok-toc-cat > .bok-toc-children {
  margin: 2px 4px 6px 13px;
  padding-left: 8px;
  border-left: 1px solid var(--line, #e2e8ec);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.bok-toc-empty {
  padding: 6px 10px;
  font-size: 12px;
  font-style: italic;
  color: var(--muted, #8a96a3);
}
.bok-toc-section { list-style: none; margin: 0; padding: 0; }
.bok-toc-section[data-depth="1"] > a { font-size: 13px; }
.bok-toc-subsections {
  list-style: none;
  margin: 1px 0 2px 10px;
  padding-left: 8px;
  border-left: 2px solid var(--line, #eef0f3);
}
.bok-toc-orphans { list-style: none; margin: 0 0 8px 0; padding: 0; }

/* Breadcrumb */
.bok-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 12px;
  color: var(--muted, #5e6b7a);
  margin-bottom: 6px;
}
.bok-crumb {
  text-decoration: none;
  color: var(--muted, #5e6b7a);
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(40, 69, 88, 0.04);
}
.bok-crumb:hover { background: rgba(40, 69, 88, 0.08); color: var(--ink, #284558); }
.bok-crumb.is-cat { font-weight: 600; color: var(--ink, #284558); background: rgba(214, 52, 56, 0.06); }
.bok-crumb-sep { color: var(--muted, #b3bcc6); }

/* Editor settings strip */
.bok-edit-settings {
  background: rgba(40, 69, 88, 0.03);
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.bok-edit-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.bok-edit-field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 200px; min-width: 0; }
.bok-edit-field > span { font-size: 11px; font-weight: 600; color: var(--muted, #5e6b7a); letter-spacing: 0.04em; text-transform: uppercase; }
.bok-edit-field input[type="text"], .bok-edit-field input[type="number"], .bok-edit-field select {
  padding: 7px 9px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 6px;
  font-size: 14px;
  background: #fff;
  width: 100%;
}
.bok-edit-field-narrow { flex: 0 0 110px; }
.bok-edit-field-check { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 8px; }
.bok-edit-field-check > span { text-transform: none; letter-spacing: 0; font-size: 13px; font-weight: 500; }
.bok-editor-spacer { flex: 1; }
.bok-delete-btn { margin-right: auto; }

/* ============================================================
   R57 — Import modal
   ============================================================ */
.bok-import-modal {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(40, 69, 88, 0.42);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
}
.bok-import-card {
  background: #fff;
  border: 1px solid rgba(40, 69, 88, 0.08);
  border-radius: 14px;
  box-shadow: 0 22px 54px rgba(40, 69, 88, 0.22), 0 2px 6px rgba(40, 69, 88, 0.08);
  width: 100%;
  max-width: 560px;
  padding: 20px 22px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
}
.bok-import-card.is-wide { max-width: 880px; }
.bok-import-card h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.bok-import-card .bok-import-sub {
  color: var(--muted, #5e6b7a);
  font-size: 13px;
  line-height: 1.45;
  margin: 4px 0 0;
}
.bok-import-step { margin: 0; min-width: 0; }
.bok-import-drop {
  display: block;
  border: 1.5px dashed var(--line, #c8d3dc);
  border-radius: 10px;
  padding: 22px 16px;
  text-align: center;
  background: rgba(40, 69, 88, 0.02);
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.bok-import-drop:hover { border-color: rgba(40, 69, 88, 0.32); background: rgba(40, 69, 88, 0.04); }
.bok-import-drop.dragover { border-color: var(--accent, #d63438); background: rgba(214, 52, 56, 0.05); }
.bok-import-drop input[type="file"] { display: none; }
.bok-import-drop-title { font-size: 14px; font-weight: 500; color: var(--ink, #284558); }
.bok-import-drop-hint  { font-size: 12px; color: var(--muted, #5e6b7a); margin-top: 4px; }
.bok-import-status {
  margin: 8px 2px 0;
  font-size: 12.5px;
  color: var(--muted, #5e6b7a);
  display: flex; gap: 8px; align-items: center;
  min-height: 18px;
}
.bok-import-status .spinner {
  width: 12px; height: 12px;
  border: 2px solid var(--line, #d8e0e6);
  border-top-color: var(--accent, #d63438);
  border-radius: 50%;
  animation: bok-spin 0.7s linear infinite;
}
@keyframes bok-spin { to { transform: rotate(360deg); } }

.bok-import-preview {
  margin: 0;
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 8px;
  flex: 1 1 auto;
  min-height: 120px;
  max-height: 50vh;
  overflow-y: auto;
}
.bok-import-row {
  display: grid;
  grid-template-columns: 1fr 220px 90px 36px;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line, #eef0f3);
}
.bok-import-row:last-child { border-bottom: 0; }
.bok-import-row.is-sensitive { background: rgba(214, 52, 56, 0.03); }
.bok-import-row input[type="text"],
.bok-import-row select {
  padding: 6px 8px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 6px;
  font-size: 13px;
  background: #fff;
  width: 100%;
}
.bok-import-row .bok-import-flags { display: flex; gap: 8px; font-size: 12px; color: var(--muted, #5e6b7a); }
.bok-import-row .bok-import-flags label { display: inline-flex; gap: 4px; align-items: center; }
.bok-import-row .bok-import-del {
  background: transparent;
  border: 1px solid var(--line, #d8e0e6);
  color: var(--muted, #5e6b7a);
  border-radius: 6px;
  cursor: pointer;
  height: 28px;
  width: 28px;
  font-size: 14px;
}
.bok-import-row .bok-import-del:hover { color: var(--accent, #d63438); border-color: var(--accent, #d63438); }
.bok-import-row .bok-import-body-preview {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--muted, #5e6b7a);
  margin-top: 4px;
  padding: 6px 10px;
  background: rgba(40, 69, 88, 0.03);
  border-radius: 6px;
  max-height: 110px;
  overflow-y: auto;
}
.bok-import-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  padding-top: 10px;
  margin: 4px -22px -16px; /* extend to card edges */
  padding: 12px 22px 14px;
  border-top: 1px solid var(--line, #eef0f3);
  background: rgba(40, 69, 88, 0.015);
  border-radius: 0 0 14px 14px;
}
.bok-import-summary {
  margin-right: auto;
  font-size: 12.5px;
  color: var(--muted, #5e6b7a);
  align-self: center;
}

@media (max-width: 720px) {
  .bok-import-row { grid-template-columns: 1fr 1fr; }
  .bok-import-row .bok-import-del { grid-column: 2; justify-self: end; }
}

/* ============================================================
   R59 — Payroll module (full redesign on top of R58)
   ============================================================ */
.payroll-content { padding: 0; }

.payroll-loading { padding: 64px; text-align: center; color: var(--muted, #5e6b7a); font-size: 14px; }
.payroll-empty {
  padding: 64px 32px;
  text-align: center;
  background: #fff;
  border: 1px dashed var(--line, #d8e0e6);
  border-radius: 14px;
}
.payroll-empty-icon { font-size: 36px; margin-bottom: 10px; }
.payroll-empty h3 { margin: 0 0 6px; font-size: 17px; color: var(--ink, #284558); }
.payroll-empty p  { margin: 0; color: var(--muted, #5e6b7a); font-size: 13.5px; }

/* ---------- Toolbar (period list) ---------- */
.payroll-toolbar {
  display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap;
  margin-bottom: 22px;
}
.payroll-toolbar-text h2 { margin: 0 0 4px; font-size: 22px; letter-spacing: -0.01em; }
.payroll-toolbar-text p  { margin: 0; color: var(--muted, #5e6b7a); font-size: 13.5px; }
.payroll-toolbar-actions { margin-left: auto; display: inline-flex; gap: 8px; flex-wrap: wrap; }

/* ---------- Year sections (<details>) ---------- */
.payroll-year {
  margin-bottom: 18px;
  border-radius: 12px;
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  overflow: hidden;
}
.payroll-year-summary {
  list-style: none;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  cursor: pointer;
  background: linear-gradient(180deg, #fbfcfd, #f6f8fa);
  border-bottom: 1px solid transparent;
  transition: background 120ms ease, border-color 120ms ease;
}
.payroll-year-summary::-webkit-details-marker { display: none; }
.payroll-year[open] .payroll-year-summary { border-bottom-color: var(--line, #e7ecf0); }
.payroll-year-summary:hover { background: linear-gradient(180deg, #f6f8fa, #f0f3f6); }
.pys-chev { color: var(--muted, #5e6b7a); transition: transform 150ms ease; font-size: 14px; }
.payroll-year[open] .pys-chev { transform: rotate(90deg); }
.payroll-year-summary h3 { margin: 0; font-size: 18px; font-weight: 700; color: var(--ink, #284558); letter-spacing: -0.005em; }
.pys-meta { margin-left: auto; font-size: 12.5px; color: var(--muted, #5e6b7a); font-variant-numeric: tabular-nums; }
.payroll-period-grid {
  display: grid;
  gap: 12px;
  padding: 16px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.payroll-period-card {
  position: relative;
  background: #fff;
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 12px;
  padding: 16px 16px 14px;
  text-align: left;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 12px;
  transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}
.payroll-period-card:hover {
  border-color: rgba(40, 69, 88, 0.25);
  box-shadow: 0 8px 24px rgba(40, 69, 88, 0.08);
  transform: translateY(-2px);
}
.payroll-period-card.is-paid       { background: linear-gradient(180deg, #ffffff, #f4faf7); }
.payroll-period-card.is-reconciled { background: linear-gradient(180deg, #ffffff, #f6f3fb); }
.ppc-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.ppc-month-block { line-height: 1.1; }
.ppc-month-name { font-size: 16px; font-weight: 700; color: var(--ink, #284558); letter-spacing: -0.005em; }
.ppc-year { font-size: 12px; color: var(--muted, #5e6b7a); font-weight: 500; margin-top: 2px; }
.ppc-gross-block label { display: block; font-size: 10.5px; color: var(--muted, #5e6b7a); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; margin-bottom: 4px; }
.ppc-gross-block strong { font-size: 20px; color: var(--ink, #284558); font-variant-numeric: tabular-nums; letter-spacing: -0.005em; }
.ppc-footer { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted, #5e6b7a); padding-top: 8px; border-top: 1px solid var(--line, #eef2f5); }
.ppc-paid-badge {
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #047857;
  background: rgba(16, 185, 129, 0.10);
  padding: 2px 8px;
  border-radius: 999px;
}
.ppc-arrow { margin-left: auto; opacity: 0; transition: opacity 140ms ease, transform 140ms ease; }
.payroll-period-card:hover .ppc-arrow { opacity: 1; transform: translateX(2px); }

/* ---------- Status pills (used across module) ---------- */
.payroll-status-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 999px;
  background: rgba(40, 69, 88, 0.08);
  color: var(--ink, #284558);
}
.payroll-status-pill::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.payroll-status-pill.is-draft      { background: rgba(40, 69, 88, 0.10); color: #475569; }
.payroll-status-pill.is-approved   { background: rgba(37, 99, 235, 0.12); color: #1d4ed8; }
.payroll-status-pill.is-paid       { background: rgba(16, 185, 129, 0.14); color: #047857; }
.payroll-status-pill.is-reconciled { background: rgba(124, 58, 237, 0.12); color: #6d28d9; }

/* ---------- Period detail page ---------- */
.payroll-period-page { padding: 0; display: flex; flex-direction: column; gap: 18px; }

/* Hero header — gradient + big title + status + actions. */
.payroll-hero {
  display: flex; align-items: center; gap: 18px;
  padding: 22px 24px;
  border-radius: 16px;
  background: linear-gradient(135deg, #284558 0%, #1a3760 60%, #284a7a 100%);
  color: #fff;
  position: relative;
  overflow: hidden;
}
.payroll-hero::after {
  content: ''; position: absolute; right: -80px; top: -80px;
  width: 280px; height: 280px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.10), transparent 70%);
  pointer-events: none;
}
.payroll-hero.is-paid       { background: linear-gradient(135deg, #064e3b 0%, #047857 100%); }
.payroll-hero.is-approved   { background: linear-gradient(135deg, #1e3a8a 0%, #1d4ed8 100%); }
.payroll-hero.is-reconciled { background: linear-gradient(135deg, #4c1d95 0%, #6d28d9 100%); }

.payroll-back {
  width: 38px; height: 38px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: background 120ms ease, transform 120ms ease;
  flex-shrink: 0;
}
.payroll-back:hover { background: rgba(255, 255, 255, 0.18); transform: translateX(-2px); }
.payroll-hero-main { flex: 1; min-width: 0; position: relative; z-index: 1; }
.payroll-hero-eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 600; color: rgba(255, 255, 255, 0.7); }
.payroll-hero-title  { margin: 4px 0 8px; font-size: 28px; font-weight: 700; letter-spacing: -0.02em; }
.payroll-hero-meta   { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; font-size: 13px; color: rgba(255, 255, 255, 0.85); }
.payroll-hero-meta .payroll-status-pill {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}
.payroll-hero-sep { opacity: 0.4; }
.payroll-hero-actions { position: relative; z-index: 1; display: inline-flex; gap: 8px; }
.payroll-hero-actions .btn-secondary {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}
.payroll-hero-actions .btn-secondary:hover { background: rgba(255, 255, 255, 0.22); }
.payroll-hero-actions .btn-primary {
  background: #fff;
  color: var(--ink, #284558);
  border-color: #fff;
}
.payroll-hero-actions .btn-primary:hover { background: rgba(255, 255, 255, 0.92); }

/* Stats strip — 5 cards, big numbers, small descriptions. */
.payroll-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
}
.pst-card {
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 4px;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.pst-card:hover { border-color: rgba(40, 69, 88, 0.18); box-shadow: 0 4px 12px rgba(40, 69, 88, 0.05); }
.pst-card label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted, #5e6b7a); font-weight: 600; }
.pst-card strong {
  font-size: 26px;
  font-weight: 700;
  color: var(--ink, #284558);
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.pst-card.pst-money strong { font-size: 20px; }
.pst-card small { font-size: 11.5px; color: var(--muted, #5e6b7a); }
.pst-card.is-grand { background: linear-gradient(135deg, #284558, #1a3760); color: #fff; border-color: transparent; }
.pst-card.is-grand label, .pst-card.is-grand small { color: rgba(255, 255, 255, 0.72); }
.pst-card.is-grand strong { color: #fff; }

/* Anomaly chips — clickable summaries that flash matching rows. */
.payroll-anomalies { display: flex; gap: 8px; flex-wrap: wrap; }
.payroll-anomaly {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 100ms ease, box-shadow 120ms ease;
}
.payroll-anomaly:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(40, 69, 88, 0.08); }
.payroll-anomaly.is-warn   { background: rgba(245, 158, 11, 0.12); border-color: rgba(245, 158, 11, 0.30); color: #92400e; }
.payroll-anomaly.is-info   { background: rgba(40, 69, 88, 0.06);   border-color: rgba(40, 69, 88, 0.15);   color: #1e293b; }
.payroll-anomaly.is-danger { background: rgba(239, 68, 68, 0.10);  border-color: rgba(239, 68, 68, 0.30);  color: #991b1b; }
.payroll-anomaly.is-good   { background: rgba(16, 185, 129, 0.12); border-color: rgba(16, 185, 129, 0.30); color: #065f46; }
.pa-icon { font-size: 14px; line-height: 1; }
.pa-count {
  font-weight: 700;
  background: rgba(40, 69, 88, 0.08);
  border-radius: 999px;
  padding: 1px 8px;
  min-width: 18px;
  text-align: center;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.payroll-anomaly.is-warn   .pa-count { background: rgba(245, 158, 11, 0.25); }
.payroll-anomaly.is-info   .pa-count { background: rgba(40, 69, 88, 0.15); color: #fff; }
.payroll-anomaly.is-danger .pa-count { background: rgba(239, 68, 68, 0.25); }
.payroll-anomaly.is-good   .pa-count { background: rgba(16, 185, 129, 0.25); }

/* R62 — Prefill summary banner. Shows on every draft period if the
   system has populated cells the captain hasn't touched yet. */
.payroll-prefill-banner {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.08), rgba(37, 99, 235, 0.06));
  border: 1px solid rgba(16, 185, 129, 0.22);
  border-radius: 12px;
  padding: 12px 16px;
  font-size: 13px;
}
.ppb-icon { font-size: 18px; line-height: 1; }
.ppb-text { display: flex; flex-direction: column; gap: 2px; }
.ppb-text strong { color: #065f46; font-weight: 700; }
.ppb-text small  { color: var(--muted, #5e6b7a); font-size: 12px; }
.ppb-hint { margin-left: auto; color: var(--muted, #5e6b7a); font-size: 12px; max-width: 360px; }

/* R62 — Auto-prefilled cell visual hint. Subtle dotted-bottom marker
   so the captain can tell system-set from manually-set without it
   being noisy. Manual edits remove the marker (auto_prefilled=false
   in DB, so the .is-auto class is absent on next render). */
.pdg-cell.is-auto::after {
  content: '';
  position: absolute;
  left: 4px; right: 4px; bottom: 1px;
  height: 1px;
  background: currentColor;
  opacity: 0.32;
  border-radius: 1px;
}

/* "Non-crew rows detected" banner — kept from R58.1 */
.payroll-junk-banner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: rgba(245, 158, 11, 0.10);
  border: 1px solid rgba(245, 158, 11, 0.30);
  color: #92400e;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 13px;
}
.payroll-junk-banner button { margin-left: auto; }

.payroll-legend {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12px; color: var(--muted, #5e6b7a);
  margin: 6px 0 12px;
}
.pl-pill {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 5px;
  font-weight: 600;
  font-size: 12px;
}
.pl-pill.is-D { background: rgba(16, 185, 129, 0.18); color: #047857; }
.pl-pill.is-H { background: rgba(37, 99, 235, 0.18); color: #1d4ed8; }
.pl-pill.is-S { background: rgba(245, 158, 11, 0.18); color: #b45309; }
.pl-pill.is-T { background: rgba(124, 58, 237, 0.18); color: #6d28d9; }
.pl-pill.is-O { background: rgba(40, 69, 88, 0.10);  color: #475569; }
.pl-spacer { flex: 1; }
.pl-meta { font-size: 12px; color: var(--muted, #5e6b7a); }

.payroll-grid-scroll {
  overflow-x: auto;
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.03);
}
table.payroll-duty-grid {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: 12px;
}
.payroll-duty-grid th, .payroll-duty-grid td {
  padding: 6px 6px;
  border-bottom: 1px solid var(--line, #eef0f3);
  border-right: 1px solid var(--line, #f6f8fa);
  text-align: center;
  white-space: nowrap;
  background: #fff;
}
.payroll-duty-grid thead th {
  position: sticky; top: 0; z-index: 2;
  background: linear-gradient(180deg, #f9fafb, #f3f5f8);
  font-weight: 600;
  font-size: 11px;
  color: var(--muted, #5e6b7a);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 10px 6px;
  border-bottom: 1px solid var(--line, #dee2e6);
}
.payroll-duty-grid .pdg-stick {
  position: sticky; left: 0;
  z-index: 4;
  text-align: left;
  background: #fff;
  border-right: 2px solid var(--line, #e2e8ec);
  min-width: 260px;
  width: 260px;
  max-width: 260px;
  padding: 8px 12px;
  box-sizing: border-box;
  overflow: hidden;
}
.payroll-duty-grid thead .pdg-stick { z-index: 6; background: linear-gradient(180deg, #f9fafb, #f3f5f8); }
/* Zebra-stripe non-divider rows so the eye can follow across 30 days.
   Sticky cells MUST use opaque colours — rgba with alpha < 1 would let
   day cells that have scrolled past the sticky column bleed through. */
.payroll-duty-grid tbody tr.pdg-row:nth-of-type(odd) td { background: #fcfdfe; }
.payroll-duty-grid tbody tr.pdg-row:nth-of-type(odd) .pdg-stick { background: #fcfdfe; }
.payroll-duty-grid tbody tr.pdg-row:hover td { background: rgba(40, 69, 88, 0.025); }
.payroll-duty-grid tbody tr.pdg-row:hover .pdg-stick { background: #f1f3f6; }

/* Crew name + avatar + position row layout. */
.pdg-name-flex { display: flex; align-items: center; gap: 10px; }
.pdg-avatar {
  flex: 0 0 30px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(40, 69, 88, 0.10), rgba(40, 69, 88, 0.18));
  color: var(--ink, #284558);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.pdg-row.is-new-hire .pdg-avatar {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.16), rgba(16, 185, 129, 0.32));
  color: #047857;
}
.pdg-name-text { min-width: 0; flex: 1 1 auto; overflow: hidden; }
.pdg-name-line {
  font-weight: 600; font-size: 13px; color: var(--ink, #284558);
  display: flex; align-items: center; gap: 6px;
  line-height: 1.2;
  min-width: 0;
}
/* Long names (Fraser William Nicholas Gow) ellipsis-clip on the
   name-name span so the new-hire + anomaly badges stay visible. */
.pdg-name-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 0 1 auto;
}
.pdg-name-sub  { font-size: 11px; color: var(--muted, #5e6b7a); display: flex; align-items: center; gap: 8px; margin-top: 3px; flex-wrap: nowrap; min-width: 0; overflow: hidden; }
.pdg-pos { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.pdg-new-hire {
  background: rgba(16, 185, 129, 0.16);
  color: #047857;
  font-size: 9.5px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.pdg-day { width: 28px; min-width: 28px; padding: 6px 0; }
.pdg-cell {
  width: 28px; min-width: 28px; height: 30px;
  font-weight: 600; font-size: 12px;
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background 100ms ease, transform 80ms ease, box-shadow 100ms ease;
}
.pdg-cell:hover {
  transform: scale(1.10);
  box-shadow: inset 0 0 0 2px rgba(40, 69, 88, 0.12);
  z-index: 1;
}
.pdg-cell.is-empty { background: #fff; color: transparent; }
.pdg-cell.is-empty:hover { background: rgba(40, 69, 88, 0.04); }
.pdg-cell.is-D { background: rgba(16, 185, 129, 0.22); color: #047857; }
.pdg-cell.is-H { background: rgba(37, 99, 235, 0.22);  color: #1d4ed8; }
.pdg-cell.is-S { background: rgba(245, 158, 11, 0.26); color: #92400e; }
.pdg-cell.is-T { background: rgba(124, 58, 237, 0.22); color: #6d28d9; }
.pdg-cell.is-O { background: rgba(40, 69, 88, 0.16);   color: #1f2937; }
.pdg-total { font-weight: 600; color: var(--ink, #284558); min-width: 30px; font-variant-numeric: tabular-nums; }
.pdg-gross {
  text-align: right;
  min-width: 110px;
  font-variant-numeric: tabular-nums;
  padding-right: 12px !important;
}
.pdg-gross strong { font-size: 13px; }
.pdg-row.is-new-hire .pdg-stick { box-shadow: inset 4px 0 0 0 #10b981; }

/* Department divider — split into sticky-label + gradient-fill cells
   so the label stays visible when the grid is scrolled horizontally
   (R59.2). Gradient background extends across both cells. */
.pdg-dept-row td {
  border-top: 1px solid var(--line, #dee2e6);
  border-bottom: 1px solid var(--line, #dee2e6);
  padding: 0;
}
.pdg-dept-row .pdg-dept-stick {
  /* Gradient layered over solid white so the sticky cell stays
     opaque while keeping the visual tint. Plain rgba would let
     scrolled-past day cells bleed through. */
  background: linear-gradient(90deg, rgba(40, 69, 88, 0.10), rgba(40, 69, 88, 0.06)), #fff;
  padding: 9px 14px !important;
  text-align: left;
  border-right: 2px solid var(--line, #e2e8ec);
  z-index: 2;
}
.pdg-dept-row .pdg-dept-fill {
  background: linear-gradient(90deg, rgba(40, 69, 88, 0.04), rgba(40, 69, 88, 0.01));
}
.pdg-dept-label {
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink, #284558);
}
.pdg-dept-count {
  margin-left: 10px;
  font-size: 11px;
  color: var(--muted, #5e6b7a);
  font-weight: 600;
  background: rgba(40, 69, 88, 0.10);
  padding: 1px 8px;
  border-radius: 999px;
}

/* Leave-remaining chip — tone shifts with how much is left. */
.payroll-leave-pill {
  display: inline-flex; align-items: center;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 2px 7px;
  border-radius: 999px;
  cursor: help;
}
.payroll-leave-pill.is-ok  { color: #047857; background: rgba(16, 185, 129, 0.14); }
.payroll-leave-pill.is-mid { color: #b45309; background: rgba(245, 158, 11, 0.16); }
.payroll-leave-pill.is-low { color: var(--danger); background: rgba(239, 68, 68, 0.16); }

/* Per-row delete button. */
.pdg-actions {
  width: 34px; min-width: 34px;
  padding: 0 !important;
  background: #fff;
}
.payroll-duty-grid tbody tr.pdg-row:nth-of-type(odd) .pdg-actions { background: #fcfdfe; }
.pdg-row-del {
  width: 22px; height: 22px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted, #5e6b7a);
  border-radius: 6px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms ease, color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.pdg-row:hover .pdg-row-del { opacity: 1; }
.pdg-row-del:hover { color: var(--danger); border-color: rgba(239, 68, 68, 0.4); background: rgba(239, 68, 68, 0.06); }

.payroll-footer {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 16px;
  margin-top: 14px;
  align-items: flex-start;
}
.payroll-fee-block, .payroll-totals-block {
  background: #fff;
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 10px;
  padding: 12px 14px;
}
.payroll-fee-block h4 { margin: 0 0 8px; font-size: 13px; font-weight: 600; }
.payroll-fees-table { width: 100%; font-size: 12.5px; }
.payroll-fees-table th, .payroll-fees-table td { padding: 6px 6px; }
.payroll-fees-table th { font-weight: 600; color: var(--muted, #5e6b7a); text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.payroll-fees-table td.num { text-align: right; }
.payroll-fees-table input[type="number"] {
  width: 96px; text-align: right;
  padding: 4px 6px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 6px;
  font-size: 12.5px;
}
.ptb-row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 13px; }
.ptb-row label { color: var(--muted, #5e6b7a); }
.ptb-row strong { font-variant-numeric: tabular-nums; }
.ptb-row.is-grand { padding-top: 8px; margin-top: 4px; border-top: 1px solid var(--line, #eef0f3); font-weight: 700; }
.ptb-row.is-grand strong { font-size: 15px; color: var(--ink, #284558); }

.payroll-import-sheet { margin: 8px 0 16px; }
.payroll-import-sheet h4 { margin: 0 0 4px; font-size: 13px; }
.payroll-import-sheet ul { margin: 0; padding-left: 20px; font-size: 12px; color: #334155; }

/* ============================================================
   R61 — Top tabs, auto-generate banner, YTD, Compensation,
   Audit, search, print stylesheet
   ============================================================ */
.payroll-top-tabs {
  display: flex;
  gap: 4px;
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 12px;
  padding: 5px;
  margin-bottom: 20px;
  width: fit-content;
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.03);
}
.ptt-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent;
  border: 0;
  padding: 9px 16px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted, #5e6b7a);
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.ptt-btn:hover { background: rgba(40, 69, 88, 0.04); color: var(--ink, #284558); }
.ptt-btn.is-on {
  background: var(--ink, #284558);
  color: #fff;
  box-shadow: 0 2px 6px rgba(40, 69, 88, 0.16);
}
.ptt-icon { font-size: 14px; }

/* Auto-generate banner — bold prompt for current month. */
.payroll-auto-banner {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 22px;
  margin-bottom: 18px;
  border-radius: 14px;
  background: linear-gradient(135deg, #fef9c3, #fef08a);
  border: 1px solid rgba(202, 138, 4, 0.25);
  box-shadow: 0 4px 14px rgba(202, 138, 4, 0.10);
}
.pab-icon { font-size: 28px; line-height: 1; }
.pab-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pab-text strong { font-size: 15px; color: #713f12; }
.pab-text span { font-size: 13px; color: #854d0e; }
.payroll-auto-banner .btn { flex-shrink: 0; }

/* YTD dashboard cards. */
.payroll-ytd {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 22px;
}
.pyd-card {
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 4px;
  min-height: 100px;
}
.pyd-card label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted, #5e6b7a); font-weight: 700; }
.pyd-card strong {
  font-size: 20px;
  font-weight: 700;
  color: var(--ink, #284558);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.pyd-card small { font-size: 11.5px; color: var(--muted, #5e6b7a); line-height: 1.35; }
.pyd-delta { font-weight: 700; padding: 1px 6px; border-radius: 999px; font-size: 10.5px; }
.pyd-delta.is-up   { background: rgba(239, 68, 68, 0.12); color: var(--danger); }
.pyd-delta.is-down { background: rgba(16, 185, 129, 0.14); color: #047857; }
.pyd-card.pyd-action strong { font-size: 13px; color: var(--muted, #5e6b7a); font-weight: 500; }
.pyd-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
@media (max-width: 1100px) { .payroll-ytd { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .payroll-ytd { grid-template-columns: 1fr; } }

/* Compensation table. */
.payroll-compensation-table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  min-width: 100%;
  font-size: 13px;
}
.payroll-compensation-table th, .payroll-compensation-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line, #eef0f3);
  text-align: center;
  background: #fff;
  vertical-align: middle;
}
.payroll-compensation-table th {
  font-size: 10.5px;
  color: var(--muted, #5e6b7a);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  background: linear-gradient(180deg, #f9fafb, #f3f5f8);
  padding: 12px 12px;
  line-height: 1.2;
}
.payroll-compensation-table th.pcomp-name-th { text-align: left; padding-left: 16px; }
.payroll-compensation-table tbody tr.pcomp-row:nth-of-type(even) td { background: #fcfdfe; }
.payroll-compensation-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.pcomp-name { text-align: left !important; padding-left: 16px !important; min-width: 220px; }
.pcomp-input {
  width: 100%;
  max-width: 130px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  font-size: 13px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  transition: border-color 120ms ease, background 120ms ease;
}
select.pcomp-input { text-align: left; max-width: 90px; }
input[type="date"].pcomp-input { text-align: left; max-width: 150px; }
.pcomp-input:hover { border-color: var(--line, #d8e0e6); background: #fff; }
.pcomp-input:focus {
  outline: none;
  border-color: var(--accent, #d63438);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.08);
}
.pcomp-check { display: inline-flex; align-items: center; justify-content: center; }
.pcomp-check input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; }
.pcomp-dept-row td {
  background: linear-gradient(90deg, rgba(40, 69, 88, 0.10), rgba(40, 69, 88, 0.04)), #fff !important;
  text-align: left;
  padding: 9px 16px !important;
  border-top: 1px solid var(--line, #dee2e6);
  border-bottom: 1px solid var(--line, #dee2e6);
}

/* Audit log table. */
.payroll-audit-table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  font-size: 12.5px;
}
.payroll-audit-table th, .payroll-audit-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line, #eef0f3);
  background: #fff;
  vertical-align: middle;
  text-align: left;
}
.payroll-audit-table th {
  font-size: 10.5px;
  color: var(--muted, #5e6b7a);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  background: linear-gradient(180deg, #f9fafb, #f3f5f8);
}
.payroll-audit-table tbody tr.paud-row:nth-of-type(even) td { background: #fcfdfe; }
.paud-when  { white-space: nowrap; color: var(--muted, #5e6b7a); font-variant-numeric: tabular-nums; }
.paud-kind  { white-space: nowrap; font-weight: 600; }
.paud-kind-ico { margin-right: 6px; font-size: 14px; }
.paud-entity { font-weight: 500; color: var(--ink, #284558); }
.paud-diff   { font-family: var(--mono, ui-monospace, 'SFMono-Regular', monospace); font-size: 11.5px; }
.paud-before { color: var(--muted, #5e6b7a); }
.paud-arrow  { margin: 0 6px; color: #475569; }
.paud-after  { color: #047857; font-weight: 600; }
.paud-actor  { color: var(--muted, #5e6b7a); white-space: nowrap; }
.paud-notes  { color: var(--muted, #5e6b7a); font-size: 11.5px; }

/* Crew search input on period detail. */
.pvt-tail {
  margin-left: auto;
  display: inline-flex;
  gap: 8px;
  align-items: center;
}
.payroll-search-input {
  padding: 6px 12px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
  min-width: 220px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.payroll-search-input:focus {
  outline: none;
  border-color: var(--accent, #d63438);
  box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.08);
}

/* Print stylesheet — Summary view becomes a clean PDF.
   .is-payroll-printing is added by Payroll.printSummary() to flag a
   deliberate print (so we can suppress nav etc. without affecting
   other modules' print). @page rules ensure no excessive margins. */
@media print {
  body.is-payroll-printing #app-nav,
  body.is-payroll-printing .drawer-shell,
  body.is-payroll-printing #app-header,
  body.is-payroll-printing #toast,
  body.is-payroll-printing .payroll-top-tabs,
  body.is-payroll-printing .payroll-toolbar,
  body.is-payroll-printing .payroll-anomalies,
  body.is-payroll-printing .payroll-junk-banner,
  body.is-payroll-printing .payroll-auto-banner,
  body.is-payroll-printing .payroll-view-toggle,
  body.is-payroll-printing .payroll-back,
  body.is-payroll-printing .payroll-hero-actions,
  body.is-payroll-printing .pdg-actions,
  body.is-payroll-printing .payroll-drawer,
  body.is-payroll-printing .pvt-tail {
    display: none !important;
  }
  body.is-payroll-printing .payroll-hero {
    background: #fff !important;
    color: var(--ink, #284558) !important;
    border: 1px solid #e2e8ec;
    padding: 16px 18px;
    page-break-after: avoid;
  }
  body.is-payroll-printing .payroll-hero-title { color: var(--ink, #284558); font-size: 22px; }
  body.is-payroll-printing .payroll-hero-eyebrow { color: var(--muted, #5e6b7a); }
  body.is-payroll-printing .payroll-hero-meta { color: var(--muted, #5e6b7a); }
  body.is-payroll-printing .payroll-stats {
    page-break-inside: avoid;
    grid-template-columns: repeat(5, 1fr);
  }
  body.is-payroll-printing .pst-card { padding: 8px 10px; min-height: 0; }
  body.is-payroll-printing .pst-card.is-grand { background: #f6f8fa !important; color: var(--ink, #284558) !important; border: 1px solid #e2e8ec !important; }
  body.is-payroll-printing .pst-card.is-grand label,
  body.is-payroll-printing .pst-card.is-grand small,
  body.is-payroll-printing .pst-card.is-grand strong { color: var(--ink, #284558) !important; }
  body.is-payroll-printing .payroll-summary-scroll { overflow: visible !important; border: 0; box-shadow: none; }
  body.is-payroll-printing table.payroll-summary-table { font-size: 10px; width: 100%; }
  body.is-payroll-printing .payroll-summary-table th,
  body.is-payroll-printing .payroll-summary-table td { padding: 4px 6px; }
  body.is-payroll-printing .psum-row { page-break-inside: avoid; }
  body.is-payroll-printing .psum-totals-row { page-break-before: avoid; }
  body.is-payroll-printing .psum-input { border: 0 !important; background: transparent !important; padding: 0 !important; }
  body.is-payroll-printing .pdg-avatar { display: none; }
  body.is-payroll-printing .pdg-name-flex .pdg-name-line { font-size: 11px; }
  body.is-payroll-printing .pdg-name-flex .pdg-name-sub { font-size: 9px; }
  /* Preserve colour for status/dept tints. */
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; color-adjust: exact !important; }
  @page { margin: 12mm; size: landscape; }
}

/* ============================================================
   R64 — PayrollAssistant (Claude-powered chat panel)
   ============================================================ */
.ptt-btn.pa-fab {
  margin-left: auto;
  background: linear-gradient(135deg, #6d28d9, #2563eb);
  color: #fff;
  font-weight: 700;
}
.ptt-btn.pa-fab:hover { background: linear-gradient(135deg, #7c3aed, #3b82f6); color: #fff; box-shadow: 0 4px 12px rgba(124, 58, 237, 0.25); }

.pa-panel {
  position: fixed; inset: 0; z-index: 95;
  pointer-events: none;
}
.pa-panel.is-open { pointer-events: auto; }
.pa-backdrop {
  position: absolute; inset: 0;
  background: rgba(40, 69, 88, 0.30);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 200ms ease;
}
.pa-panel.is-open .pa-backdrop { opacity: 1; }
.pa-card {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 520px; max-width: 100vw;
  background: #fff;
  box-shadow: -20px 0 40px rgba(40, 69, 88, 0.18);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.pa-panel.is-open .pa-card { transform: translateX(0); }

.pa-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line, #eef0f3);
  background: linear-gradient(135deg, #284558, #1a3760);
  color: #fff;
  position: relative;
}
.pa-head-id { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; }
.pa-avatar {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: linear-gradient(135deg, #7c3aed, #2563eb);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.15);
}
.pa-head h3  { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.005em; }
.pa-head small { display: block; font-size: 11.5px; opacity: 0.78; margin-top: 1px; }
.pa-close {
  width: 32px; height: 32px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  border-radius: 8px; font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: background 120ms ease;
}
.pa-close:hover { background: rgba(255, 255, 255, 0.18); }

.pa-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
  background: linear-gradient(180deg, #f9fafb, #fdfdfd);
}

.pa-intro {
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 13px;
  color: var(--ink, #284558);
}
.pa-intro p { margin: 0 0 8px; }
.pa-quick { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.pa-quick button {
  font-size: 12px;
  padding: 6px 10px;
  background: rgba(40, 69, 88, 0.05);
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 999px;
  cursor: pointer;
  color: var(--ink, #284558);
  transition: background 120ms ease, border-color 120ms ease;
}
.pa-quick button:hover { background: rgba(40, 69, 88, 0.10); border-color: rgba(40, 69, 88, 0.20); }

.pa-msg { display: flex; gap: 10px; }
.pa-msg-user { justify-content: flex-end; }
.pa-msg-assistant { align-items: flex-start; }
.pa-msg-avatar {
  flex: 0 0 28px;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, #7c3aed, #2563eb);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px;
  margin-top: 2px;
}
.pa-msg-body { flex: 1; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pa-bubble {
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.45;
  max-width: 100%;
  word-wrap: break-word;
  color: var(--ink, #284558);
}
.pa-msg-user .pa-bubble {
  background: linear-gradient(135deg, #284558, #1a3760);
  color: #fff;
  border-color: transparent;
  max-width: 80%;
}
.pa-thinking {
  display: inline-flex; gap: 4px;
  padding: 12px 14px;
}
.pa-thinking span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--muted, #94a3b8);
  animation: pa-blink 1.4s infinite;
}
.pa-thinking span:nth-child(2) { animation-delay: 0.18s; }
.pa-thinking span:nth-child(3) { animation-delay: 0.36s; }
@keyframes pa-blink {
  0%, 80%, 100% { opacity: 0.3; transform: scale(0.9); }
  40%           { opacity: 1;   transform: scale(1.1); }
}

.pa-tool-readout {
  font-size: 11.5px;
  color: var(--muted, #5e6b7a);
  font-style: italic;
  padding: 2px 4px;
}
.pa-tool-readout code {
  background: rgba(40, 69, 88, 0.06);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 11px;
}

.pa-tool-confirm {
  background: #fffbeb;
  border: 2px solid rgba(202, 138, 4, 0.45);
  border-radius: 12px;
  padding: 12px 14px;
  margin-top: 4px;
}
.pa-tool-confirm-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px;
  color: #713f12;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.pa-tool-name {
  background: rgba(202, 138, 4, 0.22);
  padding: 2px 8px;
  border-radius: 999px;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10.5px;
}
.pa-tool-confirm-body { font-size: 13px; color: #4b3009; line-height: 1.5; margin-bottom: 12px; }
.pa-tool-confirm-body strong { color: #713f12; }
.pa-tool-confirm-actions { display: flex; gap: 8px; justify-content: flex-end; }

.pa-tool-done {
  display: flex; align-items: center; gap: 8px;
  background: rgba(16, 185, 129, 0.08);
  border: 1px solid rgba(16, 185, 129, 0.22);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 12.5px;
  color: var(--ink, #284558);
}
.pa-tool-done-icon { font-size: 14px; color: #047857; }
.pa-tool-done small { margin-left: auto; color: var(--muted, #5e6b7a); font-size: 11px; }

.pa-composer {
  display: flex; gap: 10px;
  padding: 12px 18px 16px;
  border-top: 1px solid var(--line, #eef0f3);
  background: #fff;
  align-items: flex-end;
}
.pa-composer textarea {
  flex: 1;
  resize: none;
  padding: 10px 12px;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 10px;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  line-height: 1.45;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.pa-composer textarea:focus {
  outline: none;
  border-color: #6d28d9;
  box-shadow: 0 0 0 3px rgba(109, 40, 217, 0.10);
}
.pa-composer button { flex-shrink: 0; }

@media (max-width: 760px) {
  .pa-card {
    top: auto; right: 0; left: 0; bottom: 0;
    width: 100%; max-height: 90vh;
    transform: translateY(100%);
    border-radius: 16px 16px 0 0;
  }
  .pa-panel.is-open .pa-card { transform: translateY(0); }
}

/* ---------- R60 — View toggle + Summary table ---------- */
.payroll-view-toggle {
  display: flex; align-items: center; gap: 4px;
  background: #fff;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 12px;
  padding: 4px;
  width: fit-content;
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.03);
}
.pvt-btn {
  background: transparent;
  border: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted, #5e6b7a);
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: background 120ms ease, color 120ms ease;
}
.pvt-btn:hover { background: rgba(40, 69, 88, 0.04); color: var(--ink, #284558); }
.pvt-btn.is-on {
  background: var(--ink, #284558);
  color: #fff;
  box-shadow: 0 2px 6px rgba(40, 69, 88, 0.18);
}
.pvt-hint {
  margin-left: 14px;
  font-size: 12px;
  color: var(--muted, #5e6b7a);
}

/* Summary table — wide spreadsheet view. */
.payroll-summary-scroll {
  overflow-x: auto;
  border: 1px solid var(--line, #e2e8ec);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(40, 69, 88, 0.03);
}
table.payroll-summary-table {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: 12.5px;
}
.payroll-summary-table th, .payroll-summary-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line, #eef0f3);
  border-right: 1px solid var(--line, #f6f8fa);
  white-space: nowrap;
  background: #fff;
  vertical-align: middle;
}
.payroll-summary-table th {
  position: sticky; top: 0; z-index: 2;
  background: linear-gradient(180deg, #f9fafb, #f3f5f8);
  font-weight: 700;
  font-size: 10.5px;
  color: var(--muted, #5e6b7a);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 10px 10px;
  border-bottom: 1px solid var(--line, #dee2e6);
  text-align: center;
  line-height: 1.2;
}
.payroll-summary-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.payroll-summary-table th.psum-stick,
.payroll-summary-table td.psum-stick {
  position: sticky; left: 0; z-index: 4;
  text-align: left;
  background: #fff;
  border-right: 2px solid var(--line, #e2e8ec);
  min-width: 240px;
  padding: 10px 14px;
}
.payroll-summary-table thead th.psum-stick { z-index: 6; background: linear-gradient(180deg, #f9fafb, #f3f5f8); }
.payroll-summary-table tbody tr.psum-row:nth-of-type(odd) td       { background: #fcfdfe; }
.payroll-summary-table tbody tr.psum-row:nth-of-type(odd) .psum-stick { background: #fcfdfe; }
.payroll-summary-table tbody tr.psum-row:hover td       { background: rgba(40, 69, 88, 0.025); }
/* Sticky cell hover must be opaque — see duty-grid note above. */
.payroll-summary-table tbody tr.psum-row:hover .psum-stick { background: #f1f3f6; }
.psum-row.is-senior .psum-stick { box-shadow: inset 4px 0 0 0 #d97706; }
.psum-row.is-new-hire .psum-stick { box-shadow: inset 4px 0 0 0 #10b981; }
.psum-name { cursor: pointer; }

/* Dept dividers in summary. */
.psum-dept-row td { padding: 0; border-top: 1px solid var(--line, #dee2e6); border-bottom: 1px solid var(--line, #dee2e6); }
.psum-dept-row .psum-dept-stick {
  position: sticky; left: 0; z-index: 2;
  /* Layered over white so the sticky cell stays opaque. */
  background: linear-gradient(90deg, rgba(40, 69, 88, 0.10), rgba(40, 69, 88, 0.06)), #fff !important;
  padding: 9px 14px !important;
  text-align: left;
  border-right: 2px solid var(--line, #e2e8ec);
  min-width: 240px;
}
.psum-dept-row .psum-dept-fill {
  background: linear-gradient(90deg, rgba(40, 69, 88, 0.04), rgba(40, 69, 88, 0.01));
}

/* Inline editable inputs in summary. */
.psum-input {
  width: 88px;
  text-align: right;
  padding: 5px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  font-size: 12.5px;
  background: transparent;
  font-variant-numeric: tabular-nums;
  color: var(--ink, #284558);
  transition: border-color 120ms ease, background 120ms ease;
}
.psum-input:hover { border-color: var(--line, #d8e0e6); background: #fff; }
.psum-input:focus {
  outline: none;
  border-color: var(--accent, #d63438);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.08);
}
.psum-comments-col { min-width: 220px; }
.payroll-summary-table .psum-comments { padding: 4px 6px; }
.psum-comments-input { width: 100%; text-align: left; min-width: 200px; }
.psum-subtotal { background: rgba(16, 185, 129, 0.06) !important; }
.payroll-summary-table tbody tr.psum-row:nth-of-type(odd) .psum-subtotal { background: rgba(16, 185, 129, 0.09) !important; }

/* Negative / low remaining cell tinting. */
.payroll-summary-table td.is-negative { color: var(--danger); font-weight: 700; }
.payroll-summary-table td.is-low      { color: #b45309; font-weight: 600; }

/* Totals row. */
.psum-totals-row td {
  background: linear-gradient(180deg, #f3f5f8, #e9edf2) !important;
  border-top: 2px solid var(--ink, #284558);
  padding: 10px 10px;
  font-size: 12.5px;
}
.psum-totals-row .psum-stick {
  background: linear-gradient(180deg, #f3f5f8, #e9edf2) !important;
  font-weight: 700;
  color: var(--ink, #284558);
  letter-spacing: 0.02em;
}
.psum-totals-row td strong { font-variant-numeric: tabular-nums; color: var(--ink, #284558); }

/* ---------- R59 — Grid additions ---------- */
/* Day-of-week header: tiny letter above the day number. */
.pdg-day-dow { display: block; font-size: 9px; font-weight: 500; color: var(--muted, #9aa5b1); letter-spacing: 0.04em; line-height: 1; margin-bottom: 2px; }
.pdg-day-num { display: block; font-size: 12px; font-weight: 700; color: var(--ink, #284558); line-height: 1; }
.pdg-day.is-weekend .pdg-day-num { color: #b45309; }
.pdg-day.is-weekend { background: linear-gradient(180deg, #fef6e7, #fde9c0) !important; }
.pdg-cell.is-weekend.is-empty { background: rgba(245, 158, 11, 0.03); }

/* Chev on the sticky crew column (hints clickable drawer). */
.pdg-chev {
  margin-left: 4px;
  color: var(--muted, #b3bcc6);
  font-size: 18px;
  font-weight: 400;
  opacity: 0;
  transition: opacity 140ms ease, transform 140ms ease;
}
.payroll-duty-grid tbody tr.pdg-row .pdg-stick:hover .pdg-chev { opacity: 1; transform: translateX(2px); }
.payroll-duty-grid tbody tr.pdg-row .pdg-stick { cursor: pointer; }

/* Senior crew rows get a subtle gold edge marker. We use box-shadow
   instead of an absolutely-positioned ::before because overriding
   position:sticky with position:relative (R59) silently broke the
   sticky-left behaviour on every senior row — Captain, Chief Officer,
   Chief Engineer, etc. would scroll off-screen with the grid.
   box-shadow is purely visual and doesn't touch positioning. */
.pdg-row.is-senior .pdg-stick {
  box-shadow: inset 4px 0 0 0 #d97706;
  padding-left: 14px !important;
}

/* Anomaly dots on name. */
.pdg-anomaly {
  display: inline-flex;
  font-size: 11px;
  margin-left: 4px;
  cursor: help;
}
.pdg-anomaly.is-warn   { color: #b45309; }
.pdg-anomaly.is-info   { color: #5e6b7a; font-weight: 700; }
.pdg-anomaly.is-danger { color: var(--danger); }

/* Spotlight flash when user clicks an anomaly chip. */
@keyframes pdg-spotlight {
  0%   { background: rgba(214, 52, 56, 0.16); box-shadow: inset 0 0 0 2px rgba(214, 52, 56, 0.45); }
  100% { background: transparent; box-shadow: inset 0 0 0 0 transparent; }
}
.pdg-row.is-spotlight td { animation: pdg-spotlight 2.4s ease-out; }

/* ---------- R59 — Slide-in row drawer ---------- */
.payroll-drawer {
  position: fixed; inset: 0; z-index: 95;
  pointer-events: none;
}
.payroll-drawer.is-open { pointer-events: auto; }
.payroll-drawer-backdrop {
  position: absolute; inset: 0;
  background: rgba(40, 69, 88, 0.32);
  opacity: 0;
  transition: opacity 200ms ease;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.payroll-drawer.is-open .payroll-drawer-backdrop { opacity: 1; }
.payroll-drawer-card {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 460px; max-width: 100vw;
  background: #fff;
  box-shadow: -20px 0 40px rgba(40, 69, 88, 0.18);
  transform: translateX(100%);
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.payroll-drawer.is-open .payroll-drawer-card { transform: translateX(0); }
.pdr-body { overflow-y: auto; padding: 22px 24px 24px; flex: 1; }

.pdr-head {
  display: flex; align-items: flex-start; gap: 10px;
  padding-bottom: 16px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line, #eef2f5);
  position: relative;
}
.pdr-close {
  position: absolute; right: -4px; top: -4px;
  width: 32px; height: 32px;
  border: 1px solid var(--line, #d8e0e6);
  background: #fff;
  border-radius: 8px;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  color: var(--muted, #5e6b7a);
  transition: background 100ms ease, color 100ms ease;
}
.pdr-close:hover { background: rgba(40, 69, 88, 0.05); color: var(--ink, #284558); }
.pdr-id { display: flex; align-items: center; gap: 14px; }
.pdr-avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(40, 69, 88, 0.15), rgba(40, 69, 88, 0.30));
  color: var(--ink, #284558);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  font-weight: 700;
}
.pdr-id-text h3 { margin: 0; font-size: 18px; letter-spacing: -0.01em; color: var(--ink, #284558); }
.pdr-id-sub { font-size: 13px; color: var(--muted, #5e6b7a); margin-top: 2px; display: flex; gap: 6px; align-items: center; }
.pdr-id-dot { opacity: 0.4; }
.pdr-badges { margin-top: 6px; display: flex; gap: 6px; flex-wrap: wrap; }
.pdr-badge {
  display: inline-flex;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(40, 69, 88, 0.08);
  color: var(--ink, #284558);
}
.pdr-badge.is-new     { background: rgba(16, 185, 129, 0.16); color: #047857; }
.pdr-badge.is-leaving { background: rgba(245, 158, 11, 0.18); color: #92400e; }

.pdr-section { margin-bottom: 22px; }
.pdr-section h4 {
  margin: 0 0 10px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--muted, #5e6b7a);
  font-weight: 700;
  display: flex; align-items: center; justify-content: space-between;
}
.pdr-section-sub { text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 12px; color: var(--muted, #5e6b7a); }

/* Pay panel. */
.pdr-pay {
  background: #f8fafc;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 10px;
  padding: 10px 14px;
}
.pdr-pay-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  font-size: 13px;
  color: var(--ink, #284558);
  border-bottom: 1px dashed rgba(40, 69, 88, 0.08);
}
.pdr-pay-row:last-child { border-bottom: 0; }
.pdr-pay-row.pdr-derived  { color: var(--muted, #5e6b7a); font-size: 12.5px; }
.pdr-pay-row.pdr-gross    { padding-top: 12px; font-weight: 700; font-size: 14px; }
.pdr-pay-row.pdr-gross strong { font-size: 16px; font-variant-numeric: tabular-nums; }
.pdr-input-wrap {
  display: inline-flex; align-items: center;
  background: #fff;
  border: 1px solid var(--line, #d8e0e6);
  border-radius: 8px;
  padding: 4px 8px 4px 10px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.pdr-input-wrap:focus-within { border-color: var(--accent, #d63438); box-shadow: 0 0 0 3px rgba(214, 52, 56, 0.10); }
.pdr-input-ccy { font-size: 11px; color: var(--muted, #5e6b7a); font-weight: 600; margin-right: 6px; }
.pdr-input-wrap input {
  width: 110px;
  border: 0;
  background: transparent;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink, #284558);
  text-align: right;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.pdr-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; flex-wrap: wrap; }

/* Days breakdown cards. */
.pdr-days {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
}
.pdr-day-card {
  border-radius: 10px;
  padding: 10px 8px;
  text-align: center;
  border: 1px solid transparent;
}
.pdr-day-card.is-D { background: rgba(16, 185, 129, 0.10); border-color: rgba(16, 185, 129, 0.25); }
.pdr-day-card.is-H { background: rgba(37, 99, 235, 0.10);  border-color: rgba(37, 99, 235, 0.25); }
.pdr-day-card.is-S { background: rgba(245, 158, 11, 0.12); border-color: rgba(245, 158, 11, 0.28); }
.pdr-day-card.is-T { background: rgba(124, 58, 237, 0.10); border-color: rgba(124, 58, 237, 0.25); }
.pdr-day-card.is-O { background: rgba(40, 69, 88, 0.05);   border-color: rgba(40, 69, 88, 0.15); }
.pdr-day-card label { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
.pdr-day-card.is-D label { color: #047857; }
.pdr-day-card.is-H label { color: #1d4ed8; }
.pdr-day-card.is-S label { color: #92400e; }
.pdr-day-card.is-T label { color: #6d28d9; }
.pdr-day-card.is-O label { color: #475569; }
.pdr-day-card strong { display: block; font-size: 22px; font-weight: 700; color: var(--ink, #284558); line-height: 1.1; margin: 3px 0; font-variant-numeric: tabular-nums; }
.pdr-day-card small { font-size: 11px; color: var(--muted, #5e6b7a); }

/* Leave panel — horizontal bar + grid. */
.pdr-leave-bar {
  position: relative;
  height: 8px;
  border-radius: 999px;
  background: rgba(40, 69, 88, 0.08);
  overflow: hidden;
  margin-bottom: 14px;
}
.pdr-leave-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: linear-gradient(90deg, #2563eb, #1d4ed8);
  border-radius: 999px;
  transition: width 240ms ease;
}
.pdr-leave-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px;
  font-size: 13px;
}
.pdr-leave-grid label { display: block; font-size: 11px; color: var(--muted, #5e6b7a); }
.pdr-leave-grid strong { font-size: 14px; color: var(--ink, #284558); font-variant-numeric: tabular-nums; }
.pdr-leave-grid .is-grand {
  grid-column: 1 / -1;
  background: rgba(16, 185, 129, 0.08);
  border-radius: 8px;
  padding: 8px 12px;
  margin-top: 4px;
}
.pdr-leave-grid .is-grand strong { font-size: 18px; color: #047857; }
.pdr-leave-grid .is-grand strong.is-negative { color: var(--danger); }
.pdr-empty {
  padding: 14px;
  background: #f8fafc;
  border: 1px dashed var(--line, #d8e0e6);
  border-radius: 8px;
  font-size: 12.5px;
  color: var(--muted, #5e6b7a);
}

/* Contract panel. */
.pdr-contract {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  background: #f8fafc;
  border: 1px solid var(--line, #e7ecf0);
  border-radius: 10px;
  padding: 12px 14px;
}
.pdr-contract label { display: block; font-size: 10.5px; color: var(--muted, #5e6b7a); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; margin-bottom: 3px; }
.pdr-contract strong { font-size: 13px; color: var(--ink, #284558); font-variant-numeric: tabular-nums; }
.pdr-foot-note { font-size: 11.5px; color: var(--muted, #5e6b7a); margin: 10px 0 0; }

/* Mobile: drawer becomes a bottom sheet. */
@media (max-width: 760px) {
  .payroll-drawer-card {
    top: auto; right: 0; left: 0; bottom: 0;
    width: 100%;
    max-height: 86vh;
    transform: translateY(100%);
    border-radius: 20px 20px 0 0;
  }
  .payroll-drawer.is-open .payroll-drawer-card { transform: translateY(0); }
}

/* Stats strip: stack to 2-col on narrow screens. */
@media (max-width: 1100px) {
  .payroll-stats { grid-template-columns: repeat(2, 1fr); }
  .pst-card.is-grand { grid-column: span 2; }
}
@media (max-width: 640px) {
  .payroll-stats { grid-template-columns: 1fr; }
  .pst-card.is-grand { grid-column: span 1; }
  .payroll-hero { flex-direction: column; align-items: stretch; padding: 18px; }
  .payroll-hero-title { font-size: 22px; }
  .payroll-hero-actions { justify-content: flex-end; }
  .pdr-days { grid-template-columns: repeat(2, 1fr); }
  .pdr-contract { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .payroll-footer { grid-template-columns: 1fr; }
  .payroll-duty-grid .pdg-stick { min-width: 160px; }
  .pdg-name-line { font-size: 12px; }
}

/* ----- Mobile: TOC drawer ----- */
@media (max-width: 900px) {
  #bok-toc-toggle { display: inline-flex; }
  .bok-shell { grid-template-columns: 1fr; min-height: 0; }
  .bok-toc {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    height: 100dvh;
    width: 86vw;
    max-width: 360px;
    z-index: 65;
    border-radius: 0;
    border: none;
    border-left: 1px solid var(--line, #d8e0e6);
    transform: translateX(100%);
    transition: transform 200ms ease-out;
    box-shadow: -8px 0 24px rgba(40, 69, 88, 0.16);
  }
  .bok-toc.open { transform: translateX(0); }
  .bok-toc-backdrop.open { display: block; }
  .bok-content {
    max-height: none;
    padding: 0 16px 24px;
  }
  body.bok-toc-open { overflow: hidden; }
}

@media (max-width: 640px) {
  .bok-search-input { width: 100%; }
  #page-book .bok-header { flex-direction: column; align-items: stretch; }
  #page-book .bok-header-actions { width: 100%; }
  .bok-section { padding: 22px 0 8px; }
  .bok-section-head h2 { font-size: 19px; }
  .bok-section.is-child .bok-section-head h2 { font-size: 16px; }
  .bok-table { font-size: 12.5px; }
  .bok-table th, .bok-table td { padding: 6px 8px; }
  /* Tables get a horizontal scroll container so wide spec tables
     stay legible without breaking the row layout. */
  .bok-section-body { overflow-x: auto; }
  .bok-facts { grid-template-columns: 1fr; padding: 12px; }
  .bok-edit-fact-row { grid-template-columns: 1fr; }
  .bok-edit-fact-row .bok-fact-del { justify-self: end; width: 32px; }
}

/* ============================================================
   R42 / QW4 — Auditor read-only mode
   ============================================================ */
/* Hide write-controls when body has .is-auditor. Anything tagged
   data-write="1" disappears for auditor users. The DB enforces
   the restriction; this is purely UX so they don't see "Save"
   buttons that will throw an error when clicked. */
body.is-auditor [data-write],
body.is-auditor .btn-write-only {
  display: none !important;
}
body.is-auditor [data-readonly-disable] {
  pointer-events: none;
  opacity: 0.5;
  filter: grayscale(0.4);
}
/* Tag auditor pills uniformly */
.auditor-pill {
  display: inline-block;
  background: #1f2937;
  color: #fde68a;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: 0.5px;
}

/* ============================================================
   R44 — Collapsible PO department groups (uses native <details>)
   ============================================================ */
/* Convert the existing .po-group-head styling so it works as a
   <summary> instead of a <header>: kill the native disclosure
   triangle, make the whole row clickable. */
details.po-group > summary.po-group-head {
  cursor: pointer;
  list-style: none;
  user-select: none;
}
details.po-group > summary.po-group-head::-webkit-details-marker { display: none; }
details.po-group > summary.po-group-head::marker            { display: none; }

/* Animated chevron — rotates 90° when collapsed. */
.po-group-chevron {
  display: inline-block;
  width: 14px;
  text-align: center;
  font-size: 11px;
  color: var(--navy-700, #2A4A6F);
  transition: transform 160ms ease;
  margin-right: 2px;
}
details.po-group:not([open]) > summary.po-group-head .po-group-chevron {
  transform: rotate(-90deg);
}

/* When collapsed, drop the bottom border on the summary so the
   whole capsule looks closed off cleanly. */
details.po-group:not([open]) > summary.po-group-head {
  border-bottom-color: transparent;
}

/* Hover affordance so it's discoverable as clickable. */
details.po-group > summary.po-group-head:hover {
  background: linear-gradient(180deg, rgba(20,37,61,0.07), rgba(20,37,61,0.02));
}
details.po-group > summary.po-group-head:focus-visible {
  outline: 2px solid var(--accent, #3b82f6);
  outline-offset: -2px;
}

/* R44 (alignment fix) — when the chevron sits inside the summary
   alongside h3 and the totals block, the original
   justify-content:space-between distributes all 3 across the row,
   pushing the title to the centre. Pin the totals to the far right
   so chevron + title sit flush left as a tight pair. */
details.po-group > summary.po-group-head { gap: 10px; }
details.po-group > summary.po-group-head .po-group-totals { margin-left: auto; }

/* ============================================================
   NAV DRAWER (R44 — 2026-05-10)
   Burgess-style left-slide primary navigation. Replaces the old
   horizontal portal-nav dropdowns and the mobile-drawer/MobileNav
   shim — same UI on every viewport. Two-panel pattern: category
   buttons on the primary panel, sub-items on the secondary panel
   that slides over (mobile) or sits beside (desktop).
   ============================================================ */

/* Minimal top bar — burger + HOME + spacer + search + bell + user.
   The .portal-nav--minimal modifier overrides the legacy horizontal-
   nav rules. `flex: 1` is critical: without it the nav shrinks to its
   children's width and `.nav-spacer { flex: 1 }` has no remaining
   space to push the right-side controls hard right. */
.portal-nav--minimal {
  display: flex !important;
  align-items: center;
  gap: 10px;
  flex: 1;
  width: 100%;
}
.nav-burger {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #fff;
  width: 36px; height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
  transition: background 0.16s var(--ease-precise), border-color 0.16s var(--ease-precise);
}
.nav-burger:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.30); }
.nav-burger:focus-visible { outline: 2px solid var(--red-500); outline-offset: 2px; }
.nav-burger .ic { width: 20px; height: 20px; }

.nav-home {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--cream) !important;
  text-decoration: none;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  transition: background 0.16s var(--ease-precise);
}
.nav-home:hover { background: rgba(255,255,255,0.06); color: var(--cream) !important; }
.nav-home .ic { width: 14px; height: 14px; opacity: 0.85; }

/* Header search — Linear/Stripe-style search field with its own
   popover dropdown that opens under the input. Independent of the
   side drawer; clicking the input no longer opens the drawer as
   a side effect (R44 revision, 2026-05-10). */
.header-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 6px;
  width: 240px;
  max-width: 28vw;
  flex: 0 0 auto;
  position: relative;
  transition: background 0.16s var(--ease-precise), border-color 0.16s var(--ease-precise), width 0.18s var(--ease-precise);
}
.header-search:focus-within {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.25);
}
.header-search .ic { width: 14px; height: 14px; opacity: 0.55; flex: none; color: var(--cream); }
.header-search input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--cream);
  font: 13px/1.4 var(--sans);
  padding: 0;
}
.header-search input::placeholder { color: rgba(255, 255, 255, 0.45); }

/* Hide the header search on narrow viewports — at phone width the
   drawer's hamburger is the way in and the search box would squeeze
   the bell + user pill off-screen. */
@media (max-width: 760px) {
  .header-search { display: none; }
}

/* Popover results dropdown — appears below the header input when
   the user types. Light surface (page-coloured) so it reads as a
   floating panel on top of the navy header strip. */
.header-search-results {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  min-width: 320px;
  max-height: 70vh;
  overflow-y: auto;
  background: #fff;
  border-radius: 8px;
  box-shadow: var(--shadow-modal);
  z-index: 1250;
  padding: 4px;
}
.header-search-empty {
  margin: 16px;
  font-size: 13px;
  color: var(--ink-muted);
  text-align: center;
}
.header-search-result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  width: 100%;
  text-align: left;
  font-family: var(--sans);
  color: var(--ink);
}
.header-search-result:hover,
.header-search-result:focus-visible {
  background: var(--cream-dark);
  outline: none;
}
.header-search-result .hsr-cat {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: var(--ink-muted);
}
.header-search-result .hsr-label {
  font-size: 13px;
  color: var(--ink);
  font-weight: 500;
}
.header-search-result .hsr-sub {
  font-size: 12px;
  color: var(--ink-muted);
  font-weight: 400;
}

/* Backdrop + drawer container. The drawer is fixed top-left, full
   viewport height, and slides in from x = -100% to 0. */
.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: 1300;
  pointer-events: none;
}
.nav-drawer.is-open { pointer-events: auto; }
.nav-drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(40, 69, 88, 0.42);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 0.24s var(--ease-precise);
}
.nav-drawer.is-open .nav-drawer-backdrop { opacity: 1; }

/* Primary panel — fixed width, slides in from the left. The
   gradient mirrors Burgess's teal-to-deeper-teal but in our brand
   navy so the drawer reads as part of the same vessel chrome. */
.nav-drawer-primary {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 248px;
  max-width: 88vw;
  background: linear-gradient(180deg, #4A7791 0%, #38617A 70%, #284558 100%);
  color: var(--cream);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.28s var(--ease-precise);
  box-shadow: 12px 0 40px -12px rgba(0,0,0,0.45);
  /* Internal scroll only — the foot stays pinned. */
  overflow: hidden;
}
.nav-drawer.is-open .nav-drawer-primary { transform: translateX(0); }

.nav-drawer-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 18px 8px;
}
.nav-drawer-close {
  background: transparent;
  border: 0;
  color: var(--cream);
  width: 32px; height: 32px;
  border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.16s var(--ease-precise);
}
.nav-drawer-close:hover { background: rgba(255,255,255,0.06); }
.nav-drawer-close:focus-visible { outline: 2px solid var(--red-500); outline-offset: 2px; }
.nav-drawer-eyebrow {
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: var(--track-eyebrow);
  font-weight: 600;
  opacity: 0.55;
}

/* Search input — Linear-style: hairline ring, search icon prefix,
   the input itself is borderless and inherits the panel colour. */
.nav-drawer-search {
  margin: 4px 18px 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 6px;
  transition: border-color 0.16s var(--ease-precise), background 0.16s var(--ease-precise);
}
.nav-drawer-search:focus-within {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.20);
}
.nav-drawer-search .ic { width: 16px; height: 16px; opacity: 0.55; flex: none; }
.nav-drawer-search input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--cream);
  font: 14px/1.4 var(--sans);
}
.nav-drawer-search input::placeholder { color: rgba(255,255,255,0.4); }

/* Category list — flat buttons with right-chevron, hairline rule
   between rows. .is-active is the focused/hovered visual state. */
.nav-drawer-cats {
  display: flex;
  flex-direction: column;
  padding: 4px 8px 12px;
  overflow-y: auto;
  flex: 1;
}
.drawer-cat {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 12px;
  background: transparent;
  border: 0;
  color: var(--cream);
  cursor: pointer;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  text-align: left;
  border-radius: 6px;
  transition: background 0.14s var(--ease-precise);
  position: relative;
}
.drawer-cat::after {
  content: '';
  position: absolute;
  left: 12px; right: 12px; bottom: 0;
  height: 1px;
  background: rgba(255,255,255,0.06);
}
.drawer-cat:last-child::after { display: none; }
.drawer-cat:hover { background: rgba(255,255,255,0.05); }
.drawer-cat:focus-visible { outline: 2px solid var(--red-500); outline-offset: -2px; }
.drawer-cat-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: rgba(255,255,255,0.06);
  flex: none;
  color: rgba(255,255,255,0.85);
}
.drawer-cat-glyph .ic { width: 14px; height: 14px; }
.drawer-cat-label { flex: 1; }
.drawer-cat-chev { width: 14px; height: 14px; opacity: 0.4; flex: none; }

/* Search-results panel replaces the cats list when the input has text. */
.nav-drawer-search-results {
  flex: 1;
  overflow-y: auto;
  padding: 4px 8px 12px;
}
.nav-drawer-search-empty {
  margin: 24px 14px;
  font-size: 13px;
  color: rgba(255,255,255,0.5);
  text-align: center;
}
.drawer-search-result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--cream);
  cursor: pointer;
  font-family: var(--sans);
  text-align: left;
  width: 100%;
  position: relative;
}
.drawer-search-result:hover { background: rgba(255,255,255,0.05); }
.drawer-search-result .dsr-cat {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  color: rgba(255,255,255,0.5);
}
.drawer-search-result .dsr-label {
  font-size: 14px;
  font-weight: 500;
}
.drawer-search-result .dsr-chev {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 12px; height: 12px;
  opacity: 0.35;
}

/* Foot — quick links pinned at the bottom of the primary panel. */
.nav-drawer-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px 18px;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-size: 12px;
  color: rgba(255,255,255,0.55);
}
.nav-drawer-foot a,
.nav-drawer-foot button {
  color: rgba(255,255,255,0.85);
  background: transparent;
  border: 0;
  font: inherit;
  cursor: pointer;
  padding: 0;
}
.nav-drawer-foot a:hover,
.nav-drawer-foot button:hover { color: var(--cream); }
.nav-drawer-foot-sep { opacity: 0.5; }
.nav-drawer-signout { color: var(--red-500) !important; }
/* Single-line version stamp in the drawer foot (Captain, 2026-05-28). */
.nav-drawer-foot-version {
  font-size: 11px;
  color: var(--ink-muted, rgba(255,255,255,0.45));
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Secondary panel — slides in from the right edge of the primary on
   desktop (sits at left: 320px), or covers the primary on mobile. */
.nav-drawer-secondary {
  position: absolute;
  top: 0; bottom: 0;
  left: 248px;
  width: 268px;
  max-width: calc(88vw - 0px);
  background: #38617A;
  color: var(--cream);
  display: flex;
  flex-direction: column;
  transform: translateX(-110%);
  transition: transform 0.28s var(--ease-precise), opacity 0.2s var(--ease-precise);
  opacity: 0;
  pointer-events: none;
  border-left: 1px solid rgba(255,255,255,0.06);
  box-shadow: 12px 0 40px -12px rgba(0,0,0,0.45);
  overflow: hidden;
}
.nav-drawer.has-secondary .nav-drawer-secondary {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}

.nav-drawer-secondary-head {
  padding: 14px 18px 8px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.nav-drawer-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 0;
  color: var(--cream);
  font: 600 12px/1.4 var(--sans);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 6px;
}
.nav-drawer-back:hover { background: rgba(255,255,255,0.05); }
.nav-drawer-back .ic { width: 14px; height: 14px; }

.nav-drawer-secondary-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 8px 24px;
}

.cat-page {
  display: none;
  flex-direction: column;
  gap: 0;
}
.cat-page.is-active { display: flex; }
.cat-page > a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  color: var(--cream);
  text-decoration: none;
  /* R44 revision (2026-05-10) — sub-items now uppercase to match the
     category labels. Same eyebrow tracking + slightly smaller weight
     than the primary buttons so the two levels read as related
     without competing. */
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
  transition: background 0.14s var(--ease-precise);
}
.cat-page > a:hover { background: rgba(255,255,255,0.05); color: var(--cream); }
.cat-page > a strong { font-weight: 700; }

/* Sub-group inside a category (e.g. Finance under Administration).
   The heading reads as a small caps label rather than a clickable
   row, and the items below get a subtle left rule. */
.cat-subgroup {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid rgba(255,255,255,0.06);
}
.cat-subgroup-head {
  margin: 6px 14px 4px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255,255,255,0.45);
}
.cat-subgroup > a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 14px 11px 22px;
  color: var(--cream);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
}
.cat-subgroup > a:hover { background: rgba(255,255,255,0.05); color: var(--cream); }

/* Pills — HOD / Office gating badges, and the "Interior / Engineering"
   department-context labels next to Inventory items. */
.drawer-pill {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border-radius: 99px;
  background: rgba(225, 29, 46, 0.18);
  color: #FBA0A8;
  border: 1px solid rgba(225, 29, 46, 0.30);
}
.drawer-pill-soft {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.7);
  border-color: rgba(255,255,255,0.10);
}

/* Body lock when drawer is open so background doesn't scroll. */
body.nav-drawer-open { overflow: hidden; }

/* Mobile (≤720px) — secondary panel slides over the primary instead
   of sitting beside it. The whole drawer is a single column. */
@media (max-width: 720px) {
  .nav-drawer-primary { width: min(82vw, 300px); max-width: none; }
  .nav-drawer-secondary {
    left: 0;
    width: min(82vw, 300px);
    max-width: none;
    box-shadow: none;
    border-left: 0;
  }
}

/* Hide the legacy MobileNav drawer (#mobile-drawer / .mn-drawer) — the
   new NavDrawer handles all viewport widths. The MobileNav module in
   app.js may still call .open()/.close() on it; setting display:none
   harmlessly noop's any attempt to show it. */
#mobile-drawer { display: none !important; }
/* Hide the burger that the old MobileNav module injected if it's
   present anywhere in the header — only the new #nav-burger is real. */
.mn-burger, button.hamburger#hamburger { display: none !important; }

/* ============================================================
   R44 mobile override — neutralize the legacy @media (max-width:
   900px) rules that transformed .portal-nav into a vertical drawer.
   Now that NavDrawer handles all viewports, the top bar should stay
   a flat horizontal strip at every width. Specificity beats the
   `body #portal-nav a` rules above by adding the .portal-nav--minimal
   class to the chain.
   ============================================================ */
@media (max-width: 900px) {
  body #portal-nav.portal-nav--minimal {
    position: static !important;
    width: 100% !important;
    height: auto !important;
    transform: none !important;
    background: transparent !important;
    overflow: visible !important;
    padding: 0 !important;
    box-shadow: none !important;
    flex-direction: row !important;
    z-index: auto !important;
    display: flex !important;
    flex: 1 !important;
    border: 0 !important;
  }
  body #portal-nav.portal-nav--minimal::before,
  body #portal-nav.portal-nav--minimal::after { display: none !important; content: none !important; }

  /* Top-bar children — burger, home link, bell, user trigger. Reset
     the drawer-row styling that the legacy rules slap on `a` and
     `button.nav-trigger` inside #portal-nav. */
  body #portal-nav.portal-nav--minimal > a,
  body #portal-nav.portal-nav--minimal .nav-burger,
  body #portal-nav.portal-nav--minimal .nav-home,
  body #portal-nav.portal-nav--minimal .user-trigger,
  body #portal-nav.portal-nav--minimal .notif-trigger {
    width: auto !important;
    min-height: 0 !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 4px !important;
    color: var(--cream) !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    margin-bottom: 0 !important;
    padding: 8px 12px !important;
    text-shadow: none !important;
    display: inline-flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
  }
  /* Burger + bell are circular pills with a hairline border. */
  body #portal-nav.portal-nav--minimal .nav-burger,
  body #portal-nav.portal-nav--minimal .notif-trigger {
    border-radius: 50% !important;
    width: 36px !important;
    height: 36px !important;
    padding: 0 !important;
    border: 1px solid rgba(255,255,255,0.15) !important;
    justify-content: center !important;
  }
  body #portal-nav.portal-nav--minimal .nav-spacer {
    display: block !important;
    flex: 1 !important;
  }
  /* The user-dropdown is a positioned wrapper — keep its menu absolute. */
  body .user-dropdown { width: auto; margin-top: 0; border-top: 0; padding-top: 0; }
  /* Body-level menu-open backdrop is for the old drawer; suppress. */
  body.menu-open::before { display: none !important; }
  body.menu-open { overflow: auto !important; }

  /* R56 (2026-05-12) — kill the legacy "Notifications" ::after label
     on the bell. The old drawer rule (@900px above) injected this
     text as a row label inside the slide-out drawer; the new
     minimal nav puts the bell back in the top bar where the label
     just overflows next to the icon. */
  body #portal-nav.portal-nav--minimal .notif-trigger::after,
  body #portal-nav.portal-nav--minimal .notif-trigger::before {
    content: none !important;
    display: none !important;
  }
  /* Keep the notif badge pinned to the icon, not pushed sideways by
     the now-suppressed label. Mirrors the desktop badge position. */
  body #portal-nav.portal-nav--minimal .notif-badge {
    top: -4px !important;
    right: -4px !important;
    left: auto !important;
  }
}

/* R56 (2026-05-12) — phone-width header refinements (≤640px). The
   user pill at this width should be just the avatar — the username
   and caret eat tap area and force the header to wrap to two
   lines. Tap target is the avatar itself; the menu still opens on
   tap. Also tightens the header-inner padding so the whole row
   fits inside the safe area. */
@media (max-width: 640px) {
  .portal-header-inner {
    padding: 0 12px;
    height: 56px;
    gap: 6px;
  }
  /* Compact wordmark on phones so the brand doesn't crowd the
     burger + bell + avatar trio. */
  .header-wordmark { height: 20px; }
  /* Drop the username + chevron — avatar carries the menu. */
  body .user-trigger #nav-username,
  body .user-trigger .caret {
    display: none !important;
  }
  body .user-trigger {
    border: 0 !important;
    padding: 0 !important;
    background: transparent !important;
  }
  body .user-trigger .user-avatar {
    width: 32px;
    height: 32px;
    font-size: 12px;
    border: 1px solid rgba(255, 255, 255, 0.15);
  }
  /* Anchor the dropdown menu to the right edge of the avatar
     rather than overflowing past the screen edge. */
  body #user-dropdown .user-menu {
    right: 0;
    min-width: 240px;
    max-width: calc(100vw - 24px);
  }
  /* Tighten the bell + burger so the row sits ~44px tall. */
  body #portal-nav.portal-nav--minimal .nav-burger,
  body #portal-nav.portal-nav--minimal .notif-trigger {
    width: 34px !important;
    height: 34px !important;
  }
}

/* ============================================================
   FOOD PREFERENCES (R47 — 2026-05-10)
   Custom-rendered section on My Profile. Three controls that the
   rest of the profile sections don't use: pill-group multi-selects
   (dietary requirements, cuisines), comma-separated text inputs
   for free tags (dislikes, favourites), and repeating allergy
   rows with severity dropdowns.
   ============================================================ */

/* Privacy/intent note at the top of the section. */
.profile-food-note {
  background: rgba(40, 69, 88, 0.04);
  border-left: 3px solid var(--navy-700);
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-bottom: 14px;
  line-height: 1.5;
}
.profile-food-empty {
  font-size: 13px;
  color: var(--ink-muted);
  font-style: italic;
  padding: 6px 0 8px;
}

/* Pill-group multi-select. Each pill is a button that toggles .is-on
   on click. The save handler reads the .is-on state from the DOM. */
.pill-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 6px 0 6px;
}
.pill-toggle {
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  padding: 6px 12px;
  font: 500 12.5px/1.2 var(--sans);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 0.14s var(--ease-precise), border-color 0.14s var(--ease-precise), color 0.14s var(--ease-precise);
}
.pill-toggle:hover {
  border-color: var(--navy-700);
  color: var(--navy-900);
}
.pill-toggle.is-on {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: var(--cream);
}
.pill-toggle:focus-visible {
  outline: 2px solid var(--red-500);
  outline-offset: 2px;
}

/* Allergy rows — each is a 3-input strip with a remove button. */
.allergy-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}
.allergy-row {
  display: grid;
  grid-template-columns: 1fr 120px 1.4fr 32px;
  gap: 6px;
  align-items: center;
}
.allergy-row input,
.allergy-row select {
  height: 36px;
  padding: 6px 10px;
  border: 1px solid var(--hairline-strong);
  border-radius: 6px;
  font: 13px var(--sans);
  background: #fff;
  color: var(--ink);
  min-width: 0;
}
.allergy-row input:focus,
.allergy-row select:focus {
  border-color: var(--navy-700);
  outline: none;
}
/* Severity colour-codes the dropdown so a severe allergy reads as a
   hard flag at a glance. The data-current attribute is set at render
   time from the saved value. (When the user changes the select
   manually, the visual state only refreshes on next render — a
   small concession to keep the JS surface tight.) */
.allergy-row .allergy-severity[data-current="severe"] {
  background: rgba(225, 29, 46, 0.10);
  border-color: rgba(225, 29, 46, 0.50);
  color: var(--red-700);
  font-weight: 600;
}
.allergy-row .allergy-severity[data-current="moderate"] {
  background: rgba(220, 130, 0, 0.10);
  border-color: rgba(220, 130, 0, 0.45);
  color: #b86a00;
  font-weight: 600;
}
.allergy-remove {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  width: 32px; height: 36px;
  font-size: 18px; line-height: 1;
  color: var(--ink-muted);
  cursor: pointer;
  transition: background 0.14s var(--ease-precise), color 0.14s var(--ease-precise), border-color 0.14s var(--ease-precise);
}
.allergy-remove:hover {
  background: rgba(225, 29, 46, 0.08);
  border-color: rgba(225, 29, 46, 0.30);
  color: var(--red-700);
}

@media (max-width: 600px) {
  .allergy-row {
    grid-template-columns: 1fr 110px 32px;
    grid-template-areas:
      "name severity remove"
      "notes notes notes";
    row-gap: 4px;
  }
  .allergy-row .allergy-name      { grid-area: name; }
  .allergy-row .allergy-severity  { grid-area: severity; }
  .allergy-row .allergy-remove    { grid-area: remove; }
  .allergy-row .allergy-notes     { grid-area: notes; }
}

/* Login nudge banner — sits above the TODAY/AWAITING grid on the
   home dashboard. Soft amber tone so it reads as a prompt rather
   than a warning (R47 — 2026-05-10). */
.home-nudge {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 1080px;
  margin: 0 auto 14px;
  padding: 12px 16px;
  background: rgba(180, 83, 9, 0.07);
  border: 1px solid rgba(180, 83, 9, 0.22);
  border-radius: 10px;
  color: var(--ink);
  font-size: 13px;
}
.home-nudge.hidden { display: none; }
.home-nudge-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.home-nudge-body strong {
  font-size: 13px;
  color: var(--navy-900);
  font-weight: 700;
}
.home-nudge-body span {
  font-size: 12.5px;
  color: var(--ink-soft);
}
.home-nudge-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.home-nudge-close {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  width: 28px; height: 28px;
  border-radius: 6px;
  font-size: 18px;
  line-height: 1;
  color: var(--ink-muted);
  cursor: pointer;
  transition: background 0.14s var(--ease-precise), color 0.14s var(--ease-precise);
}
.home-nudge-close:hover { background: rgba(0,0,0,0.05); color: var(--ink); }

/* ============================================================
   R48 — Permissions admin page
   ============================================================ */
.perm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 10px;
  margin-top: 12px;
}
.perm-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.perm-card:hover {
  background: #fafbfc;
  border-color: var(--navy-700, #2A4A6F);
}
.perm-card-avatar {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--navy-700, #2A4A6F);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.perm-card-body { flex: 1; min-width: 0; }
.perm-card-name { font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.perm-card-sub  { font-size: 12px; color: var(--ink-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.perm-card-badge {
  flex: 0 0 auto;
  background: #fef3c7;
  color: #92400e;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  letter-spacing: 0.02em;
}
.perm-card-badge-default {
  background: #f3f4f6;
  color: var(--ink-muted);
  font-weight: 400;
}

/* Modal: per-section accordions */
.perm-section {
  margin: 10px 0;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 8px;
  overflow: hidden;
}
.perm-section > summary {
  padding: 10px 14px;
  background: #fafbfc;
  cursor: pointer;
  font-size: 13px;
}
.perm-section-count {
  background: var(--navy-700, #2A4A6F);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 6px;
}
.perm-section-hint {
  font-size: 12px;
  color: var(--ink-muted);
  padding: 6px 14px 0;
  margin: 0;
}
.perm-rows {
  padding: 4px 0 8px;
}

/* Each permission row — checkbox + label + description + source pill */
.perm-row {
  display: grid;
  grid-template-columns: 24px 1fr auto auto;
  gap: 10px;
  align-items: center;
  padding: 10px 14px;
  cursor: pointer;
  border-top: 1px solid var(--navy-100, #DCE7ED);
}
.perm-row:first-child { border-top: 0; }
.perm-row:hover { background: #fafbfc; }
.perm-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  cursor: pointer;
}
.perm-row-body { min-width: 0; }
.perm-row-label { font-weight: 600; font-size: 13px; }
.perm-row-desc  { font-size: 11px; color: var(--ink-muted); margin-top: 2px; line-height: 1.4; }
.perm-source {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.perm-source-override { background: #fef3c7; color: #92400e; }
.perm-source-role     { background: #f3f4f6; color: var(--ink-muted); }

/* ============================================================
   R48 (2026-05-11) — Menu Planner
   Galley module. Two-column shell (prefs summary aside + main
   menu cards). Inline contenteditable dish names. Modal for
   generating via the assistant.
   ============================================================ */
.mp-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin: 4px 0 16px;
}
.mp-kpi {
  background: var(--surface, #fff);
  border: 1px solid var(--ink-line, rgba(15,27,45,0.08));
  border-radius: 10px;
  padding: 14px 16px;
  box-shadow: 0 1px 0 rgba(15,27,45,0.02);
}
.mp-kpi-num { font-size: 26px; font-weight: 700; color: var(--ink, #38617A); line-height: 1; }
.mp-kpi-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: var(--track-eyebrow, 0.06em); color: var(--ink-muted, #6B7280); margin-top: 6px; font-weight: 600; }
.mp-kpi-warn { border-color: rgba(225,29,46,0.30); background: rgba(225,29,46,0.04); }
.mp-kpi-warn .mp-kpi-num { color: var(--red-500, #E11D2E); }

.mp-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}
/* Crew ↔ Guest audience toggle */
.mp-aud-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: rgba(15,27,45,0.05);
  border-radius: 9px;
  margin-bottom: 16px;
}
.mp-aud-btn {
  font: inherit;
  font-weight: 600;
  font-size: 13px;
  padding: 7px 16px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-muted, #6B7280);
  cursor: pointer;
}
.mp-aud-btn.active {
  background: #fff;
  color: var(--ink-strong, #0F1B2D);
  box-shadow: 0 1px 3px rgba(15,27,45,0.12);
}
.mp-cruise-wrap { margin-right: 4px; }
.mp-passage-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px;
  border-radius: 10px;
  background: rgba(45,123,156,0.12);
  color: var(--ink, #38617A);
  font-weight: 600;
}
.mp-modal-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-muted, #6B7280);
  background: rgba(45,123,156,0.07);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 0 0 12px;
}
.mp-select-wrap { display: inline-flex; align-items: center; gap: 8px; }
.mp-select-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: var(--track-eyebrow, 0.06em); color: var(--ink-muted, #6B7280); font-weight: 600; }
.mp-select {
  font: inherit;
  padding: 8px 28px 8px 10px;
  border: 1px solid var(--ink-line, rgba(15,27,45,0.12));
  border-radius: 6px;
  background: var(--surface, #fff);
  color: var(--ink, #38617A);
  max-width: 320px;
}
.mp-danger { color: var(--red-500, #E11D2E); }

.mp-grid {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 18px;
  align-items: start;
}
@media (max-width: 900px) {
  .mp-grid { grid-template-columns: 1fr; }
}

.mp-side { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 80px; }
@media (max-width: 900px) { .mp-side { position: static; } }

.mp-card {
  background: var(--surface, #fff);
  border: 1px solid var(--ink-line, rgba(15,27,45,0.08));
  border-radius: 10px;
  overflow: hidden;
}
.mp-card-head { padding: 12px 14px; border-bottom: 1px solid var(--ink-line, rgba(15,27,45,0.06)); background: rgba(15,27,45,0.02); }
.mp-card-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.mp-eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: var(--track-eyebrow, 0.08em); font-weight: 700; color: var(--ink-muted, #6B7280); }

.mp-tag-row { display: flex; flex-direction: column; gap: 6px; }
.mp-tag-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-muted, #6B7280); font-weight: 700; }
.mp-tag-wrap { display: flex; flex-wrap: wrap; gap: 4px; }
.mp-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(15,27,45,0.06);
  color: var(--ink, #38617A);
}
.mp-tag-soft { background: rgba(20,90,170,0.08); color: #145AAA; }
.mp-tag-mute { background: rgba(15,27,45,0.04); color: var(--ink-muted, #6B7280); }
.mp-tag-count { font-weight: 700; opacity: 0.7; font-size: 10px; }

.mp-allergy-group { padding: 8px 10px; border-radius: 8px; }
.mp-allergy-group + .mp-allergy-group { margin-top: 8px; }
.mp-allergy-severe   { background: rgba(225,29,46,0.06); border: 1px solid rgba(225,29,46,0.18); }
.mp-allergy-moderate { background: rgba(247,144,9,0.06);  border: 1px solid rgba(247,144,9,0.22); }
.mp-allergy-mild     { background: rgba(15,27,45,0.03);   border: 1px solid var(--ink-line, rgba(15,27,45,0.08)); }
.mp-allergy-head { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.mp-allergy-severe   .mp-allergy-head { color: var(--red-500, #E11D2E); }
.mp-allergy-moderate .mp-allergy-head { color: #C2530A; }
.mp-allergy-mild     .mp-allergy-head { color: var(--ink-muted, #6B7280); }
.mp-allergy-count { background: rgba(255,255,255,0.6); padding: 1px 6px; border-radius: 999px; font-size: 10px; }
.mp-allergy-row { display: flex; flex-wrap: wrap; gap: 6px; font-size: 12px; padding: 4px 0; align-items: baseline; }
.mp-allergy-name { font-weight: 700; color: var(--ink, #38617A); }
.mp-allergy-who { color: var(--ink-muted, #6B7280); font-size: 11px; }
.mp-allergy-notes { color: var(--ink-muted, #6B7280); font-size: 11px; font-style: italic; }

.mp-main { display: flex; flex-direction: column; gap: 14px; }

.mp-menu-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.mp-menu-title {
  font-size: 20px; font-weight: 700; margin: 0;
  padding: 4px 6px; margin-left: -6px;
  border-radius: 6px;
  color: var(--ink, #38617A);
  outline: none;
}
.mp-menu-title:focus, .mp-menu-title:hover { background: rgba(15,27,45,0.04); }
.mp-menu-meta { font-size: 12px; color: var(--ink-muted, #6B7280); margin-top: 4px; }
.mp-summary-note {
  background: rgba(20,90,170,0.05);
  border-left: 3px solid #145AAA;
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--ink, #38617A);
  line-height: 1.5;
}
.mp-status-pill {
  display: inline-flex; align-items: center;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; padding: 3px 8px; border-radius: 999px;
  background: rgba(15,27,45,0.06); color: var(--ink-muted, #6B7280);
}
.mp-status-active { background: rgba(22,163,74,0.10); color: #166534; }

.mp-days { display: flex; flex-direction: column; gap: 10px; }
.mp-day-card {
  background: var(--surface, #fff);
  border: 1px solid var(--ink-line, rgba(15,27,45,0.08));
  border-radius: 10px;
  overflow: hidden;
}
.mp-day-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  background: rgba(15,27,45,0.03);
  border-bottom: 1px solid var(--ink-line, rgba(15,27,45,0.06));
}
.mp-day-date { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink, #38617A); }
.mp-day-add {
  font: inherit; font-size: 11px; font-weight: 600;
  background: transparent; border: 1px dashed rgba(15,27,45,0.20);
  color: var(--ink-muted, #6B7280); cursor: pointer;
  padding: 4px 10px; border-radius: 6px;
}
.mp-day-add:hover { background: rgba(15,27,45,0.04); color: var(--ink, #38617A); }
.mp-day-meals { display: flex; flex-direction: column; }
.mp-meal-row {
  display: grid;
  grid-template-columns: 96px 1fr 32px;
  gap: 10px;
  padding: 12px 14px;
  border-top: 1px solid var(--ink-line, rgba(15,27,45,0.04));
}
.mp-meal-row:first-child { border-top: 0; }
.mp-meal-type {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-muted, #6B7280);
  padding-top: 3px;
}
.mp-meal-body { min-width: 0; }
.mp-meal-dish, .mp-meal-desc {
  border-radius: 6px;
  padding: 3px 6px;
  margin: -3px -6px 2px;
  outline: none;
}
.mp-meal-dish { font-weight: 600; color: var(--ink, #38617A); font-size: 14px; }
.mp-meal-dish:focus, .mp-meal-dish:hover { background: rgba(15,27,45,0.04); }
.mp-meal-desc { font-size: 13px; color: var(--ink-muted, #6B7280); line-height: 1.45; }
.mp-meal-desc:focus, .mp-meal-desc:hover { background: rgba(15,27,45,0.03); color: var(--ink, #38617A); }
.mp-meal-desc-empty:empty:before { content: attr(data-placeholder); color: rgba(15,27,45,0.30); }
.mp-meal-ings { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.mp-ing-chip {
  font-size: 11px; font-weight: 500;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(15,27,45,0.05); color: var(--ink, #38617A);
}
.mp-meal-flags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.mp-flag {
  font-size: 10px; font-weight: 600;
  padding: 2px 6px; border-radius: 4px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.mp-flag-good { background: rgba(22,163,74,0.10); color: #166534; }
.mp-flag-warn { background: rgba(225,29,46,0.10); color: var(--red-500, #E11D2E); }
.mp-meal-del {
  font: inherit; font-size: 16px;
  background: transparent; border: 0; cursor: pointer;
  color: rgba(15,27,45,0.30);
  padding: 2px; border-radius: 4px;
  align-self: start;
}
.mp-meal-del:hover { color: var(--red-500, #E11D2E); background: rgba(225,29,46,0.06); }

/* Buffet grouping — meal-type sections within a day card (R127). */
.mp-meal-group {
  border-top: 1px solid var(--ink-line, rgba(15,27,45,0.08));
}
.mp-meal-group:first-of-type { border-top: 0; }
.mp-meal-group-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 14px;
  background: rgba(15,27,45,0.025);
  border-bottom: 1px solid var(--ink-line, rgba(15,27,45,0.06));
}
.mp-meal-group-lbl {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink, #38617A);
}
.mp-day-add-sm { font-size: 10px; padding: 3px 8px; }
.mp-meal-group-lunch  .mp-meal-group-head { background: rgba(34,107,191,0.05); }
.mp-meal-group-dinner .mp-meal-group-head { background: rgba(168,87,28,0.05); }

/* Modal: full-width inline checkbox + hint */
.mp-check-block { display: flex; align-items: center; gap: 8px; padding: 6px 0; }
.mp-hint { font-size: 12px; color: var(--ink-muted, #6B7280); font-weight: 400; }

.mp-shopping {
  background: var(--surface, #fff);
  border: 1px solid var(--ink-line, rgba(15,27,45,0.08));
  border-radius: 10px;
  padding: 0;
}
.mp-shopping > summary {
  padding: 12px 14px;
  cursor: pointer;
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink, #38617A);
  list-style: none;
}
.mp-shopping > summary::-webkit-details-marker { display: none; }
.mp-shopping[open] > summary { border-bottom: 1px solid var(--ink-line, rgba(15,27,45,0.06)); }
.mp-shopping-body { padding: 12px 14px; }
.mp-shopping-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 6px;
}
.mp-shopping-item { font-size: 12px; color: var(--ink, #38617A); padding: 4px 8px; background: rgba(15,27,45,0.03); border-radius: 4px; }
.mp-shopping-count { font-weight: 700; color: var(--ink-muted, #6B7280); margin-right: 4px; }
.mp-shopping-qty { font-weight: 700; color: var(--ink-strong, #0F1B2D); margin-right: 5px; white-space: nowrap; }
.mp-qty-sub { font-weight: 500; color: var(--ink-muted, #6B7280); font-size: 11px; }

/* Crew-on-duty provisioning basis — explains why the quantities scaled */
.mp-shopping-basis {
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink, #38617A);
  background: rgba(45,123,156,0.08);
  border: 1px solid rgba(45,123,156,0.18);
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 10px;
}
.mp-shopping-basis strong { color: var(--ink-strong, #0F1B2D); }
.mp-shopping-basis-warn {
  background: rgba(214,158,46,0.10);
  border-color: rgba(214,158,46,0.30);
}
.mp-basis-sub { display: block; color: var(--ink-muted, #6B7280); font-size: 11px; margin-top: 2px; }
.mp-basis-spread { color: var(--ink-muted, #6B7280); }

/* ----- Generate modal ----- */
.mp-modal-backdrop {
  position: fixed; inset: 0; z-index: 2200;
  background: rgba(10,22,40,0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: mp-fade 0.16s var(--ease-precise, ease);
}
@keyframes mp-fade { from { opacity: 0; } to { opacity: 1; } }
.mp-modal {
  background: var(--surface, #fff);
  border-radius: 12px;
  width: min(560px, 100%);
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  overflow: auto;
  box-shadow: 0 20px 50px -10px rgba(0,0,0,0.4);
  animation: mp-rise 0.20s var(--ease-precise, ease);
}
@keyframes mp-rise { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.mp-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--ink-line, rgba(15,27,45,0.06));
}
.mp-modal-head h3 { margin: 0; font-size: 16px; }
.mp-modal-close {
  font: inherit; font-size: 22px; line-height: 1;
  background: transparent; border: 0; cursor: pointer;
  color: var(--ink-muted, #6B7280);
  padding: 0 4px;
}
.mp-modal-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.mp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.mp-field { display: flex; flex-direction: column; gap: 4px; }
.mp-field > span, .mp-fieldset > legend { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted, #6B7280); }
.mp-field input[type="text"], .mp-field input[type="number"], .mp-field input[type="date"], .mp-field textarea, .mp-field select {
  font: inherit;
  padding: 9px 10px;
  border: 1px solid var(--ink-line, rgba(15,27,45,0.16));
  border-radius: 6px;
  background: var(--surface, #fff);
  color: var(--ink, #38617A);
}
.mp-field input:focus, .mp-field textarea:focus { outline: 2px solid rgba(20,90,170,0.30); outline-offset: 1px; border-color: #145AAA; }
.mp-fieldset {
  border: 1px solid var(--ink-line, rgba(15,27,45,0.12));
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}
.mp-fieldset legend { padding: 0 4px; }
.mp-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink, #38617A); cursor: pointer; }
.mp-modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 6px; }
.mp-modal-status { font-size: 12px; min-height: 16px; }

/* ============================================================
   R52 (2026-05-11) — Job Board (Trello-style kanban)
   Per-department boards; horizontal-scroll list view; native HTML5
   drag-and-drop on cards and lists. Cross-dept boards render
   read-only (no draggable, no edit chrome).
   Uses R43 tokens: --hairline, --shadow-card, --track-eyebrow.
   ============================================================ */
.jb-picker { display: flex; flex-direction: column; gap: 28px; }
.jb-picker-group { display: flex; flex-direction: column; gap: 12px; }
.jb-picker-eyebrow {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 11px; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.08em);
  color: var(--ink-muted); font-weight: 600;
}
.jb-picker-readonly {
  display: inline-block; margin-left: 6px; padding: 2px 6px;
  border-radius: 999px; background: var(--cream-dark);
  color: var(--ink-muted); font-size: 10px; letter-spacing: 0.04em;
}
.jb-picker-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.jb-picker-empty {
  padding: 18px 20px;
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius-lg);
  color: var(--ink-muted); font-size: 13px;
  background: rgba(255,255,255,0.5);
}
.jb-picker-card {
  text-align: left; cursor: pointer; padding: 18px 18px 16px;
  border: 0; border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  background: var(--cream);
  color: var(--ink);
  display: flex; flex-direction: column; gap: 6px;
  min-height: 112px;
  transition: transform 0.12s var(--ease-precise), box-shadow 0.12s var(--ease-precise);
}
.jb-picker-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-card-hover); }
.jb-picker-card-eyebrow {
  font-size: 10px; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.08em);
  color: rgba(255,255,255,0.85); font-weight: 600;
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
}
.jb-picker-card-title {
  font-size: 17px; font-weight: 700; line-height: 1.25;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,0.35);
}
.jb-picker-card-meta {
  margin-top: auto; font-size: 11px; color: rgba(255,255,255,0.85);
  text-shadow: 0 1px 2px rgba(0,0,0,0.25);
}

/* Board backgrounds — match the Trello reference (sand, space, sunset). */
.jb-bg-sand    { background: linear-gradient(135deg, #B7C3CB 0%, #93A2AC 100%); }
.jb-bg-space   { background: radial-gradient(circle at 30% 30%, #1B3A6B 0%, #060814 100%); }
.jb-bg-sunset  { background: linear-gradient(135deg, #8A5CFF 0%, #FF6FA1 100%); }
.jb-bg-gradient{ background: linear-gradient(135deg, var(--navy-800) 0%, var(--navy-600) 100%); }

/* ---- Board view ---- */
.jb-board {
  margin: -16px -16px 0;          /* bleed into the page padding */
  padding: 16px;
  border-radius: var(--radius-lg);
  min-height: calc(100vh - 220px);
  min-height: calc(100dvh - 220px);
  display: flex; flex-direction: column; gap: 14px;
}
.jb-board-bar {
  display: flex; align-items: center; gap: 14px;
  color: #fff;
}
.jb-back {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.15);
  border: 0; color: #fff; padding: 8px 12px;
  border-radius: var(--radius); cursor: pointer;
  font-size: 13px; font-weight: 600;
}
.jb-back:hover { background: rgba(255,255,255,0.25); }
.jb-back .ic { width: 16px; height: 16px; }
.jb-board-title { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.jb-board-eyebrow {
  font-size: 10px; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.08em);
  color: rgba(255,255,255,0.85); font-weight: 600;
}
.jb-board-title h1 {
  margin: 0; font-size: 22px; font-weight: 700;
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.25);
  outline: none;
}
.jb-board-title h1[contenteditable="true"]:hover {
  background: rgba(255,255,255,0.1); border-radius: 4px; padding: 0 4px; margin: 0 -4px;
}
.jb-board-tools .btn { color: #fff; border-color: rgba(255,255,255,0.4); background: rgba(255,255,255,0.1); }
.jb-board-tools .btn:hover { background: rgba(255,255,255,0.2); }

/* ---- Lists row (horizontal scroll) ---- */
.jb-lists {
  display: flex; gap: 12px; align-items: flex-start;
  overflow-x: auto; padding-bottom: 12px;
  scrollbar-width: thin;
}
.jb-lists::-webkit-scrollbar { height: 10px; }
.jb-lists::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.3); border-radius: 6px; }
.jb-list {
  flex: 0 0 280px;
  background: rgba(248, 246, 241, 0.96);
  border-radius: 10px;
  padding: 10px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
  display: flex; flex-direction: column; gap: 8px;
  max-height: calc(100vh - 240px);
  max-height: calc(100dvh - 240px);
}
.jb-list.jb-drop-over { outline: 2px dashed var(--navy-700); outline-offset: 2px; }
.jb-list.jb-dragging  { opacity: 0.4; }
.jb-list-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 6px 2px;
}
.jb-list-head h2 {
  margin: 0; font-size: 13px; font-weight: 700;
  color: var(--ink); letter-spacing: var(--track-eyebrow, 0.04em);
  text-transform: uppercase; outline: none;
}
.jb-list-head h2[contenteditable="true"]:hover {
  background: var(--cream-dark); border-radius: 4px; padding: 0 4px; margin: 0 -4px;
}
.jb-list-menu {
  border: 0; background: transparent; cursor: pointer;
  color: var(--ink-muted); font-size: 18px; line-height: 1; padding: 2px 6px;
  border-radius: 4px;
}
.jb-list-menu:hover { background: var(--cream-dark); color: var(--danger); }
.jb-list--add {
  flex: 0 0 280px;
  background: rgba(255,255,255,0.18);
  border: 1px dashed rgba(255,255,255,0.4);
  border-radius: 10px;
  padding: 14px;
  color: rgba(255,255,255,0.85);
  font-weight: 600; font-size: 13px;
  display: flex; align-items: center; gap: 8px;
  cursor: pointer;
  min-height: 56px;
}
.jb-list--add:hover { background: rgba(255,255,255,0.28); color: #fff; }
.jb-list--add .ic { width: 16px; height: 16px; }

/* ---- Cards stack ---- */
.jb-cards {
  display: flex; flex-direction: column; gap: 6px;
  overflow-y: auto; padding: 4px 2px;
  min-height: 6px;
  flex: 1 1 auto;
}
.jb-cards.jb-drop-over { background: rgba(76, 115, 133, 0.06); border-radius: 6px; }
.jb-card {
  background: #fff;
  border-radius: 6px;
  padding: 10px 12px;
  box-shadow: var(--shadow-card);
  cursor: pointer;
  display: flex; flex-direction: column; gap: 6px;
  transition: box-shadow 0.12s var(--ease-precise);
}
.jb-card:hover { box-shadow: var(--shadow-card-hover); }
.jb-card.jb-dragging { opacity: 0.35; }
.jb-card--done { background: var(--cream-dark); }
.jb-card--done .jb-card-title { text-decoration: line-through; color: var(--ink-muted); }
.jb-card-title {
  font-size: 14px; font-weight: 500; color: var(--ink);
  line-height: 1.35;
}
.jb-card-meta {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 2px;
}
.jb-pill {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--ink-soft);
  background: var(--cream); border-radius: 999px;
  padding: 2px 8px;
  border: 1px solid var(--hairline);
}
.jb-pill .ic { width: 11px; height: 11px; }
.jb-pill--recur { color: var(--navy-700); border-color: rgba(76, 115, 133, 0.18); background: rgba(76, 115, 133, 0.05); }
.jb-pill--done  { color: var(--success); border-color: rgba(22, 101, 52, 0.25); background: rgba(22, 101, 52, 0.06); }
.jb-claim {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--navy-700); color: #fff;
  font-size: 10px; font-weight: 700;
  margin-left: auto;
}
.jb-claim--lg { width: 36px; height: 36px; font-size: 14px; }
.jb-card-add {
  border: 0; background: transparent;
  color: var(--ink-muted); font-size: 13px; font-weight: 500;
  padding: 6px 8px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: 4px;
  text-align: left;
}
.jb-card-add:hover { background: var(--cream-dark); color: var(--navy-800); }
.jb-card-add .ic { width: 14px; height: 14px; }

/* ---- Card editor modal ---- */
.jb-modal-back {
  position: fixed; inset: 0;
  background: rgba(40, 69, 88, 0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.jb-modal {
  background: #fff; border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
  width: 100%; max-width: 540px;
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px); overflow-y: auto;
  display: flex; flex-direction: column;
}
.jb-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px 8px;
  border-bottom: 1px solid var(--hairline);
}
.jb-modal-eyebrow {
  font-size: 11px; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.08em);
  color: var(--ink-muted); font-weight: 600;
}
.jb-modal-x {
  border: 0; background: transparent; cursor: pointer;
  color: var(--ink-muted); padding: 4px; border-radius: 4px;
}
.jb-modal-x:hover { background: var(--cream-dark); color: var(--ink); }
.jb-modal-x .ic { width: 18px; height: 18px; }
.jb-modal-body {
  padding: 18px;
  display: flex; flex-direction: column; gap: 14px;
}
.jb-field { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.jb-field > span {
  font-size: 11px; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.08em);
  color: var(--ink-muted); font-weight: 600;
}
.jb-field input, .jb-field textarea, .jb-field select {
  font: var(--type-body);
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
}
.jb-field input:focus, .jb-field textarea:focus, .jb-field select:focus {
  outline: 2px solid var(--navy-700); outline-offset: -1px; border-color: var(--navy-700);
}
.jb-row { display: flex; gap: 10px; flex-wrap: wrap; }
.jb-row .jb-field { min-width: 130px; }
.jb-claim-row { padding-top: 4px; }
.jb-claim-banner {
  display: flex; align-items: center; gap: 12px;
  background: var(--cream); border: 1px solid var(--hairline);
  border-radius: var(--radius); padding: 10px 12px;
}
.jb-claim-banner strong { display: block; font-size: 13px; color: var(--ink); }
.jb-claim-banner .muted { font-size: 11px; color: var(--ink-muted); }
.jb-claim-banner .btn { margin-left: auto; }
.jb-modal-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 18px; border-top: 1px solid var(--hairline);
}
.jb-spacer { flex: 1; }
body.jb-modal-open { overflow: hidden; }

/* Mobile/iPad polish: tighter list width, taller drop targets. */
@media (max-width: 720px) {
  .jb-list, .jb-list--add { flex: 0 0 84vw; }
  .jb-board { min-height: calc(100vh - 180px); min-height: calc(100dvh - 180px); }
}

/* ============================================================
   R56 (2026-05-12) — Mobile rescue: cross-module fixes for
   patterns the page-specific rules above don't cover. Goal: at
   ≤640px no horizontal scroll, all toolbars wrap, all multi-
   column grids that aren't calendars collapse, all tap targets
   ≥40px tall. Applied with low specificity so page-specific
   rules win where they exist.
   ============================================================ */
@media (max-width: 640px) {
  /* Page chrome — tighten paddings, allow page headers to stack. */
  .portal-main { padding: 20px 14px 80px; }
  .page-header { display: block; }
  .page-header h1 { font-size: 24px; line-height: 1.2; word-break: break-word; }
  .page-header .page-sub,
  .page-header p { font-size: 13.5px; line-height: 1.45; }
  .page-header .btn,
  .page-header > button { margin-top: 12px; width: 100%; justify-content: center; }

  /* Drill matrix row was a 5-column grid — at phone width every
     column ends up ~50px wide and the times wrap into the labels.
     Collapse to a stacked card. */
  .drill-matrix-row {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--navy-100, #DCE7ED);
  }
  .drill-matrix-row > * { width: 100%; }
  .drill-matrix-row .drill-type-pill { justify-self: start; }

  /* Kiosk-style 3-up watch tiles — fine on iPad, cramped on phone. */
  .kiosk-watch-row { grid-template-columns: 1fr; }

  /* HUD row in the vessel tracker — 6 readouts won't fit at ~370px. */
  .vessel-hud-readouts { grid-template-columns: repeat(2, 1fr); gap: 6px; }

  /* Generic toolbar wraps: make every flex toolbar wrap and let
     buttons grow to full width when they wrap to their own row. */
  .module-toolbar,
  .cars-toolbar,
  .cards-toolbar,
  .budget-toolbar {
    flex-wrap: wrap;
    gap: 8px;
  }
  /* Buttons in a wrapping toolbar shouldn't be tiny; give them
     min-height for thumb reach. */
  .module-toolbar .btn,
  .cars-toolbar .btn,
  .cards-toolbar .btn,
  .budget-toolbar .btn {
    min-height: 40px;
  }

  /* Filter chip rows — keep them wrapping (not horizontally
     scrolling) so the user can see every status count at a
     glance instead of swiping. */
  .cert-filters {
    gap: 6px;
  }
  .cert-chip {
    padding: 6px 10px;
    font-size: 12px;
  }

  /* Pages that lay out as two columns at desktop should single-
     column on phones. Captures profile, settings, audit, etc. */
  .profile-shell,
  .settings-grid,
  .audit-grid,
  .two-col {
    grid-template-columns: 1fr !important;
  }

  /* Forms — make field rows stack instead of squeezing two-up. */
  .form-row {
    grid-template-columns: 1fr !important;
    gap: 12px;
  }
  /* Inputs/selects/textareas — comfortable hit-targets, no zoom
     on focus (iOS auto-zooms anything <16px). */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="tel"],
  input[type="number"],
  input[type="date"],
  input[type="month"],
  input[type="time"],
  input[type="url"],
  select,
  textarea {
    font-size: 16px;
  }

  /* Modal forms: tighten the bottom-sheet padding so more content
     is visible without scrolling. */
  .modal .modal-card form { gap: 12px; }

  /* Page-actions on the right of headers — let them wrap below. */
  .page-actions,
  .page-toolbar {
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
  }
  .page-actions .btn,
  .page-toolbar .btn {
    flex: 1 1 auto;
    min-height: 40px;
  }

  /* Empty state cards: tighten padding. */
  .empty-state { padding: 24px 16px; }

  /* Generic "stat" / KPI card grids — collapse to 2 cols, then 1. */
  .stats-grid,
  .kpi-grid,
  .summary-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}

/* Extra-narrow phones (≤380px — iPhone SE/12 mini). */
@media (max-width: 380px) {
  .stats-grid,
  .kpi-grid,
  .summary-grid,
  .module-summary {
    grid-template-columns: 1fr !important;
  }
  .portal-main { padding: 16px 10px 80px; }
  .header-wordmark { height: 18px; }
}
/* ============================================================
   CREW & PASSENGER LIST  (Wheelhouse, R64, 2026-05-14)
   IMO FAL-compliant lists. Layout-light: tabs + table + status
   pills. The PDF rendering happens in JS (jsPDF) so this CSS is
   only for the on-screen builder.
   ============================================================ */
.modal-card-wide  { max-width: 760px; }
.modal-card-xwide { max-width: 1080px; }
.modal-section-h {
  margin: 18px 28px 6px;
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--navy-700, #5C8AA4);
  font-weight: 700;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  padding-bottom: 4px;
}
.modal-section-h:first-of-type { margin-top: 8px; }

.cpl-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  margin: 8px 0 16px;
  flex-wrap: wrap;
}
.cpl-tab {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  padding: 10px 16px;
  cursor: pointer;
  font-size: 13px;
  color: var(--navy-800, #2A4366);
  border-radius: 8px 8px 0 0;
  font-weight: 600;
}
.cpl-tab:hover { background: rgba(15,27,45,0.04); }
.cpl-tab.active {
  background: #fff;
  border-color: var(--navy-100, #DCE7ED);
  color: var(--navy-900, #38617A);
}

.cpl-pane { padding: 4px 0 24px; }
.cpl-pane-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.cpl-empty {
  padding: 28px;
  text-align: center;
  background: #fff;
  border: 1px dashed var(--navy-100, #DCE7ED);
  border-radius: 12px;
  font-size: 13px;
  color: var(--ink-muted, #64748b);
}
.cpl-search {
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 13px;
  min-width: 200px;
}

.cpl-table-wrap {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  overflow-x: auto;
}
.cpl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.cpl-table thead th {
  background: #F4F7FA;
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--navy-700, #5C8AA4);
  padding: 10px 12px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  font-weight: 700;
}
.cpl-table tbody td {
  padding: 9px 12px;
  border-bottom: 1px solid #EEF2F6;
  vertical-align: top;
}
.cpl-table tbody tr {
  cursor: pointer;
  transition: background 0.12s;
}
.cpl-table tbody tr:hover { background: rgba(15,27,45,0.025); }
.cpl-table .cpl-bad  { color: #991B1B; font-weight: 600; }
.cpl-table .cpl-warn { color: #92400E; font-weight: 600; }

.cpl-pill {
  display: inline-block;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
  background: #E5EBF1;
  color: var(--navy-800, #2A4366);
  vertical-align: middle;
}
.cpl-pill-ok   { background: #DCFCE7; color: #166534; }
.cpl-pill-warn { background: #FEF3C7; color: #92400E; }
.cpl-pill-bad  { background: #FEE2E2; color: #991B1B; }
.cpl-pill-vip  { background: #FCE7F3; color: #831843; }

.cpl-locked-note { background: #FFF7E6; border: 1px solid #F1D08F; }

/* Port-call detail modal */
.port-call-detail-body { padding: 16px 24px 22px; }
.pcd-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  margin: 4px 0 14px;
}
.pcd-tab {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  padding: 8px 14px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--navy-800, #2A4366);
  border-radius: 6px 6px 0 0;
  font-weight: 600;
}
.pcd-tab.active {
  background: #fff;
  border-color: var(--navy-100, #DCE7ED);
  color: var(--navy-900, #38617A);
}
.pcd-banner {
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 12px;
  background: #F4F7FA;
  border: 1px solid var(--navy-100, #DCE7ED);
  color: var(--navy-800, #2A4366);
}
.pcd-banner-ok   { background: #DCFCE7; border-color: #BBF7D0; color: #166534; }
.pcd-banner-warn { background: #FEF3C7; border-color: #FDE68A; color: #92400E; }

.pcd-mini-input {
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 4px;
  padding: 3px 6px;
  font-size: 12px;
  width: 100%;
  min-width: 80px;
  background: #fff;
}
.pcd-mini-input:focus { border-color: var(--navy-700, #5C8AA4); outline: none; }

.port-call-actions {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.cert-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

@media (max-width: 720px) {
  .cpl-tabs { gap: 2px; }
  .cpl-tab { padding: 8px 10px; font-size: 12px; }
  .modal-card-wide, .modal-card-xwide { max-width: calc(100vw - 32px); }
}

/* ============================================================
   CREW STATUS (R65, 2026-05-14)
   Status pills in the Crew Directory + the holiday-balance widget
   in My Profile + payroll tab toolbar.
   ============================================================ */
.crew-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  vertical-align: middle;
  white-space: nowrap;
  user-select: none;
  transition: filter 0.12s, transform 0.12s;
}
.crew-status-pill-editable { cursor: pointer; }
.crew-status-pill-editable:hover { filter: brightness(1.08); transform: translateY(-1px); }
.crew-status-pill-chev { font-size: 9px; opacity: 0.85; }

.crew-list-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
/* R131 — keep "+ Add Crew Member" + Bulk-status toolbar clustered on the right. */
.crew-list-head-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.crew-bulk-bar {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: #FFF8E6;
  border: 1px solid #F5D38C;
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 13px;
  color: #6B4A07;
}
.crew-bulk-check {
  width: 18px;
  height: 18px;
  accent-color: var(--navy-700, #5C8AA4);
  margin-right: 10px;
  flex-shrink: 0;
}

/* Holiday balance widget inside MyProfile Contract section */
.ps-balance {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 10px 0 6px;
}
.ps-balance-h {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--navy-700, #5C8AA4);
  margin-bottom: 8px;
}
.ps-balance-sub {
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-muted, #64748b);
  margin-left: 6px;
}
.ps-balance-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.ps-balance-grid > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px;
  background: #F4F7FA;
  border-radius: 8px;
}
.ps-balance-num {
  font-size: 22px;
  font-weight: 800;
  color: var(--navy-900, #38617A);
}
.ps-balance-num.ps-balance-neg { color: #991B1B; }
.ps-balance-lbl {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted, #64748b);
  margin-top: 2px;
}
.ps-balance-warn {
  margin-top: 10px;
  font-size: 12px;
  color: #92400E;
  background: #FEF3C7;
  padding: 6px 10px;
  border-radius: 6px;
}

/* Payroll export toolbar */
.payroll-toolbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.payroll-toolbar-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

@media (max-width: 720px) {
  .ps-balance-grid { grid-template-columns: 1fr 1fr; }
  .crew-list-head { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   PASSAGE PLAN  (R70, 2026-05-15)
   Modal layout for the Tier-2 passage planner.
   ============================================================ */
.pp-body {
  padding: 14px 22px 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pp-safety-banner {
  background: #FEF3C7;
  border: 1px solid #FDE68A;
  color: #78350F;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.4;
}
.pp-controls {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.pp-controls .field { min-width: 200px; }
.pp-controls input, .pp-controls select {
  background: #fff;
}

.pp-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  background: #F4F7FA;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  padding: 12px 14px;
}
.pp-summary-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pp-summary-tile-label {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy-700, #5C8AA4);
  font-weight: 700;
}
.pp-summary-tile-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--navy-900, #38617A);
}
.pp-summary-tile-sub {
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}

.pp-results {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 14px;
}
.pp-map-wrap { min-width: 0; }
.pp-table-wrap {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pp-table-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.pp-table {
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 10px;
  overflow: auto;
  max-height: 460px;
  background: #fff;
}
.pp-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.pp-table thead th {
  background: #F4F7FA;
  text-align: left;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--navy-700, #5C8AA4);
  padding: 8px 10px;
  border-bottom: 1px solid var(--navy-100, #DCE7ED);
  position: sticky;
  top: 0;
  z-index: 1;
}
.pp-table tbody td {
  padding: 7px 10px;
  border-bottom: 1px solid #EEF2F6;
  vertical-align: top;
}
.pp-table tbody tr:hover { background: rgba(15,27,45,0.025); }
.pp-table .pp-wp-name { font-weight: 600; }
.pp-table .pp-wp-coords { font-size: 11px; color: var(--ink-muted, #64748b); font-variant-numeric: tabular-nums; }
.pp-table .pp-leg-num { font-variant-numeric: tabular-nums; color: var(--ink-muted, #64748b); }
.pp-table .pp-row-port { background: #F0FDF4; }
.pp-table .pp-row-custom { background: #FFF7E6; }
.pp-table .pp-remove {
  background: none; border: 0;
  color: var(--red-500, #DC2626);
  font-size: 14px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
}
.pp-table .pp-remove:hover { background: rgba(220,38,38,0.08); }

.pp-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-top: 8px;
  border-top: 1px solid var(--navy-100, #DCE7ED);
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .pp-results { grid-template-columns: 1fr; }
  .pp-map-wrap > div { height: 320px !important; }
  .pp-table { max-height: 320px; }
}

/* Passage Planning page hero cards (R70 Wheelhouse module) */
.pp-page-hero { margin-top: 8px; }
.pp-page-hero-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 16px;
}
.pp-page-card {
  background: #fff;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 12px;
  padding: 22px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pp-page-card-glyph {
  font-size: 28px;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: #F4F7FA;
  border-radius: 12px;
  margin-bottom: 4px;
}
.pp-page-card h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--navy-900, #38617A);
}
.pp-page-card p {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted, #64748b);
  line-height: 1.45;
  flex: 1;
}
.pp-page-card .btn { align-self: flex-start; margin-top: 6px; }

/* Per-leg speed / fuel overrides on Charter leg line (R71, 2026-05-15) */
.charter-leg-overrides {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 10px;
}
.charter-leg-overrides label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--ink-muted, #64748b);
}
.charter-leg-overrides input {
  width: 56px;
  font-size: 12px;
  padding: 2px 6px;
  border: 1px solid var(--navy-100, #DCE7ED);
  border-radius: 4px;
  background: #fff;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.charter-leg-overrides input:focus {
  border-color: var(--navy-700, #5C8AA4);
  outline: none;
}
.charter-leg-overrides input::placeholder { color: #b8c3d0; }
.charter-leg-overrides small { color: var(--ink-muted, #64748b); }
.charter-leg-override-dot {
  display: inline-block;
  margin-left: 6px;
  color: var(--navy-700, #5C8AA4);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
}

/* ============================================================
   R85 — Crew Cabin Assignments
   ============================================================ */
.module-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin: 12px 0 8px;
}
.summary-tile {
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 14px 16px;
}
.summary-tile.is-warning {
  border-color: #fbbf24;
  background: #fffbeb;
}
.summary-num {
  font-size: 28px;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1;
}
.summary-label {
  font-size: 11px;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 4px;
}
.cabins-header-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 8px;
}
.cabins-date-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--navy-700);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.cabins-date-label input[type="date"] {
  padding: 6px 8px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 14px;
}
.cabins-section-h2 {
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
  margin: 28px 0 8px;
}
.cabins-view-toggle {
  display: inline-flex;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  overflow: hidden;
}
.cabins-view-toggle .seg-btn {
  background: #fff;
  border: 0;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  color: var(--navy-700);
}
.cabins-view-toggle .seg-btn.active {
  background: var(--navy-800);
  color: #fff;
}

/* Floor plan — actual GA crew-deck rendered to canvas, with cabin
   hotspots and crew-name pills overlaid via percentage coordinates. */
.cabins-floorplan {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 12px;
  margin-top: 12px;
  overflow: hidden;
}
.cabins-ga-stage {
  position: relative;
  width: 100%;
  min-height: 160px;
}
.cabins-ga-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
  user-select: none;
  -webkit-user-drag: none;
}
.cabins-hotspot-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.cabin-hotspot {
  position: absolute;
  pointer-events: auto;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: 6px;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s, background 0.15s;
}
.cabin-hotspot:hover {
  border-color: var(--navy-700);
  background: rgba(76, 115, 133, 0.06);
}
.cabin-hotspot.is-full     { border-color: rgba(16, 185, 129, 0.6); }
.cabin-hotspot.is-partial  { border-color: rgba(245, 158, 11, 0.6); }
.cabin-hotspot.is-hospital.is-full,
.cabin-hotspot.is-hospital.is-partial { border-color: rgba(239, 68, 68, 0.7); }
.cabin-hotspot-pills {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  max-width: 95%;
}
.cabin-pill {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
  cursor: pointer;
}
.cabin-pill.gender-f { background: #fce7f3; color: #831843; }
.cabin-pill.gender-m { background: #dbeafe; color: #1e3a8a; }
.cabin-pill.gender-x { background: #e2e8f0; color: #1e293b; }
.cabin-pill:hover { filter: brightness(0.95); }
@media (max-width: 760px) {
  .cabin-pill { font-size: 9px; padding: 2px 6px; }
}
.cabins-hull {
  position: relative;
  padding: 36px 120px 36px 56px;  /* more right padding so bow taper has room */
}
/* R129 — phone breakpoint. The 120px right + 56px left padding (176px
   combined) crushed the cabin diagram on any phone narrower than ~480px
   and forced horizontal page scroll. Halve the asymmetric padding and
   trust the SVG hull bg to scale. */
@media (max-width: 640px) {
  .cabins-hull { padding: 20px 40px 20px 20px; }
}
.cabins-hull-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.cabins-orient {
  position: absolute;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: #1e293b;
  text-transform: uppercase;
  z-index: 1;
  pointer-events: none;
  opacity: 0.7;
}
.cabins-orient-stern { top: 50%; left: 14px;  transform: translateY(-50%) rotate(-90deg); transform-origin: center; }
.cabins-orient-bow   { top: 50%; right: 14px; transform: translateY(-50%) rotate(90deg);  transform-origin: center; }
.cabins-orient-port  { top: 12px;    left: 50%; transform: translateX(-50%); }
.cabins-orient-stbd  { bottom: 12px; left: 50%; transform: translateX(-50%); }
/* Deck layout: stern block (galley/mess) | stairwell (UP/DN) | cabin grid (6 cols) */
.cabins-deck-layout {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 110px 36px 1fr;
  gap: 10px;
}
.cabins-stern-block,
.cabins-stairwell,
.cabins-deck {
  display: grid;
  grid-template-rows: 1fr auto 1fr;
  gap: 10px;
  min-height: 220px;
}
.cabin-service {
  background: rgba(255, 255, 255, 0.78);
  border: 1px dashed #94a3b8;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 10px 8px;
  color: #475569;
}
.cabin-service-name {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.1;
}
.cabin-service-sub {
  font-size: 10px;
  color: #94a3b8;
  margin-top: 4px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.cabins-corridor-aux {
  background: transparent;
  min-height: 30px;
}
.cabin-stairs {
  background: #fef9c3;
  border: 1px solid #ca8a04;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: #92400e;
  letter-spacing: 0.12em;
  line-height: 1.2;
  padding: 4px;
}
.stairs-arrow {
  display: block;
  font-size: 14px;
  margin-bottom: 2px;
}
.cabins-deck {
  /* keep its own flex behaviour but match the 1fr/auto/1fr structure */
}
.cabins-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
}
/* Bow-side cabins get exaggerated rounded corners to suggest the hull curve. */
.cabins-row:first-child .cabin-cell:last-child { border-top-right-radius: 28px; }
.cabins-row:last-child  .cabin-cell:last-child { border-bottom-right-radius: 28px; }
.cabins-row:first-child .cabin-cell:first-child { border-top-left-radius: 10px; }
.cabins-row:last-child  .cabin-cell:first-child { border-bottom-left-radius: 10px; }
.cabins-corridor {
  background: repeating-linear-gradient(90deg, transparent 0 14px, rgba(148,163,184,0.18) 14px 15px);
  border: 1px dashed transparent;
  color: #475569;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  text-align: center;
  padding: 6px 0;
  border-radius: 4px;
}
.cabin-cell {
  background: #fff;
  border: 2px solid #cbd5e1;
  border-radius: 6px;
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  min-height: 96px;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
/* Bow-side cabins lean slightly toward centerline to suggest hull curve.
   Top row leans down (negative angle), bottom row leans up. */
.cabins-row:first-child .cabin-cell.is-bow-2 { transform: rotate(-1deg); transform-origin: left center; }
.cabins-row:first-child .cabin-cell.is-bow   { transform: rotate(-2.5deg); transform-origin: left center; }
.cabins-row:last-child  .cabin-cell.is-bow-2 { transform: rotate(1deg); transform-origin: left center; }
.cabins-row:last-child  .cabin-cell.is-bow   { transform: rotate(2.5deg); transform-origin: left center; }
.cabin-cell:hover { border-color: var(--navy-700); }
.cabin-cell.is-empty   { background: #fff;     border-color: #cbd5e1; }
.cabin-cell.is-partial { background: #fef3c7;  border-color: #f59e0b; }
.cabin-cell.is-full    { background: #dcfce7;  border-color: #10b981; }
.cabin-cell.is-rank-lock { box-shadow: inset 0 0 0 1px #5C8AA4; }
.cabin-cell.is-hospital { background: #fee2e2; border-color: #ef4444; }
.cabin-cell.is-hospital.is-full { background: #fecdd3; }
@media (max-width: 900px) {
  .cabins-row { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 520px) {
  .cabins-row { grid-template-columns: repeat(2, 1fr); }
}
.cabin-name {
  font-weight: 700;
  font-size: 12px;
  color: var(--navy-900);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 4px;
  line-height: 1.15;
}
.cabin-cap {
  font-size: 11px;
  color: #64748b;
  margin-bottom: 6px;
}
.cabin-chips {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: auto;
}
.cabin-empty {
  font-size: 11px;
  color: #94a3b8;
  font-style: italic;
}
.cabin-chip {
  display: inline-block;
  background: #e0e7ff;
  color: #1e1b4b;
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cabin-chip.gender-f { background: #fce7f3; color: #831843; }
.cabin-chip.gender-m { background: #dbeafe; color: #1e3a8a; }
.cabin-chip.gender-x { background: #e2e8f0; color: #1e293b; }
.cabin-chip:hover { filter: brightness(0.95); }

/* List view */
.cabins-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 12px;
  font-size: 14px;
}
.cabins-table th,
.cabins-table td {
  padding: 10px;
  border-bottom: 1px solid #e2e8f0;
  text-align: left;
  vertical-align: top;
}
.cabins-table thead th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
  background: #f8fafc;
}
.cabins-table tbody tr { cursor: pointer; }
.cabins-table tbody tr:hover { background: #f8fafc; }
.cabins-table .cabin-chip {
  font-size: 11px;
  padding: 3px 8px;
  margin: 2px 4px 2px 0;
}
.cabins-table .muted { color: #94a3b8; font-size: 12px; }

/* Couples + rotations */
.couple-row,
.rotation-row,
.medical-row,
.cabin-occupant-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid #e2e8f0;
  gap: 12px;
}
.couple-status {
  display: inline-block;
  background: #ede9fe;
  color: #5b21b6;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  margin-left: 8px;
  text-transform: capitalize;
}
.rotation-row .rotation-seg {
  display: inline-block;
  background: #e2e8f0;
  color: #334155;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  margin: 2px 4px 2px 0;
  cursor: pointer;
}
.rotation-row .rotation-seg.is-current {
  background: #bbf7d0;
  color: #14532d;
  font-weight: 600;
}
.cabin-occupant-meta { font-size: 12px; color: #64748b; margin-top: 2px; }

/* Modal */
#cabins-modal.modal { display: flex; }
#cabins-modal.modal.hidden { display: none; }
#cabins-modal .modal-card { max-width: 720px; width: 92%; }
.cabin-modal-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 700px) {
  .cabin-modal-grid { grid-template-columns: 1fr; }
}
.cabin-modal-form label {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--navy-700);
  margin-bottom: 12px;
}
.cabin-modal-form label input,
.cabin-modal-form label select {
  display: block;
  width: 100%;
  padding: 8px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 14px;
  margin-top: 4px;
  text-transform: none;
  letter-spacing: 0;
  color: var(--navy-900);
}
.cabins-modal-section-title {
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--navy-900);
}
.cabins-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}
.cabins-diff-scroll {
  max-height: 50vh;
  overflow-y: auto;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
}
.cabins-table tr.is-change td { background: #fef9c3; }
.cabins-table tr.is-warn td { background: #fee2e2; }

/* Module summary tiles (reuse the existing styling if defined; this is a safety net) */
.cabins-floorplan + .module-toolbar { margin-top: 12px; }

/* ============================================================
   R90 (2026-05-19) — OWNERS TAB
   ============================================================ */

/* Guest cards (Owners tab → Guests pane) */
.owners-guest-list {
  display: grid;
  /* R129 — min(320px, 100%) prevents the 320px floor from forcing horizontal page scroll when the container is narrower (iPhone SE etc.). */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 12px;
  /* R131b — equal-height rows. Without this, cards in the same row
     align to the tallest content; align-items:stretch was already the
     grid default but the children weren't honouring it. */
  align-items: stretch;
}
/* R131b — Wrapper fills the grid cell so .og-card can stretch to
   the full row height. */
.og-card-wrap { display: flex; }
.og-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  font: inherit;
  background: #fff;
  border: 1px solid #d9e1e9;
  border-radius: 10px;
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease, transform 80ms ease;
}
.og-card:hover {
  border-color: #284558;
  box-shadow: 0 6px 18px -12px rgba(10, 58, 94, 0.35);
}
.og-card:active { transform: translateY(1px); }
.og-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}
.og-card-head > div {
  flex: 1 1 auto;
  min-width: 0;
}
.og-card-head > .og-pill { flex: 0 0 auto; }
.og-card-name {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #284558;
  overflow-wrap: anywhere;
  /* R131b — clamp to two lines so wildly different name lengths
     don't make the header tower. The "(preferred)" suffix still
     shows; anything past line 2 ellipsises. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.og-card-sub {
  /* Legacy — superseded by .og-card-email + .og-card-phone in R131k.
     Kept so older HTML callers (if any) still render sanely. */
  margin: 4px 0 0;
  font-size: 13px;
  color: #6a7886;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* R131k — Card head now flows top-to-bottom: name → email → phone.
   .og-card-id-text grows; email + phone clamp to a single line so
   long addresses don't push the head past two lines. */
.og-card-id-text { flex: 1; min-width: 0; }
.og-card-email,
.og-card-phone {
  margin: 4px 0 0;
  font-size: 13px;
  color: #6a7886;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.og-card-phone { font-size: 12px; }
/* R131l — WhatsApp invite button. Nested inside the phone line so
   it reads as a "send to this number" action. Brand-green tint on
   hover; suppressed entirely when no phone number is on file. */
.og-wa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  margin-left: 6px;
  border-radius: 50%;
  background: #25d36622;
  color: #128c7e;
  cursor: pointer;
  vertical-align: -5px;
  transition: background 150ms ease, color 150ms ease;
}
.og-wa-btn:hover { background: #25d366; color: #fff; }
.og-wa-svg {
  width: 14px; height: 14px;
  fill: currentColor;
  display: block;
}
/* R131k — Status pill row (NEW / UPDATED / Last updated …). Sits
   between the head and the tags/chips. */
.og-card-status {
  margin-top: 10px;
}
.og-card-status .og-pill-strong {
  font-weight: 700;
  letter-spacing: 0.08em;
}
/* R131b — Chips row sits at the bottom of the card so cards in the
   same row line up at the foot regardless of how many chips each has.
   R131c — Right padding leaves clear airspace for the ⋯ menu trigger
   in the bottom-right corner so chips don't slide underneath it. */
.og-card-chips {
  margin-top: auto;
  padding-top: 10px;
  padding-right: 40px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.og-chip {
  display: inline-block;
  font-size: 12px;
  padding: 3px 9px;
  border-radius: 999px;
  background: #f1ece0;
  color: #5d4914;
  border: 1px solid #e6d6b7;
}
.og-chip-danger {
  background: #fbeae6;
  color: #b34233;
  border-color: #e7b6ab;
}
/* R131f — Watersports kit pills (mask · fin · lifejacket).
   Tighter spacing + slightly smaller than the other chips so the
   three sit together as a visual group. */
.og-kit-group {
  display: inline-flex;
  gap: 4px;
}
.og-kit-group .og-chip.og-kit {
  font-size: 11px;
  padding: 2px 8px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
/* R131h — Inline fin SVG sized to match the emoji glyphs sitting
   either side of it. currentColor lets the icon recolour with the
   chip text colour on hover / active states. */
.og-kit-group .og-kit-svg {
  width: 13px;
  height: 13px;
  fill: currentColor;
  flex: 0 0 13px;
}

.og-meta { color: #6a7886; font-size: 13px; margin-left: 4px; }

.og-pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  background: #eef2f7;
  color: #455260;
  white-space: nowrap;
}
.og-pill-success { background: #e6f4ec; color: #2d7d52; }
.og-pill-warn    { background: #fff5d6; color: #8a6300; }
.og-pill-info    { background: #e6effb; color: #185abd; }
.og-pill-muted   { background: #ececec; color: #7a7a7a; }

/* Invitation rows */
.owners-inv-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.og-inv {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  background: #fff;
  border: 1px solid #d9e1e9;
  border-radius: 10px;
  padding: 12px 16px;
  flex-wrap: wrap;
}
.og-inv-main { flex: 1; min-width: 240px; }
.og-inv-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.og-inv-name { font-weight: 600; color: #284558; }
.og-inv-meta {
  font-size: 13px;
  color: #6a7886;
}
.og-inv-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.og-action {
  font: inherit;
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid #b5cbdc;
  background: #fff;
  color: #284558;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.og-action:hover { background: #284558; color: #fff; border-color: #284558; }
.og-action-danger { border-color: #e7b6ab; color: #b34233; }
.og-action-danger:hover { background: #b34233; color: #fff; border-color: #b34233; }
/* R131 — Compact X button on invitation rows to archive in one tap. */
.og-action-x {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid #DCE7ED;
  background: #fff;
  color: #6a7886;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.og-action-x:hover { background: #b34233; color: #fff; border-color: #b34233; }
.og-inv.is-archived { opacity: 0.6; }

/* R131 — Card wrapper hosting the card button and the menu trigger.
   R131b — Wrapper is now a flex container (set in .owners-guest-list
   block above) so cards stretch to equal height; keep position:relative
   here so the absolute menu trigger anchors against the wrapper. */
.og-card-wrap {
  position: relative;
}
.og-card-wrap.is-archived .og-card { opacity: 0.55; }
/* R131c — Move the menu trigger to the bottom-right corner so it
   stops competing with the name + Preferences-received pill at the
   top. Menu opens upwards (bottom-anchored) so it stays inside the
   card's visual frame instead of crashing into the card below. */
.og-card-menu-btn {
  position: absolute;
  bottom: 10px; right: 10px;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1px solid #DCE7ED;
  background: #fff;
  color: #6a7886;
  /* R131d — flex-center the ⋯ glyph. Without this the horizontal-
     ellipsis character sits on the typographic baseline and the
     dots look low in the pill. The padding-bottom nudge accounts
     for the glyph's own bottom-skew. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0 4px 0;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
  box-shadow: 0 1px 3px rgba(40, 69, 88, 0.06);
}
.og-card-menu-btn:hover { background: #284558; color: #fff; border-color: #284558; }
.og-card-menu {
  position: absolute;
  /* Anchor at the bottom-right and grow upwards. 44px clears the
     trigger (28px + a small gap). */
  bottom: 46px; right: 8px;
  min-width: 200px;
  background: #fff;
  border: 1px solid #DCE7ED;
  border-radius: 8px;
  box-shadow: 0 -8px 24px rgba(40, 69, 88, 0.12);
  padding: 6px;
  z-index: 3;
  display: none;
}
.og-card-menu.is-open { display: block; }
.og-menu-section {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6a7886;
  padding: 6px 10px 4px;
}
.og-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  padding: 8px 10px;
  border-radius: 4px;
  font-size: 13px;
  color: #284558;
  cursor: pointer;
}
.og-menu-item:hover { background: #EEF3F6; }
.og-menu-item.is-current { background: #DCE7ED; font-weight: 600; }
.og-menu-item.og-menu-danger { color: #b34233; }
.og-menu-item.og-menu-danger:hover { background: #fbeae6; }
.og-menu-sep {
  height: 1px;
  background: #DCE7ED;
  margin: 4px 0;
}

/* R131 — Profile photo thumb + monogram fallback inside the card head. */
.og-card-id { display: flex; align-items: center; gap: 12px; }
.og-card-thumb {
  width: 56px; height: 56px; flex: 0 0 56px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid #DCE7ED;
  background: #EEF3F6;
}
.og-card-thumb-empty {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; letter-spacing: 0.02em;
  color: #284558;
}

/* R131 — VIP chip alongside the guest name. */
.og-vip-chip {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
}
.og-vip-family { background: #284558; color: #fff; }
.og-vip-vvip   { background: #b08537; color: #fff; }
.og-vip-vip    { background: #DCE7ED; color: #284558; }

/* R131 — Tag pills under the card head. */
.og-card-tags {
  display: flex; flex-wrap: wrap; gap: 4px 6px;
  margin: 6px 0 4px;
}
.og-tag-pill {
  padding: 2px 8px;
  background: #EEF3F6;
  border: 1px solid #DCE7ED;
  border-radius: 999px;
  font-size: 11px;
  color: #284558;
}

/* 2026-05-31 — Full vs Essentials chooser cards. */
.og-version-choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 10px;
}
.og-version-choice {
  display: flex;
  flex-direction: column;
  text-align: left;
  background: #fff;
  border: 1px solid #DCE7ED;
  border-radius: 10px;
  padding: 16px;
  font: inherit;
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease, transform 80ms ease;
}
.og-version-choice:hover {
  border-color: #0a3a5e;
  box-shadow: 0 6px 18px -12px rgba(10, 58, 94, 0.35);
}
.og-version-choice:active { transform: translateY(1px); }
.og-version-choice-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.og-version-choice-title {
  font-size: 15px;
  font-weight: 600;
  color: #0a3a5e;
}
.og-version-choice-tag {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
  color: #6a7886;
  padding: 2px 8px;
  background: #EEF3F6;
  border-radius: 999px;
}
.og-version-choice-desc {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: #4a5765;
}

/* 2026-05-31 — Essentials chip on the drawer header. */
.og-d-version-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin-left: 8px;
  vertical-align: middle;
}
.og-d-version-chip-essentials { background: #f1ece0; color: #5d4914; border: 1px solid #e6d6b7; }
.og-d-version-chip-full       { background: #EEF3F6; color: #284558; border: 1px solid #DCE7ED; }

/* R131 — Counter badge on the guest sub-tab bar. */
.og-tab-count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  background: #DCE7ED;
  color: #284558;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  min-width: 18px;
  text-align: center;
}
.finance-tab.active .og-tab-count {
  background: #284558;
  color: #fff;
}

/* Guest detail drawer */
.og-d-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ece4d6;
  margin-bottom: 16px;
}
.og-d-name {
  margin: 0;
  font-family: 'Times New Roman', Georgia, serif;
  font-weight: 400;
  font-size: 24px;
  color: #284558;
}
.og-d-sub {
  margin: 4px 0 0;
  color: #6a7886;
  font-size: 14px;
}
.og-d-section {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #284558;
  margin: 22px 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid #ece4d6;
}
.og-d-grid {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 24px;
}
@media (max-width: 600px) {
  .og-d-grid { grid-template-columns: 1fr; }
}
.og-d-row {
  display: contents;
}
.og-d-row dt {
  font-size: 12px;
  font-weight: 600;
  color: #6a7886;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 6px 0 2px;
}
.og-d-row dd {
  margin: 0;
  font-size: 14px;
  padding: 0 0 8px;
  white-space: pre-wrap;
  border-bottom: 1px dashed #f0e9d8;
}
.og-d-confidential {
  background: #fff8e9;
  border: 1px solid #e9d99c;
  border-radius: 8px;
  padding: 12px 14px;
}
.og-d-confidential .og-d-row dd { border-bottom-color: #e6d289; }
.og-d-comp {
  background: #fbfaf6;
  border: 1px solid #ece4d6;
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  font-size: 14px;
}

/* ============================================================
   R125 — Engineering Logbook
   Module-scoped, all selectors namespaced .englog-*. Borrows the
   project palette tokens (--navy, --ink, --line, --cream, --red).
   Category accents map to the seven entry types; severity uses the
   shared danger/warn/success tokens.
   ============================================================ */
:root {
  --englog-machinery: #2e6b8a;
  --englog-fuel:      #c06010;
  --englog-defect:    var(--red-500);
  --englog-ums:       var(--success);
  --englog-safety:    #1a4fa0;
  --englog-env:       #0671a0;
  --englog-general:   #5b21b6;
  --englog-permit:    #b45309;
  --englog-handover:  var(--navy-700);
}

/* Prompts banner (AIS / scheduled / AMS) */
.englog-prompts {
  display: flex; flex-direction: column; gap: 8px;
  margin: 12px 0 16px;
}
.englog-prompt {
  background: #fff8e6;
  border: 1px solid #f0d680;
  border-left: 4px solid var(--warn);
  border-radius: var(--radius);
  padding: 10px 14px;
  display: flex; align-items: center; gap: 12px;
  font-size: 13px;
}
.englog-prompt-icon {
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border-radius: 50%;
  color: var(--warn); font-size: 16px;
}
.englog-prompt-body { flex: 1; min-width: 0; }
.englog-prompt-title { font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.englog-prompt-sub { font-size: 12px; color: var(--ink-soft); }
.englog-prompt-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* Status strip */
.englog-status {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}
.englog-status-card {
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.englog-status-label {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-muted); margin-bottom: 4px;
}
.englog-status-val {
  font-size: 14px; color: var(--ink); font-weight: 600;
}
.englog-status-sub { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }

/* Pending-handover banner */
.englog-pending-handover {
  background: #eff6ff;
  border: 1px solid #bcdcfa;
  border-left: 4px solid var(--navy-600);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 14px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.englog-pending-handover-body { flex: 1; min-width: 200px; }
.englog-pending-handover-title { font-weight: 600; color: var(--ink); }
.englog-pending-handover-sub { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }

/* Tab panels */
.englog-tab-panel { padding: 12px 0; }

/* Log header (search + filter chips) */
.englog-log-header {
  display: flex; gap: 10px; align-items: flex-start;
  margin-bottom: 14px; flex-wrap: wrap;
}
.englog-search {
  flex: 1; min-width: 220px;
  background: #fff;
  border: 1px solid var(--line);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--ink);
  border-radius: var(--radius);
  outline: none;
}
.englog-search:focus { border-color: var(--navy-600); }
.englog-filters {
  display: flex; gap: 6px; flex-wrap: wrap;
}

/* Log feed */
.englog-feed { display: flex; flex-direction: column; gap: 6px; }
.englog-date-sep {
  font-size: 11px; letter-spacing: .15em; text-transform: uppercase;
  color: var(--ink-muted);
  display: flex; align-items: center; gap: 10px;
  padding: 12px 0 4px;
}
.englog-date-sep::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}

.englog-entry {
  background: #fff;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  cursor: pointer;
  transition: box-shadow .15s, border-color .15s;
}
.englog-entry:hover { box-shadow: var(--shadow-sm); border-color: #d0d6df; }
.englog-entry.cat-machinery   { border-left-color: var(--englog-machinery); }
.englog-entry.cat-fuel        { border-left-color: var(--englog-fuel); }
.englog-entry.cat-defect      { border-left-color: var(--englog-defect); }
.englog-entry.cat-ums         { border-left-color: var(--englog-ums); }
.englog-entry.cat-safety      { border-left-color: var(--englog-safety); }
.englog-entry.cat-environmental { border-left-color: var(--englog-env); }
.englog-entry.cat-general     { border-left-color: var(--englog-general); }
.englog-entry.cat-permit      { border-left-color: var(--englog-permit); }
.englog-entry.cat-handover    { border-left-color: var(--englog-handover); background: #f7f9fc; }
.englog-entry.is-locked       { opacity: .85; }
.englog-entry.is-locked .englog-entry-event::after {
  content: ' 🔒'; font-size: 11px; color: var(--ink-muted);
}

.englog-entry-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.englog-entry-time {
  font-family: ui-monospace, monospace;
  font-size: 12px; color: var(--navy-700);
  font-weight: 600; letter-spacing: .02em;
}
.englog-entry-cat-badge {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 3px; background: var(--cream-dark);
  color: var(--ink-soft);
}
.englog-entry-cat-badge.cat-machinery     { background: rgba(46,107,138,.12);  color: #1d4f68; }
.englog-entry-cat-badge.cat-fuel          { background: rgba(192,96,16,.12);   color: #8a4408; }
.englog-entry-cat-badge.cat-defect        { background: var(--red-100);        color: var(--red-700); }
.englog-entry-cat-badge.cat-ums           { background: rgba(22,101,52,.10);   color: var(--success); }
.englog-entry-cat-badge.cat-safety        { background: rgba(26,79,160,.10);   color: #15407f; }
.englog-entry-cat-badge.cat-environmental { background: rgba(6,113,160,.10);   color: #054d70; }
.englog-entry-cat-badge.cat-general       { background: rgba(91,33,182,.10);   color: #4a1a96; }
.englog-entry-cat-badge.cat-permit        { background: rgba(180,83,9,.10);    color: var(--warn); }
.englog-entry-cat-badge.cat-handover      { background: rgba(20,37,61,.10);    color: var(--navy-700); }

.englog-sev-badge {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 3px;
}
.englog-sev-low      { background: rgba(22,101,52,.10);  color: var(--success); }
.englog-sev-medium   { background: rgba(180,83,9,.10);   color: var(--warn); }
.englog-sev-high     { background: var(--red-100);       color: var(--red-700); }
.englog-sev-critical { background: var(--red-500); color: #fff; }

.englog-entry-engineer {
  font-size: 11px; color: var(--ink-muted);
  margin-left: auto;
  font-family: ui-monospace, monospace;
}
.englog-entry-source {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  padding: 1px 5px; border-radius: 3px;
  background: #e0f2fe; color: #075985;
}
.englog-entry-event { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.englog-entry-comment { font-size: 13px; color: var(--ink-soft); font-style: italic; line-height: 1.45; }
.englog-entry-links {
  margin-top: 6px; display: flex; gap: 8px; flex-wrap: wrap;
  font-size: 11px;
}
.englog-entry-link {
  color: var(--navy-600); text-decoration: none;
  border: 1px solid var(--line); padding: 2px 7px; border-radius: 3px;
  background: var(--cream);
}
.englog-entry-link:hover { background: var(--cream-dark); }
.englog-entry-edited {
  font-size: 10px; color: var(--ink-muted); margin-top: 4px;
  font-family: ui-monospace, monospace;
}

/* Composer */
.englog-composer { max-width: 640px; }
.englog-help {
  background: var(--cream); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px 12px;
  font-size: 13px; color: var(--ink-soft); margin-bottom: 16px;
}
.englog-field-group { margin-bottom: 14px; }
.englog-field-label {
  display: block;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 6px; font-weight: 600;
}
.englog-input, .englog-select, .englog-textarea {
  width: 100%;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--ink);
  outline: none;
  font-family: inherit;
}
.englog-input:focus, .englog-select:focus, .englog-textarea:focus {
  border-color: var(--navy-600);
  box-shadow: 0 0 0 3px rgba(30,52,84,.10);
}
.englog-textarea { resize: vertical; line-height: 1.5; }

/* Category grid */
.englog-cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
}
.englog-cat-tile {
  display: flex; align-items: center; gap: 10px;
  background: #fff; border: 1.5px solid var(--line);
  border-radius: var(--radius); padding: 12px 14px;
  cursor: pointer; transition: all .15s;
  font-size: 13px; color: var(--ink);
  text-align: left;
}
.englog-cat-tile:hover {
  border-color: var(--navy-600); background: var(--cream);
}
.englog-cat-tile.selected {
  background: rgba(30,52,84,.06);
  border-color: var(--navy-700);
  box-shadow: 0 0 0 2px rgba(30,52,84,.10);
}
.englog-cat-tile-icon { font-size: 18px; line-height: 1; flex-shrink: 0; }
.englog-cat-tile-label {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); font-weight: 600;
}
.englog-cat-tile.selected .englog-cat-tile-label { color: var(--navy-700); }

/* Event pills */
.englog-event-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.englog-event-pill {
  font-size: 12px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink-soft);
  border-radius: 999px;
  cursor: pointer;
  transition: all .15s;
  font-family: inherit;
}
.englog-event-pill:hover { background: var(--cream); border-color: var(--navy-600); }
.englog-event-pill.selected {
  background: var(--navy-700);
  border-color: var(--navy-700);
  color: #fff;
}

/* Severity buttons */
.englog-sev-row { display: flex; gap: 6px; }
.englog-sev-btn {
  flex: 1;
  padding: 9px;
  border: 1.5px solid var(--line);
  background: #fff;
  cursor: pointer;
  border-radius: var(--radius);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-muted); text-align: center;
  font-weight: 600;
  transition: all .15s;
}
.englog-sev-btn.sel-low      { background: rgba(22,101,52,.10);  border-color: var(--success); color: var(--success); }
.englog-sev-btn.sel-medium   { background: rgba(180,83,9,.10);   border-color: var(--warn);    color: var(--warn); }
.englog-sev-btn.sel-high     { background: var(--red-100);       border-color: var(--red-500); color: var(--red-700); }
.englog-sev-btn.sel-critical { background: var(--red-500);       border-color: var(--red-700); color: #fff; }

/* Cross-link options */
.englog-crosslink-options {
  display: flex; flex-direction: column; gap: 6px;
}
.englog-crosslink-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--cream); border: 1px solid var(--line);
  padding: 8px 10px; border-radius: var(--radius);
  font-size: 13px;
}
.englog-crosslink-row input[type=checkbox] { transform: scale(1.1); }

/* Handover checklist */
.englog-checklist {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius);
}
.englog-checklist-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  font-size: 13px;
  color: var(--ink-soft);
}
.englog-checklist-item:last-child { border-bottom: none; }
.englog-checklist-item:hover { background: var(--cream); }
.englog-check-box {
  width: 20px; height: 20px;
  border: 1.5px solid var(--line);
  background: #fff;
  border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  font-size: 12px; color: var(--success);
  transition: all .15s;
}
.englog-checklist-item.checked .englog-check-box {
  background: rgba(22,101,52,.10);
  border-color: var(--success);
}
.englog-checklist-item.checked { color: var(--ink); }

/* Submit button */
.englog-submit { width: 100%; margin-top: 12px; }

/* Permits */
.englog-permits-header { margin-bottom: 14px; }
.englog-permit-composer {
  background: var(--cream); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-bottom: 16px;
}
.englog-permits-list { display: flex; flex-direction: column; gap: 8px; }
.englog-permit-card {
  background: #fff; border: 1px solid var(--line);
  border-left: 4px solid var(--englog-permit);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.englog-permit-card.is-closed { border-left-color: var(--ink-muted); opacity: .75; }
.englog-permit-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 4px; flex-wrap: wrap;
}
.englog-permit-title { font-weight: 600; color: var(--ink); flex: 1; min-width: 0; }
.englog-permit-status {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 3px;
  background: rgba(180,83,9,.10); color: var(--warn);
}
.englog-permit-status.closed { background: var(--cream-dark); color: var(--ink-muted); }
.englog-permit-meta { font-size: 12px; color: var(--ink-soft); margin-bottom: 4px; }
.englog-permit-detail { font-size: 13px; color: var(--ink-soft); margin: 6px 0; }
.englog-permit-actions { display: flex; gap: 8px; margin-top: 8px; }

/* Export */
.englog-quick-range { display: flex; flex-wrap: wrap; gap: 6px; }

/* Locked banner */
.englog-locked-notice {
  background: var(--cream); border: 1px dashed var(--line);
  padding: 12px 14px; border-radius: var(--radius);
  font-size: 13px; color: var(--ink-soft); margin: 16px 0;
}

/* Mobile tweaks */
@media (max-width: 600px) {
  .englog-cat-grid { grid-template-columns: repeat(2, 1fr); }
  .englog-sev-row { flex-wrap: wrap; }
  .englog-sev-btn { flex: 1 1 calc(50% - 3px); }
  .englog-status { grid-template-columns: 1fr 1fr; }
}


/* ============================================================
   INTERIOR CARE GUIDE (R130) — icare-* scoped block
   ============================================================ */
.icare-header { gap: 16px; align-items: start; }
.icare-conditions {
  display: flex; gap: 12px; flex-wrap: wrap;
}
.icare-conditions > div {
  display: flex; flex-direction: column;
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 10px; padding: 8px 12px; min-width: 96px;
}
.icare-cond-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.65; }
.icare-cond-val { font-size: 15px; font-weight: 600; margin-top: 2px; }

.icare-tabs {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 16px 0 20px;
  border-bottom: 1px solid var(--border, #e5e5e5);
  padding-bottom: 0;
}
.icare-tab {
  background: transparent; border: none;
  padding: 10px 16px; font-size: 14px; font-weight: 500;
  cursor: pointer; color: var(--text, #333);
  border-bottom: 3px solid transparent;
  transition: color .15s, border-color .15s, background .15s;
  border-radius: 8px 8px 0 0;
}
.icare-tab:hover { background: var(--hover, rgba(0,0,0,0.04)); }
.icare-tab.is-active {
  color: var(--accent, #0a66c2);
  border-bottom-color: var(--accent, #0a66c2);
  font-weight: 600;
}

.icare-section { margin-bottom: 28px; }
.icare-h { font-size: 16px; font-weight: 600; margin: 0 0 12px; }
.icare-h3 { font-size: 13px; font-weight: 600; margin: 8px 0; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; }
.icare-empty {
  padding: 32px; text-align: center;
  background: var(--card-bg, #fff);
  border: 1px dashed var(--border, #e5e5e5);
  border-radius: 12px;
  color: var(--text-soft, #666);
}

/* Chip rows (stains / surfaces) */
.icare-chiprow {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.icare-stain-chip {
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 13px;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s;
  color: var(--text, #333);
}
.icare-stain-chip:hover { background: var(--hover, rgba(0,0,0,0.04)); border-color: var(--accent, #0a66c2); }
.icare-stain-chip.is-priority { border-color: #d97706; color: #b45309; font-weight: 600; }
.icare-stain-chip.is-active {
  background: var(--accent, #0a66c2); color: #fff;
  border-color: var(--accent, #0a66c2); font-weight: 600;
}

/* Action card (spill first aid output) */
.icare-action {
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e5e5e5);
  border-left: 4px solid var(--accent, #0a66c2);
  border-radius: 12px;
  padding: 20px;
  margin-top: 8px;
}
.icare-priority {
  background: #fef3c7; color: #92400e;
  border: 1px solid #fcd34d;
  border-radius: 8px; padding: 10px 14px;
  font-weight: 600; font-size: 14px;
  margin: 12px 0;
}
.icare-note {
  background: rgba(10, 102, 194, 0.06);
  border-left: 3px solid var(--accent, #0a66c2);
  padding: 10px 14px;
  border-radius: 0 6px 6px 0;
  margin: 12px 0;
  font-size: 14px;
}
.icare-surface-note {
  background: rgba(0,0,0,0.03);
  padding: 12px 14px;
  border-radius: 8px;
  margin: 12px 0;
  font-size: 14px;
  line-height: 1.5;
}
.icare-steps {
  list-style: none; padding-left: 0; margin: 16px 0;
  counter-reset: step;
}
.icare-steps > li {
  background: rgba(0,0,0,0.02);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 10px;
}
.icare-step-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 15px;
}
.icare-step-num {
  background: var(--accent, #0a66c2);
  color: #fff; font-weight: 700;
  width: 26px; height: 26px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px;
  flex-shrink: 0;
}
.icare-step-tx { opacity: 0.55; font-size: 12px; }
.icare-step-detail { margin: 8px 0 0 36px; font-size: 14px; line-height: 1.55; color: var(--text-soft, #555); }
.icare-step-followup {
  background: #fff7ed; border: 1px dashed #fdba74;
  font-size: 13px; color: #9a3412;
}
.icare-avoid { margin-top: 18px; }
.icare-action-foot {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border, #e5e5e5);
  font-size: 13px;
  color: var(--text-soft, #666);
}

/* Pills */
.icare-pill-row { display: flex; flex-wrap: wrap; gap: 6px; }
.icare-pill {
  background: rgba(0,0,0,0.05);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 500;
}
.icare-pill-danger {
  background: #fee2e2;
  color: #991b1b;
  border: 1px solid #fca5a5;
}

/* Surfaces tab */
.icare-toolbar {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  margin-bottom: 16px;
}
.icare-filter-row { display: flex; gap: 6px; flex-wrap: wrap; flex: 1 1 auto; }
.icare-filter {
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 12px;
  cursor: pointer;
  color: var(--text, #333);
  transition: background .15s, border-color .15s, color .15s;
}
.icare-filter:hover { background: var(--hover, rgba(0,0,0,0.04)); }
.icare-filter.is-active { background: var(--text, #1f2937); color: #fff; border-color: var(--text, #1f2937); }
.icare-search {
  flex: 1 1 220px;
  padding: 8px 12px;
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 8px;
  font-size: 13px;
  background: var(--card-bg, #fff);
  color: var(--text, #333);
  min-width: 180px;
  height: 38px;
  box-sizing: border-box;
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
}
.icare-search:focus { outline: 2px solid var(--accent, #0a66c2); outline-offset: -1px; border-color: var(--accent, #0a66c2); }

/* Cards grid */
.icare-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}
.icare-card {
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 12px;
  padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.icare-card-head {
  display: flex; justify-content: space-between; align-items: start; gap: 8px;
  margin-bottom: 4px;
}
.icare-card-head h3 { font-size: 15px; font-weight: 600; margin: 0; }
.icare-card-cat {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  background: rgba(0,0,0,0.05);
  padding: 3px 8px; border-radius: 999px;
  flex-shrink: 0;
  opacity: 0.75;
}
.icare-card-block { font-size: 13px; line-height: 1.5; }
.icare-card-block h4 { font-size: 12px; font-weight: 600; margin: 0 0 4px; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; }
.icare-card-block p { margin: 0; color: var(--text-soft, #555); }
.icare-card-block ul { margin: 4px 0; padding-left: 18px; color: var(--text-soft, #555); }
.icare-card-avoid { padding-top: 8px; border-top: 1px dashed var(--border, #e5e5e5); }

/* Stones */
.icare-banner {
  background: rgba(10, 102, 194, 0.06);
  border: 1px solid rgba(10, 102, 194, 0.2);
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.6;
}
.icare-banner-warn {
  background: #fef3c7;
  border-color: #fcd34d;
  color: #78350f;
  margin-top: 16px;
}
.icare-stone-grid .icare-stone-card { gap: 8px; }
.icare-stone-status {
  font-size: 11px; font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.04em;
  flex-shrink: 0;
}
.icare-stone-status-ok       { background: #dcfce7; color: #166534; }
.icare-stone-status-due      { background: #fef3c7; color: #92400e; }
.icare-stone-status-overdue  { background: #fee2e2; color: #991b1b; }
.icare-stone-status-unknown  { background: rgba(0,0,0,0.08); color: var(--text-soft, #666); }
.icare-stone-log {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--border, #e5e5e5);
  font-size: 12px;
}
.icare-stone-log-lbl { opacity: 0.6; }

/* Reference (two-column) */
.icare-reference {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 28px;
}
.icare-ref-col {}
.icare-product-group { margin-bottom: 18px; }
.icare-product-list { padding-left: 18px; margin: 0; font-size: 13px; line-height: 1.6; }
.icare-product-list li { margin-bottom: 8px; color: var(--text-soft, #444); }
.icare-product-list strong { color: var(--text, #111); }
.icare-never-h { color: #991b1b; }
.icare-never-list { padding-left: 18px; margin: 0; font-size: 13px; line-height: 1.55; }
.icare-never-list li { margin-bottom: 12px; }
.icare-never-why { color: var(--text-soft, #666); font-size: 12px; }

@media (max-width: 760px) {
  .icare-reference { grid-template-columns: 1fr; gap: 20px; }
  .icare-toolbar { flex-direction: column; align-items: stretch; }
  .icare-search { width: 100%; flex: 0 0 auto; }
  .icare-tabs { flex-wrap: nowrap; overflow-x: auto; }
  .icare-tab { flex-shrink: 0; }
  .icare-conditions { width: 100%; }
}

/* ============================================================
   R134 — Watch Checklist
   ============================================================ */
#page-watch, #page-watch-log,
#page-watch-stations, #page-watch-template, #page-watch-devices {
  padding: 16px;
}

.watch-loading {
  padding: 40px; text-align: center; color: rgba(255,255,255,0.55);
}

/* ---- Enrolment card ---- */
.watch-enrol-card {
  max-width: 480px; margin: 24px auto 0;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02));
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 14px; padding: 22px;
}
.watch-enrol-eyebrow {
  font-size: 11px; letter-spacing: 0.10em; text-transform: uppercase;
  color: #fcd34d; font-weight: 700; margin-bottom: 6px;
}
.watch-enrol-blurb { color: rgba(255,255,255,0.70); margin: 0 0 14px; }
.watch-enrol-label, .watch-modal-label {
  display: block; margin-bottom: 12px; font-size: 12px;
  color: rgba(255,255,255,0.65); font-weight: 600;
}
.watch-enrol-label input, .watch-modal-label input,
.watch-modal-label textarea, .watch-modal-label select {
  display: block; width: 100%; margin-top: 4px;
  background: rgba(0,0,0,0.30); border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px; padding: 10px 12px; color: #fff; font-size: 15px;
}
.watch-modal-check {
  display: flex; gap: 8px; align-items: center;
  font-size: 13px; color: rgba(255,255,255,0.78); margin-bottom: 12px;
}
.watch-enrol-error, .watch-modal-error {
  margin-top: 6px; color: #fca5a5; font-size: 12px; min-height: 16px;
}

/* ---- Header ---- */
.watch-header {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
.watch-day-title { margin: 0; font-size: 22px; }
.watch-day-sub   { color: rgba(255,255,255,0.55); font-size: 13px; margin-top: 2px; }
.watch-header-right {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
}
.watch-sun-pill {
  background: rgba(252,211,77,0.08); border: 1px solid rgba(252,211,77,0.25);
  color: #fde68a; border-radius: 999px; padding: 6px 12px;
  font-size: 13px; font-variant-numeric: tabular-nums; font-weight: 700;
}
.watch-sun-pill .sun-icon { color: #fcd34d; margin-right: 2px; }
.watch-wk-pill {
  background: rgba(192,132,252,0.10); border: 1px solid rgba(192,132,252,0.30);
  border-radius: 12px; padding: 6px 14px; display: flex; flex-direction: column;
}
.watch-wk-label {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700;
}
.watch-wk-name { font-size: 14px; font-weight: 700; color: #fff; }
.watch-btn {
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.14);
  color: #fff; padding: 10px 16px; border-radius: 10px; font-weight: 700;
  cursor: pointer; font-size: 14px;
}
.watch-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.watch-btn:hover:not([disabled]) { background: rgba(255,255,255,0.10); }
.watch-btn.primary {
  background: #6aa3ff; border-color: #6aa3ff; color: #0b1220;
}
.watch-btn.primary:hover { background: #8ab8ff; }

/* ---- Banners ---- */
.watch-banner {
  border-radius: 10px; padding: 10px 14px; margin-bottom: 12px; font-size: 14px;
}
.watch-banner-info {
  background: rgba(106,163,255,0.08); border: 1px solid rgba(106,163,255,0.30);
  color: #bfdbfe;
}
.watch-banner-done {
  background: rgba(34,197,94,0.08); border: 1px solid rgba(34,197,94,0.30);
  color: #bbf7d0;
}
.watch-handover {
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px; padding: 10px 14px; margin-bottom: 14px;
  display: flex; flex-direction: column; gap: 4px; font-size: 13px;
  color: rgba(255,255,255,0.80);
}
.watch-handover strong {
  display: inline-block; min-width: 80px; color: rgba(255,255,255,0.55);
  font-weight: 700; text-transform: uppercase; font-size: 10px; letter-spacing: 0.08em;
}

/* ---- Round panels ---- */
.watch-rounds { display: flex; flex-direction: column; gap: 10px; }
.watch-round {
  background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.10);
  border-left: 4px solid rgba(255,255,255,0.18); border-radius: 12px;
  overflow: hidden;
}
.watch-round.is-pending   { border-left-color: rgba(255,255,255,0.18); }
.watch-round.is-open      { border-left-color: #fbbf24; }
.watch-round.is-late      { border-left-color: #f87171; }
.watch-round.is-completed { border-left-color: #22c55e; opacity: 0.85; }
.watch-round.is-missed    { border-left-color: #b91c1c; opacity: 0.7; }
.watch-round.is-skipped   { border-left-color: rgba(255,255,255,0.08); opacity: 0.55; }
.watch-round-head {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 12px 16px; cursor: pointer; align-items: center;
  list-style: none;
}
.watch-round-head::-webkit-details-marker { display: none; }
.watch-round-head-left  { display: flex; gap: 14px; align-items: baseline; min-width: 0; }
.watch-round-head-right { display: flex; gap: 14px; align-items: baseline; }
.watch-round-time {
  font-variant-numeric: tabular-nums; font-weight: 700; color: #fcd34d;
  font-size: 15px; min-width: 56px;
}
.watch-round-label {
  font-weight: 700; color: #fff; font-size: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.watch-round-progress { color: rgba(255,255,255,0.55); font-size: 12px; }
.watch-round-status {
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 700; padding: 4px 8px; border-radius: 999px;
  background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.70);
}
.watch-round.is-open    .watch-round-status { background: rgba(251,191,36,0.18); color: #fde68a; }
.watch-round.is-late    .watch-round-status { background: rgba(248,113,113,0.18); color: #fecaca; }
.watch-round.is-completed .watch-round-status { background: rgba(34,197,94,0.18); color: #bbf7d0; }
.watch-round.is-missed  .watch-round-status { background: rgba(185,28,28,0.20); color: #fca5a5; }
.watch-round-body {
  padding: 0 16px 14px;
  display: flex; flex-direction: column; gap: 12px;
}
.watch-round-skipped {
  padding: 10px 16px 14px; color: rgba(255,255,255,0.45); font-style: italic;
}

/* ---- Required stations ---- */
.watch-stations {
  background: rgba(0,0,0,0.20); border: 1px solid rgba(255,255,255,0.06);
  border-radius: 10px; padding: 10px 12px;
}
.watch-stations-head {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700; margin-bottom: 6px;
}
.watch-station {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 6px 8px; border-radius: 6px;
  font-size: 13px; color: rgba(255,255,255,0.78);
}
.watch-station.is-done {
  background: rgba(34,197,94,0.08); color: #bbf7d0;
}
.watch-station-when { font-variant-numeric: tabular-nums; }
.watch-stations .watch-btn { margin-top: 8px; }

/* ---- Items ---- */
.watch-items { display: flex; flex-direction: column; gap: 4px; }
.watch-item {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; border-radius: 8px;
  background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.04);
  cursor: pointer; font-size: 14px;
}
.watch-item:hover { background: rgba(255,255,255,0.05); }
.watch-item input[type="checkbox"] {
  width: 20px; height: 20px; margin: 0; flex: 0 0 auto;
  accent-color: #22c55e;
}
.watch-item-label { flex: 1; color: rgba(255,255,255,0.92); }
.watch-item-sched { color: rgba(255,255,255,0.45); font-size: 12px; margin-left: 6px; }
.watch-item-when {
  font-variant-numeric: tabular-nums; color: #bbf7d0; font-size: 12px;
  font-weight: 700; flex: 0 0 auto;
}
.watch-item.is-done .watch-item-label { color: rgba(255,255,255,0.55); text-decoration: line-through; }
.watch-item.is-late .watch-item-when  { color: #fca5a5; }

/* R145.2 — expandable bullet description on each tick item.
   The label is a transparent button so a tap on the label text
   expands the detail block below; the checkbox is independent. */
.watch-item-wrap { display: flex; flex-direction: column; gap: 0; }
/* R152 (v2.05) — child item indented under parent on the WK iPad. */
.watch-item-wrap.is-child {
  margin-left: 26px;
  border-left: 2px solid rgba(255,255,255,0.10);
  padding-left: 8px;
}
#page-watch .watch-item-wrap.is-child {
  border-left-color: rgba(40, 69, 88, 0.18);
}
.watch-item-label-btn {
  flex: 1;
  display: flex; align-items: center; gap: 6px;
  appearance: none;
  background: transparent; border: 0; padding: 0;
  text-align: left;
  color: inherit; font: inherit;
  cursor: pointer;
  min-width: 0;
}
.watch-item-label-btn.is-static { cursor: default; }
.watch-item-label-btn:focus-visible { outline: 2px solid rgba(106,163,255,0.55); outline-offset: 2px; border-radius: 4px; }
.watch-item-expand {
  flex: 0 0 auto;
  font-size: 12px; opacity: 0.55;
  transition: transform 0.15s ease;
  margin-left: 4px;
}
.watch-item.has-detail { /* subtle cue that there's more to see */ }
.watch-item.is-expanded .watch-item-expand { opacity: 0.9; }
.watch-item-detail {
  margin: 4px 0 8px 36px;
  padding: 10px 14px;
  background: rgba(106,163,255,0.06);
  border-left: 3px solid rgba(106,163,255,0.35);
  border-radius: 0 6px 6px 0;
  font-size: 13px; color: rgba(255,255,255,0.85);
}
.watch-item-detail[hidden] { display: none; }
.watch-item-detail ul { margin: 0; padding-left: 18px; }
.watch-item-detail li { margin: 3px 0; line-height: 1.45; }

/* Light-theme overrides for the laptop portal context */
#page-watch .watch-item-detail {
  background: rgba(11,37,69,0.04);
  border-left-color: rgba(11,37,69,0.30);
  color: var(--ink, #1A1A1A);
}

/* R145 — tick-style "Start Vessel Round" row. Sits in .watch-items
   alongside regular tick items but isn't a real <input> — clicks
   on the whole row open the walkabout. Uses a faux checkbox so it
   visually matches its siblings without confusing the tick semantics. */
.watch-item.watch-rounds-task {
  cursor: pointer;
  background: rgba(106,163,255,0.06);
  border-color: rgba(106,163,255,0.20);
}
.watch-item.watch-rounds-task:hover { background: rgba(106,163,255,0.10); }
.watch-item-checkbox {
  width: 20px; height: 20px; flex: 0 0 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid rgba(255,255,255,0.30);
  border-radius: 5px;
  font-size: 14px; font-weight: 800; line-height: 1;
  color: transparent;
}
.watch-item.watch-rounds-task.is-done {
  background: rgba(34,197,94,0.10);
  border-color: rgba(34,197,94,0.30);
  cursor: default;
}
.watch-item.watch-rounds-task.is-done .watch-item-checkbox {
  background: #22c55e; border-color: #22c55e; color: #fff;
}
.watch-item.watch-rounds-task.is-done .watch-item-label {
  color: rgba(255,255,255,0.55); text-decoration: line-through;
}
.watch-item.watch-rounds-task.is-done .watch-item-when { color: #bbf7d0; }

.watch-round-actions {
  display: flex; justify-content: flex-end; padding-top: 4px;
}
.watch-round-done   { color: #bbf7d0; font-size: 13px; }
.watch-round-missed { color: #fca5a5; font-size: 13px; }

/* ---- Modals ---- */
.watch-modal .modal-card {
  max-width: 480px;
}
.watch-modal h3 { margin-top: 0; }
.watch-modal-blurb { color: rgba(255,255,255,0.65); font-size: 13px; }
.watch-modal-actions {
  display: flex; gap: 10px; justify-content: flex-end; margin-top: 6px;
}

/* ---- Admin links footer ---- */
.watch-admin-links {
  margin-top: 24px; padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.06);
  display: flex; flex-wrap: wrap; gap: 18px;
  font-size: 13px;
}
.watch-admin-links a {
  color: rgba(255,255,255,0.55); text-decoration: none;
}
.watch-admin-links a:hover { color: #6aa3ff; }

@media (max-width: 720px) {
  .watch-header { flex-direction: column; align-items: stretch; }
  .watch-header-right { justify-content: space-between; }
  .watch-round-head-right { flex-direction: column; align-items: flex-end; gap: 4px; }
}

/* ============================================================
   R134 task 5 — Watch QR Scanner overlay
   ============================================================ */
.watch-scan-modal .modal-card {
  max-width: 520px; padding: 0; overflow: hidden;
}
.watch-scan-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; border-bottom: 1px solid rgba(255,255,255,0.08);
}
.watch-scan-head h3 { margin: 0; }
.watch-scan-close {
  background: none; border: none; color: rgba(255,255,255,0.65);
  font-size: 28px; cursor: pointer; line-height: 1;
}
.watch-scan-camera {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  background: #000; overflow: hidden;
}
.watch-scan-camera video {
  width: 100%; height: 100%; object-fit: cover;
}
.watch-scan-overlay {
  position: absolute; inset: 0; pointer-events: none;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
}
.watch-scan-reticle {
  width: 60%; aspect-ratio: 1; max-width: 280px;
  border: 3px solid rgba(252,211,77,0.85); border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.45);
}
.watch-scan-hint {
  margin-top: 18px; color: #fff; font-size: 14px; font-weight: 700;
  text-shadow: 0 1px 3px rgba(0,0,0,0.8);
  padding: 6px 12px; background: rgba(0,0,0,0.45); border-radius: 8px;
}
.watch-scan-fallback {
  padding: 18px;
}
.watch-scan-fallback p {
  margin: 0 0 10px; color: rgba(255,255,255,0.78); font-size: 13px;
}
.watch-scan-fallback form { display: flex; gap: 10px; }
.watch-scan-fallback input {
  flex: 1; background: rgba(0,0,0,0.30); border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px; padding: 10px 12px; color: #fff; font-size: 15px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.watch-scan-status {
  padding: 0 18px; min-height: 24px; font-size: 13px;
  color: rgba(255,255,255,0.78);
}
.watch-scan-actions {
  display: flex; justify-content: flex-end; padding: 12px 18px 16px;
}

/* ============================================================
   R134 tasks 6/7/8 — Watch admin pages
   ============================================================ */
.watch-admin-toolbar {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  margin-bottom: 14px;
}
.watch-btn-ghost {
  background: transparent; border: 1px solid rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.75); padding: 8px 12px; font-size: 13px;
  text-decoration: none; border-radius: 8px;
}
.watch-btn-ghost:hover { background: rgba(255,255,255,0.06); color: #fff; }

.watch-admin-table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px; overflow: hidden;
}
.watch-admin-table th,
.watch-admin-table td {
  padding: 10px 14px; text-align: left;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  font-size: 13px; vertical-align: middle;
}
.watch-admin-table th {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); font-weight: 700;
  background: rgba(0,0,0,0.20);
}
.watch-admin-table tr.is-retired td { opacity: 0.5; }
.watch-admin-table tr:hover:not(.is-retired) { background: rgba(255,255,255,0.03); }
.watch-admin-table code {
  background: rgba(0,0,0,0.20); padding: 2px 6px; border-radius: 4px;
  font-size: 12px;
}
.watch-admin-num {
  width: 64px; background: rgba(0,0,0,0.20); border: 1px solid rgba(255,255,255,0.10);
  color: #fff; padding: 4px 8px; border-radius: 6px;
}
.watch-admin-actions { display: flex; gap: 6px; }

/* Dark-theme pill base — scoped to the .pill-on / .pill-off compound so
   it doesn't override the canonical light .pill component defined in
   the portal core. Used in watch admin + device admin tables which sit
   on a dark navy backdrop. */
.pill.pill-on,
.pill.pill-off {
  display: inline-block; font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; font-weight: 700;
  padding: 3px 8px; border-radius: 999px;
}
.pill-on  { background: rgba(34,197,94,0.16);  color: #bbf7d0; }
.pill-off { background: rgba(248,113,113,0.16); color: #fecaca; }

/* Template page */
.watch-template-rounds { display: flex; flex-direction: column; gap: 12px; }
.watch-template-round {
  background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px; padding: 12px 14px;
}
.watch-template-round.is-retired { opacity: 0.55; }
.watch-template-round-head {
  display: flex; justify-content: space-between; gap: 12px;
  align-items: center; flex-wrap: wrap; margin-bottom: 8px;
}
.watch-template-round-left { display: flex; gap: 10px; align-items: center; flex: 1; min-width: 0; }
.watch-template-round-meta {
  color: rgba(255,255,255,0.55); font-size: 12px;
}
.watch-template-round-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.watch-template-items { display: flex; flex-direction: column; gap: 4px; padding-left: 16px; }
.watch-template-item {
  display: flex; gap: 8px; align-items: center;
  padding: 6px 8px; border-radius: 6px;
  background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.04);
}
.watch-template-item.is-retired { opacity: 0.5; }
.watch-template-item-label { flex: 1; font-size: 13px; }
.watch-template-item-time { color: #fcd34d; font-size: 11px; font-weight: 700; }
.watch-template-add-item { align-self: flex-start; margin-top: 4px; }

/* R152 (v2.05) — Nested sub-steps. Children indent under their
   parent with a left margin + faint connector hint via a ⮡-style
   bullet. Indent / outdent buttons are scoped here too so they
   render compactly. */
.watch-template-item.is-child {
  margin-left: 32px;
  background: rgba(255,255,255,0.015);
  border-left: 2px solid rgba(255,255,255,0.08);
}
.watch-template-item-bullet {
  color: rgba(255,255,255,0.30);
  font-family: var(--mono, monospace);
  font-size: 14px;
  line-height: 1;
  margin-right: 2px;
}
.watch-btn-indent, .watch-btn-outdent {
  min-width: 28px;
  padding: 4px 8px;
  font-weight: 700;
}
.watch-btn-indent[disabled], .watch-btn-outdent[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}
#page-watch-template .watch-template-item.is-child {
  background: rgba(40, 69, 88, 0.04);
  border-left-color: rgba(40, 69, 88, 0.18);
}
#page-watch-template .watch-template-item-bullet {
  color: rgba(40, 69, 88, 0.4);
}

.watch-station-link {
  display: flex; gap: 8px; align-items: center;
  padding: 8px 10px; border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.04);
  cursor: pointer;
}
.watch-station-link:hover { background: rgba(255,255,255,0.03); }
.watch-station-links {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 320px; overflow-y: auto; margin-bottom: 8px;
}

/* ============================================================
   R134 task 9 — Due-round prompt + pulse animation
   ============================================================ */
.watch-due-prompt {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px; margin-bottom: 12px; border-radius: 12px;
  cursor: pointer; user-select: none;
  background: rgba(251,191,36,0.10);
  border: 1px solid rgba(251,191,36,0.40);
  color: #fde68a;
  animation: watch-due-pulse 2.2s ease-in-out infinite;
}
.watch-due-prompt.is-late {
  background: rgba(248,113,113,0.10);
  border-color: rgba(248,113,113,0.50);
  color: #fecaca;
  animation: watch-due-pulse-late 1.4s ease-in-out infinite;
}
.watch-due-prompt:hover { filter: brightness(1.15); }
.watch-due-glyph {
  width: 32px; height: 32px; flex: 0 0 32px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; font-weight: 800; font-size: 18px;
  background: rgba(251,191,36,0.25);
}
.watch-due-prompt.is-late .watch-due-glyph { background: rgba(248,113,113,0.30); }
.watch-due-text { flex: 1; min-width: 0; }
.watch-due-title { font-size: 14px; font-weight: 800; letter-spacing: 0.04em; }
.watch-due-sub   { font-size: 12px; opacity: 0.85; margin-top: 2px; }
.watch-due-cta   { font-weight: 700; flex: 0 0 auto; }

@keyframes watch-due-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(251,191,36,0.0);   }
  50%      { box-shadow: 0 0 0 6px rgba(251,191,36,0.18); }
}
@keyframes watch-due-pulse-late {
  0%, 100% { box-shadow: 0 0 0 0 rgba(248,113,113,0.0);  }
  50%      { box-shadow: 0 0 0 7px rgba(248,113,113,0.22); }
}

/* Scroll-to-round flash */
.watch-round-pulse {
  outline: 3px solid rgba(252,211,77,0.65);
  outline-offset: 2px;
  transition: outline-color 0.6s ease;
}

/* ============================================================
   R134 task 10 — Watch Log archive
   ============================================================ */
.watch-log-layout {
  display: grid; grid-template-columns: minmax(360px, 1fr) 2fr;
  gap: 18px; align-items: start;
}
.watch-log-list .watch-admin-table tr { cursor: pointer; }
.watch-log-list .watch-admin-table tr.is-selected td { background: rgba(106,163,255,0.10); }
.watch-log-detail {
  background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px; padding: 16px;
}
.watch-log-day-head h2 { margin: 0 0 6px; }
.watch-log-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px 18px; font-size: 12px; color: rgba(255,255,255,0.75);
  margin-bottom: 10px;
}
.watch-log-meta strong {
  display: inline-block; min-width: 80px; color: rgba(255,255,255,0.55);
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
}
.watch-log-notes {
  background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px; padding: 8px 12px; font-size: 13px;
  color: rgba(255,255,255,0.80); margin: 10px 0;
}
.watch-log-notes em {
  display: inline-block; min-width: 70px; color: rgba(255,255,255,0.50);
  font-style: normal; text-transform: uppercase; font-size: 10px;
  letter-spacing: 0.06em; font-weight: 700;
}
.watch-log-rounds { display: flex; flex-direction: column; gap: 12px; }
.watch-log-round {
  border: 1px solid rgba(255,255,255,0.06); border-radius: 10px;
  padding: 10px 14px;
}
.watch-log-round-head {
  display: flex; gap: 10px; align-items: baseline; margin-bottom: 6px; flex-wrap: wrap;
}
.watch-log-reason {
  background: rgba(248,113,113,0.10); border: 1px solid rgba(248,113,113,0.30);
  color: #fecaca; padding: 6px 10px; border-radius: 6px;
  margin: 4px 0 8px; font-size: 12px;
}
.watch-log-items, .watch-log-scans-block { display: flex; flex-direction: column; gap: 4px; }
.watch-log-scans-head {
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: rgba(255,255,255,0.50); font-weight: 700; margin: 8px 0 4px;
}
.watch-log-item, .watch-log-scan-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  gap: 8px; align-items: baseline;
  padding: 4px 6px; border-radius: 4px;
  font-size: 13px;
}
.watch-log-item.is-done .watch-log-tick { color: #22c55e; }
.watch-log-item.is-late .watch-log-when { color: #fca5a5; }
.watch-log-scan-row.is-done { color: #bbf7d0; }
.watch-log-note {
  grid-column: 2 / -1; font-style: italic;
  color: rgba(255,255,255,0.55); font-size: 12px;
}
.watch-log-when {
  font-variant-numeric: tabular-nums; color: rgba(255,255,255,0.55); font-size: 12px;
}
@media (max-width: 1000px) {
  .watch-log-layout { grid-template-columns: 1fr; }
}

/* ============================================================
   R134 — Harbour Watch Checklist launcher + kiosk overlay
   ------------------------------------------------------------
   Sits alongside the Emergency Muster button (50/50 split via
   .kiosk-muster-bar's flex). Navy / amber accent so it reads as
   "operational" rather than "emergency". The overlay below
   replaces the crew grid when the Watchkeeper opens the watch
   from inside the kiosk; closing returns to the sign-in board
   without any URL navigation.
   ============================================================ */
.kiosk-watch-launch-btn {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 18px 22px;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(180deg, #5C8AA4 0%, #4A7791 100%);
  color: #fff;
  cursor: pointer;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow:
    0 6px 18px rgba(76, 115, 133, 0.32),
    inset 0 1px 0 rgba(252,211,77,0.30);
  border: 1px solid rgba(252,211,77,0.35);
  transition: transform 0.08s, box-shadow 0.2s;
}
.kiosk-watch-launch-btn:hover {
  box-shadow:
    0 8px 24px rgba(76, 115, 133, 0.45),
    inset 0 1px 0 rgba(252,211,77,0.45);
}
.kiosk-watch-launch-btn:active { transform: scale(0.985); }
.kiosk-watch-launch-btn .kiosk-muster-glyph { font-size: 22px; color: #fcd34d; }
.kiosk-watch-launch-btn .kiosk-muster-label { font-size: 18px; }
.kiosk-watch-launch-btn .kiosk-muster-sub   { margin-left: auto; font-size: 11px; opacity: 0.85; text-transform: none; letter-spacing: 0; }

/* Phone: stack the two halves vertically — the bar already drops
   to one column on the narrow kiosk-grid breakpoint below. */
@media (max-width: 720px) {
  .kiosk-muster-bar { flex-direction: column; }
}

/* ---- Overlay ---- */
.kiosk-watch-overlay {
  background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 14px;
  margin-bottom: 14px;
  overflow: hidden;
}
.kiosk-watch-overlay-head {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  background: rgba(0,0,0,0.18);
}
.kiosk-watch-back {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.14);
  color: #fff;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13px; font-weight: 700;
  cursor: pointer;
}
.kiosk-watch-back:hover { background: rgba(255,255,255,0.10); }
.kiosk-watch-overlay-title {
  font-size: 14px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255,255,255,0.65); font-weight: 700;
}
.kiosk-watch-overlay-body {
  padding: 14px;
}
/* When the overlay is showing, hide the crew grid + emergency panel
   so the watch occupies the lower kiosk surface fully. Toggled by
   adding .kiosk-watch-active to #kiosk-view in SignIn.openWatchChecklist. */
#kiosk-view.kiosk-watch-active #kiosk-grid,
#kiosk-view.kiosk-watch-active #kiosk-emergency,
#kiosk-view.kiosk-watch-active #kiosk-muster-bar { display: none; }

/* R140 — Day-type pill (working / non-working) in the Watch header. */
.watch-daytype-pill {
  background: rgba(34,197,94,0.10);
  border: 1px solid rgba(34,197,94,0.30);
  border-radius: 12px;
  padding: 6px 14px;
  display: flex;
  flex-direction: column;
}
.watch-daytype-pill.is-non-working {
  background: rgba(106,163,255,0.10);
  border-color: rgba(106,163,255,0.30);
}

/* ============================================================
   R140e — Watch admin pages, light-theme refinement (PORTAL ONLY)
   ------------------------------------------------------------
   Every rule here is scoped under one of the portal page IDs:
     #page-watch, #page-watch-template, #page-watch-stations,
     #page-watch-devices, #page-watch-log
   The kiosk overlay renders into #kiosk-watch-body (no .page
   class, not one of these IDs) so it KEEPS the original dark
   watch CSS untouched. Captain + HODs working from the laptop
   see navy-on-cream that actually reads.
   ============================================================ */

#page-watch .watch-loading,
#page-watch-template .watch-loading,
#page-watch-stations .watch-loading,
#page-watch-devices  .watch-loading,
#page-watch-log      .watch-loading { color: var(--ink-soft, #4A5568); }

/* Toolbar buttons */
#page-watch .watch-btn,
#page-watch-template .watch-btn,
#page-watch-stations .watch-btn,
#page-watch-devices  .watch-btn,
#page-watch-log      .watch-btn {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
  box-shadow: 0 1px 2px rgba(11,37,69,0.04);
}
#page-watch .watch-btn:hover:not([disabled]),
#page-watch-template .watch-btn:hover:not([disabled]),
#page-watch-stations .watch-btn:hover:not([disabled]),
#page-watch-devices  .watch-btn:hover:not([disabled]),
#page-watch-log      .watch-btn:hover:not([disabled]) { background: var(--cream, #FAF7F2); }
#page-watch .watch-btn.primary,
#page-watch-template .watch-btn.primary,
#page-watch-stations .watch-btn.primary,
#page-watch-devices  .watch-btn.primary,
#page-watch-log      .watch-btn.primary {
  background: var(--navy-700, #14253D);
  border-color: var(--navy-700, #14253D);
  color: #fff;
}
#page-watch .watch-btn.primary:hover,
#page-watch-template .watch-btn.primary:hover,
#page-watch-stations .watch-btn.primary:hover,
#page-watch-devices  .watch-btn.primary:hover,
#page-watch-log      .watch-btn.primary:hover { background: var(--navy-600, #1E3454); }
#page-watch .watch-btn-ghost,
#page-watch-template .watch-btn-ghost,
#page-watch-stations .watch-btn-ghost,
#page-watch-devices  .watch-btn-ghost,
#page-watch-log      .watch-btn-ghost {
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink-soft, #4A5568);
}
#page-watch .watch-btn-ghost:hover,
#page-watch-template .watch-btn-ghost:hover,
#page-watch-stations .watch-btn-ghost:hover,
#page-watch-devices  .watch-btn-ghost:hover,
#page-watch-log      .watch-btn-ghost:hover {
  background: var(--cream, #FAF7F2);
  color: var(--ink, #1A1A1A);
}
#page-watch .watch-admin-num,
#page-watch-template .watch-admin-num,
#page-watch-stations .watch-admin-num,
#page-watch-devices  .watch-admin-num,
#page-watch-log      .watch-admin-num {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}

/* Tables (stations + devices + log list) */
#page-watch-template .watch-admin-table,
#page-watch-stations .watch-admin-table,
#page-watch-devices  .watch-admin-table,
#page-watch-log      .watch-admin-table {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  box-shadow: 0 1px 3px rgba(11,37,69,0.04);
}
#page-watch-template .watch-admin-table th,
#page-watch-template .watch-admin-table td,
#page-watch-stations .watch-admin-table th,
#page-watch-stations .watch-admin-table td,
#page-watch-devices  .watch-admin-table th,
#page-watch-devices  .watch-admin-table td,
#page-watch-log      .watch-admin-table th,
#page-watch-log      .watch-admin-table td { border-bottom-color: var(--line, #E5E0D5); }
#page-watch-template .watch-admin-table th,
#page-watch-stations .watch-admin-table th,
#page-watch-devices  .watch-admin-table th,
#page-watch-log      .watch-admin-table th {
  background: var(--cream, #FAF7F2);
  color: var(--ink-soft, #4A5568);
}
#page-watch-template .watch-admin-table tr:hover:not(.is-retired),
#page-watch-stations .watch-admin-table tr:hover:not(.is-retired),
#page-watch-devices  .watch-admin-table tr:hover:not(.is-retired),
#page-watch-log      .watch-admin-table tr:hover:not(.is-retired) { background: var(--cream, #FAF7F2); }
#page-watch-template .watch-admin-table code,
#page-watch-stations .watch-admin-table code,
#page-watch-devices  .watch-admin-table code,
#page-watch-log      .watch-admin-table code {
  background: var(--cream-dark, #F1ECE3);
  color: var(--ink, #1A1A1A);
}
#page-watch-stations .pill-on,
#page-watch-devices  .pill-on,
#page-watch-log      .pill-on { background: rgba(22,101,52,0.10); color: var(--success, #166534); }
#page-watch-stations .pill-off,
#page-watch-devices  .pill-off,
#page-watch-log      .pill-off { background: rgba(185,28,28,0.08); color: var(--danger,  #B91C1C); }

/* Template page — round cards + items */
#page-watch-template .watch-template-round {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
}
#page-watch-template .watch-template-round-meta { color: var(--ink-soft, #4A5568); }
#page-watch-template .watch-template-item {
  background: var(--cream, #FAF7F2);
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}
#page-watch-template .watch-template-item-label { color: var(--ink, #1A1A1A); }
#page-watch-template .watch-template-item-time  { color: #b45309; }

/* Today's-day view (Captain's read-only) — round panels + items */
#page-watch .watch-day-title { color: var(--ink, #1A1A1A); }
#page-watch .watch-day-sub   { color: var(--ink-soft, #4A5568); }
#page-watch .watch-sun-pill {
  background: rgba(252,211,77,0.18);
  border-color: rgba(180,83,9,0.30);
  color: #92400e;
}
#page-watch .watch-sun-pill .sun-icon { color: #b45309; }
#page-watch .watch-wk-pill {
  background: rgba(124,58,237,0.06);
  border-color: rgba(124,58,237,0.35);
}
#page-watch .watch-wk-label { color: var(--ink-soft, #4A5568); }
#page-watch .watch-wk-name  { color: var(--ink, #1A1A1A); }
#page-watch .watch-daytype-pill {
  background: rgba(22,101,52,0.10);
  border-color: rgba(22,101,52,0.30);
}
#page-watch .watch-daytype-pill.is-non-working {
  background: rgba(106,163,255,0.10);
  border-color: rgba(106,163,255,0.40);
}
#page-watch .watch-banner-info {
  background: #eef4ff;
  border-color: #93c5fd;
  color: #1e40af;
}
#page-watch .watch-banner-done {
  background: #f0fdf4;
  border-color: #86efac;
  color: var(--success, #166534);
}
#page-watch .watch-handover {
  background: var(--cream, #FAF7F2);
  border-color: var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}
#page-watch .watch-handover strong { color: var(--ink-soft, #4A5568); }
#page-watch .watch-round {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  border-left: 4px solid rgba(11,37,69,0.14);
  box-shadow: 0 1px 3px rgba(11,37,69,0.04);
}
#page-watch .watch-round.is-pending   { border-left-color: rgba(11,37,69,0.18); }
#page-watch .watch-round.is-open      { border-left-color: #d97706; }
#page-watch .watch-round.is-late      { border-left-color: var(--danger, #B91C1C); }
#page-watch .watch-round.is-completed { border-left-color: var(--success, #166534); }
#page-watch .watch-round.is-missed    { border-left-color: var(--danger, #B91C1C); }
#page-watch .watch-round.is-skipped   { border-left-color: rgba(11,37,69,0.10); }
#page-watch .watch-round-time     { color: #b45309; }
#page-watch .watch-round-label    { color: var(--ink, #1A1A1A); }
#page-watch .watch-round-progress { color: var(--ink-soft, #4A5568); }
#page-watch .watch-round-status   { background: rgba(11,37,69,0.06); color: var(--ink-soft, #4A5568); }
#page-watch .watch-round.is-open      .watch-round-status { background: rgba(245,158,11,0.18); color: #92400e; }
#page-watch .watch-round.is-late      .watch-round-status { background: rgba(185,28,28,0.12);  color: var(--danger, #B91C1C); }
#page-watch .watch-round.is-completed .watch-round-status { background: rgba(22,101,52,0.12);  color: var(--success, #166534); }
#page-watch .watch-round.is-missed    .watch-round-status { background: rgba(185,28,28,0.18);  color: var(--danger, #B91C1C); }
#page-watch .watch-round-skipped { color: var(--ink-muted, #8A94A6); }
#page-watch .watch-stations {
  background: var(--cream, #FAF7F2);
  border: 1px solid var(--line, #E5E0D5);
}
#page-watch .watch-stations-head { color: var(--ink-soft, #4A5568); }
#page-watch .watch-station       { color: var(--ink, #1A1A1A); }
#page-watch .watch-station.is-done {
  background: rgba(22,101,52,0.08);
  color: var(--success, #166534);
}
#page-watch .watch-item {
  background: var(--cream, #FAF7F2);
  border: 1px solid var(--line, #E5E0D5);
}
#page-watch .watch-item:hover  { background: #fff; }
#page-watch .watch-item-label  { color: var(--ink, #1A1A1A); }
#page-watch .watch-item-sched  { color: var(--ink-muted, #8A94A6); }
#page-watch .watch-item-when   { color: var(--success, #166534); }
#page-watch .watch-item.is-done .watch-item-label { color: var(--ink-muted, #8A94A6); }
#page-watch .watch-item.is-late .watch-item-when  { color: var(--danger, #B91C1C); }
#page-watch .watch-round-done   { color: var(--success, #166534); }
#page-watch .watch-round-missed { color: var(--danger, #B91C1C); }
#page-watch .watch-admin-links  { border-top-color: var(--line, #E5E0D5); }
#page-watch .watch-admin-links a { color: var(--ink-soft, #4A5568); }
#page-watch .watch-admin-links a:hover { color: var(--navy-700, #14253D); }

/* Watch log detail panel */
#page-watch-log .watch-log-detail {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
}
#page-watch-log .watch-log-list .watch-admin-table tr.is-selected td { background: #eef4ff; }
#page-watch-log .watch-log-meta      { color: var(--ink, #1A1A1A); }
#page-watch-log .watch-log-meta strong { color: var(--ink-soft, #4A5568); }
#page-watch-log .watch-log-notes {
  background: var(--cream, #FAF7F2);
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}
#page-watch-log .watch-log-notes em  { color: var(--ink-soft, #4A5568); }
#page-watch-log .watch-log-round     { border: 1px solid var(--line, #E5E0D5); }
#page-watch-log .watch-log-scans-head { color: var(--ink-soft, #4A5568); }
#page-watch-log .watch-log-reason {
  background: rgba(185,28,28,0.06);
  border: 1px solid rgba(185,28,28,0.30);
  color: var(--danger, #B91C1C);
}
#page-watch-log .watch-log-item.is-done .watch-log-tick { color: var(--success, #166534); }
#page-watch-log .watch-log-item.is-late .watch-log-when { color: var(--danger,  #B91C1C); }
#page-watch-log .watch-log-scan-row.is-done             { color: var(--success, #166534); }
#page-watch-log .watch-log-note      { color: var(--ink-muted, #8A94A6); }
#page-watch-log .watch-log-when      { color: var(--ink-soft,  #4A5568); }

/* Modals opened from any of these admin pages — labels + inputs.
   Modal hosts append to <body> so they're outside #page-watch-X;
   we use the .watch-modal wrapper class (which the modal HTML
   provides) as the scope. */
.watch-modal .watch-modal-label,
.watch-modal .watch-modal-blurb { color: var(--ink-soft, #4A5568); }
.watch-modal .watch-modal-label input,
.watch-modal .watch-modal-label textarea,
.watch-modal .watch-modal-label select {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}
.watch-modal .watch-modal-check { color: var(--ink, #1A1A1A); }
.watch-modal .watch-modal-error { color: var(--danger, #B91C1C); }
.watch-modal .watch-station-link        { border: 1px solid var(--line, #E5E0D5); color: var(--ink, #1A1A1A); }
.watch-modal .watch-station-link:hover  { background: var(--cream, #FAF7F2); }

/* ============================================================
   R140k — Watch PIN keypad component
   ------------------------------------------------------------
   Reuses the existing .pin-display / .pin-dot / .pin-keypad /
   .pin-key styles (chunky kiosk look). This block just wraps
   them in a labelled container for the Watch modals.
   ============================================================ */
.watch-pin-pad {
  margin: 14px 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.watch-pin-label {
  font-size: 12px;
  color: rgba(255,255,255,0.65);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.watch-pin-pad .pin-display { margin: 8px 0 14px; }
.watch-pin-pad .pin-keypad { max-width: 320px; margin: 0 auto; width: 100%; }
.watch-pin-pad .pin-key { padding: 18px 0; font-size: 24px; }

/* Light-theme overrides — the laptop Captain-on-portal view also
   uses these modals (sign-on etc.) so they need to read on the
   navy-on-cream theme too. Modals append to <body> outside the
   page IDs, so we scope by .watch-modal. */
.watch-modal .watch-pin-label { color: var(--ink-soft, #4A5568); }
.watch-modal .pin-dot {
  border-color: rgba(11,37,69,0.30);
  background: transparent;
}
.watch-modal .pin-dot.filled {
  background: var(--navy-700, #14253D);
  border-color: var(--navy-700, #14253D);
}
.watch-modal .pin-key {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
  box-shadow: 0 1px 2px rgba(11,37,69,0.04);
}
.watch-modal .pin-key:hover { background: var(--cream, #FAF7F2); }
.watch-modal .pin-key.del { color: var(--ink-soft, #4A5568); }

/* ============================================================
   R140m — Watch Template drag-and-drop
   ------------------------------------------------------------
   Replaces the sort_order number inputs with a small grip glyph
   on each row. Sortable.js applies .watch-drag-ghost to the
   placeholder slot, .watch-drag-chosen to the row being lifted,
   and .watch-drag-dragging to the cloned visual that follows the
   cursor; we style each for a clean lift-and-drop motion.
   ============================================================ */
.watch-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  color: rgba(255,255,255,0.45);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -2px;
  line-height: 1;
  cursor: grab;
  user-select: none;
  touch-action: none;
  flex: 0 0 auto;
  transition: background 0.1s, color 0.1s;
}
.watch-drag-handle:hover { color: rgba(255,255,255,0.85); background: rgba(255,255,255,0.06); }
.watch-drag-handle:active { cursor: grabbing; }

/* Sortable states */
.watch-drag-ghost {
  opacity: 0.35;
  background: rgba(252,211,77,0.12) !important;
  border-color: rgba(252,211,77,0.45) !important;
}
.watch-drag-chosen { cursor: grabbing; }
.watch-drag-dragging {
  box-shadow: 0 12px 32px rgba(0,0,0,0.45);
  transform: rotate(0.5deg);
  opacity: 0.95;
}

/* Light theme — Captain on portal — needs darker handle ink so
   the grip is visible against the cream cards. */
#page-watch-template .watch-drag-handle {
  color: rgba(11,37,69,0.35);
}
#page-watch-template .watch-drag-handle:hover {
  color: var(--ink, #1A1A1A);
  background: rgba(11,37,69,0.06);
}
#page-watch-template .watch-drag-ghost {
  background: rgba(252,211,77,0.18) !important;
  border-color: rgba(180,83,9,0.40) !important;
}
#page-watch-template .watch-drag-dragging {
  box-shadow: 0 12px 32px rgba(11,37,69,0.25);
}

/* R140n — Danger variant of the ghost button (Delete actions). */
.watch-btn-danger {
  color: var(--danger, #B91C1C);
  border-color: rgba(185,28,28,0.30);
}
.watch-btn-danger:hover {
  background: rgba(185,28,28,0.08);
  color: var(--danger, #B91C1C);
}
[data-theme="jarvis"] .watch-btn-danger,
.kiosk-watch-overlay .watch-btn-danger {
  color: #fca5a5;
  border-color: rgba(248,113,113,0.30);
}
[data-theme="jarvis"] .watch-btn-danger:hover,
.kiosk-watch-overlay .watch-btn-danger:hover {
  background: rgba(248,113,113,0.10);
  color: #fecaca;
}

/* ============================================================
   R140p — Walkabout scanner
   Camera at the top, scrollable grouped checklist below, status
   strip between them. Stays open the whole walk.
   ============================================================ */
.watch-walkabout-modal .modal-card {
  max-width: 640px;
  padding: 0;
  overflow: hidden;
  width: min(640px, 96vw);
}
.watch-walkabout-card {
  display: flex;
  flex-direction: column;
  max-height: 92vh;
}
.watch-walkabout-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 18px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.watch-walkabout-head h3 { margin: 0; }
.watch-walkabout-camera {
  position: relative; width: 100%; aspect-ratio: 16 / 10;
  background: #000; overflow: hidden;
}
.watch-walkabout-camera video {
  width: 100%; height: 100%; object-fit: cover;
}
.watch-walkabout-reticle {
  position: absolute; top: 50%; left: 50%;
  width: 45%; aspect-ratio: 1; max-width: 220px;
  transform: translate(-50%, -50%);
  border: 3px solid rgba(252,211,77,0.85);
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.40);
  pointer-events: none;
}
.watch-walkabout-hint {
  position: absolute; left: 50%; bottom: 14px;
  transform: translateX(-50%);
  background: rgba(0,0,0,0.55);
  color: #fff; padding: 6px 12px; border-radius: 8px;
  font-size: 13px; font-weight: 700;
}
.watch-walkabout-fallback {
  padding: 18px;
}
.watch-walkabout-fallback p {
  margin: 0 0 10px;
  color: rgba(255,255,255,0.75);
  font-size: 13px;
}
.watch-walkabout-fallback form { display: flex; gap: 10px; }
.watch-walkabout-fallback input {
  flex: 1;
  background: rgba(0,0,0,0.30);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px;
  padding: 10px 12px;
  color: #fff;
  font-size: 15px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.watch-walkabout-status {
  padding: 10px 18px;
  text-align: center;
  font-weight: 700;
  font-size: 14px;
  color: rgba(255,255,255,0.85);
  background: rgba(255,255,255,0.04);
  border-top: 1px solid rgba(255,255,255,0.06);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  transition: background 0.2s, color 0.2s;
}
.watch-walkabout-status.is-success {
  background: rgba(34,197,94,0.18);
  color: #bbf7d0;
}
.watch-walkabout-status.is-info {
  background: rgba(106,163,255,0.16);
  color: #bfdbfe;
}
.watch-walkabout-list {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 12px 18px;
}
.watch-walkabout-group { margin-bottom: 12px; }
.watch-walkabout-group-head {
  display: flex; gap: 10px; align-items: baseline;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  margin-bottom: 6px;
}
.watch-walkabout-group-time {
  font-variant-numeric: tabular-nums;
  font-weight: 700; color: #fcd34d; font-size: 13px;
  min-width: 48px;
}
.watch-walkabout-group-label {
  font-weight: 700; color: #fff; font-size: 13px;
}
.watch-walkabout-req {
  display: flex; gap: 10px; align-items: center;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 14px;
  color: rgba(255,255,255,0.85);
  transition: background 0.2s, color 0.2s;
}
.watch-walkabout-req-tick {
  width: 22px; height: 22px; flex: 0 0 22px;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid rgba(255,255,255,0.30);
  border-radius: 50%;
  font-size: 13px; font-weight: 700;
  color: rgba(255,255,255,0.30);
}
.watch-walkabout-req.is-done {
  background: rgba(34,197,94,0.12);
  color: #bbf7d0;
}
.watch-walkabout-req.is-done .watch-walkabout-req-tick {
  background: var(--success, #166534);
  border-color: var(--success, #166534);
  color: #fff;
}
/* R145 — skipped row: amber + strikethrough, reason on a second line. */
.watch-walkabout-req.is-skipped {
  background: rgba(245,158,11,0.10);
  color: rgba(254,215,170,0.95);
}
.watch-walkabout-req.is-skipped .watch-walkabout-req-tick {
  background: rgba(180,83,9,0.85);
  border-color: rgba(180,83,9,0.85);
  color: #fff;
}
.watch-walkabout-req.is-skipped .watch-walkabout-req-label {
  text-decoration: line-through;
}
.watch-walkabout-req-label { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.watch-walkabout-req-reason {
  font-size: 12px; font-weight: 500; opacity: 0.8;
  text-decoration: none;
  color: rgba(254,215,170,0.85);
}
/* R145 — Skip button (ghost amber pill, right side of pending rows). */
.watch-walkabout-req-skip {
  flex: 0 0 auto;
  appearance: none;
  background: rgba(245,158,11,0.12);
  border: 1px solid rgba(245,158,11,0.35);
  color: #fde68a;
  font-size: 12px; font-weight: 700;
  padding: 6px 12px; border-radius: 999px;
  cursor: pointer;
  min-height: 32px;
}
.watch-walkabout-req-skip:hover  { background: rgba(245,158,11,0.22); }
.watch-walkabout-req-skip:active { background: rgba(245,158,11,0.32); }
/* R145 — green pulse on the row that just scanned. The Captain's
   Mario-coin spec: a brief bright flash so the eye lands on what
   just landed. Sits on top of the .is-done baseline. */
@keyframes watchScanPulse {
  0%   { background: rgba(34,197,94,0.55); transform: scale(1); box-shadow: 0 0 0 0 rgba(34,197,94,0.45); }
  35%  { background: rgba(34,197,94,0.45); transform: scale(1.025); box-shadow: 0 0 0 6px rgba(34,197,94,0.25); }
  100% { background: rgba(34,197,94,0.12); transform: scale(1); box-shadow: 0 0 0 0 rgba(34,197,94,0.00); }
}
.watch-walkabout-req.is-just-scanned {
  animation: watchScanPulse 0.85s ease-out;
}
/* R145 — full-card victory flash when the round completes. */
@keyframes watchRoundCompleteFlash {
  0%   { box-shadow: 0 0 0 0   rgba(34,197,94,0.00); background-color: transparent; }
  20%  { box-shadow: 0 0 0 8px rgba(34,197,94,0.45); background-color: rgba(34,197,94,0.18); }
  100% { box-shadow: 0 0 0 0   rgba(34,197,94,0.00); background-color: transparent; }
}
.watch-walkabout-card.is-complete-flash {
  animation: watchRoundCompleteFlash 1.1s ease-out;
}
.watch-walkabout-actions {
  display: flex; justify-content: flex-end;
  padding: 12px 18px;
  border-top: 1px solid rgba(255,255,255,0.08);
}

/* Light-theme overrides for the laptop portal context */
#page-watch .watch-walkabout-status { background: var(--cream, #FAF7F2); color: var(--ink, #1A1A1A); border-color: var(--line, #E5E0D5); }
#page-watch .watch-walkabout-status.is-success { background: rgba(22,101,52,0.12); color: var(--success, #166534); }
#page-watch .watch-walkabout-status.is-info    { background: rgba(106,163,255,0.10); color: #1e40af; }
#page-watch .watch-walkabout-group-head { border-bottom-color: var(--line, #E5E0D5); }
#page-watch .watch-walkabout-group-time  { color: #b45309; }
#page-watch .watch-walkabout-group-label { color: var(--ink, #1A1A1A); }
#page-watch .watch-walkabout-req       { color: var(--ink, #1A1A1A); }
#page-watch .watch-walkabout-req-tick  { border-color: rgba(11,37,69,0.30); color: rgba(11,37,69,0.40); }
#page-watch .watch-walkabout-req.is-done { background: rgba(22,101,52,0.10); color: var(--success, #166534); }
#page-watch .watch-walkabout-req.is-skipped { background: rgba(180,83,9,0.10); color: #92400e; }
#page-watch .watch-walkabout-req.is-skipped .watch-walkabout-req-reason { color: #92400e; }
#page-watch .watch-walkabout-req-skip {
  background: rgba(245,158,11,0.10); border-color: rgba(180,83,9,0.40); color: #92400e;
}
#page-watch .watch-item.watch-rounds-task {
  background: rgba(11,37,69,0.04); border-color: rgba(11,37,69,0.18);
}
#page-watch .watch-item.watch-rounds-task:hover { background: rgba(11,37,69,0.07); }
#page-watch .watch-item-checkbox { border-color: rgba(11,37,69,0.35); }
#page-watch .watch-item.watch-rounds-task.is-done {
  background: rgba(22,101,52,0.08); border-color: rgba(22,101,52,0.30);
}
#page-watch .watch-item.watch-rounds-task.is-done .watch-item-label { color: rgba(11,37,69,0.55); }
#page-watch .watch-item.watch-rounds-task.is-done .watch-item-when  { color: var(--success, #166534); }

/* R140s — Previous Watchkeeper's handover block in the sign-on modal. */
.watch-previous-handover {
  background: rgba(106,163,255,0.08);
  border: 1px solid rgba(106,163,255,0.30);
  border-radius: 10px;
  padding: 10px 12px;
  margin: 0 0 14px;
  font-size: 13px;
  color: rgba(255,255,255,0.85);
}
.watch-previous-handover-eyebrow {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  font-weight: 700;
  margin-bottom: 4px;
}
.watch-previous-handover-row { margin-top: 2px; }
.watch-previous-handover-row strong {
  display: inline-block;
  min-width: 64px;
  color: rgba(255,255,255,0.55);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.watch-previous-handover-empty {
  color: rgba(255,255,255,0.45);
  font-style: italic;
}
/* Light theme — laptop portal context. */
.watch-modal .watch-previous-handover {
  background: #eef4ff;
  border-color: #93c5fd;
  color: #1e40af;
}
.watch-modal .watch-previous-handover-eyebrow,
.watch-modal .watch-previous-handover-row strong {
  color: var(--ink-soft, #4A5568);
}
.watch-modal .watch-previous-handover-empty {
  color: var(--ink-muted, #8A94A6);
}

/* R142 — Sign-off signature block in the Watch Log archive. */
.watch-log-signature {
  margin: 10px 0;
  padding: 10px 12px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 8px;
}
.watch-log-signature-eyebrow {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  font-weight: 700;
  margin-bottom: 6px;
}
.watch-log-signature img {
  max-width: 360px;
  max-height: 140px;
  background: #fff;
  border-radius: 6px;
  display: block;
}
#page-watch-log .watch-log-signature {
  background: var(--cream, #FAF7F2);
  border-color: var(--line, #E5E0D5);
}
#page-watch-log .watch-log-signature-eyebrow { color: var(--ink-soft, #4A5568); }

/* ============================================================
   R140t — Modal-fit pass
   ------------------------------------------------------------
   Captain reported the Watch modals were scrolling on the iPad —
   PIN keypad with form above, walkabout with stacked rows + camera,
   etc. Tightening padding, capping heights, and switching the
   long-list modals to an internal scroll so the actions row
   stays pinned to the bottom.
   ============================================================ */

/* Generic — every watch modal caps at viewport height and pins
   the actions row to the bottom. Internal scroll inside the body. */
.watch-modal .modal-card {
  max-height: 92vh;
  display: flex;
  flex-direction: column;
}
.watch-modal .modal-card > form,
.watch-modal .modal-card > .watch-walkabout-list {
  min-height: 0;       /* allows the flex child to shrink + scroll */
}
.watch-modal .modal-card > form {
  display: flex;
  flex-direction: column;
}
.watch-modal .modal-card > form > .watch-modal-actions {
  margin-top: auto;    /* pin to bottom of the form's flex column */
}

/* PIN keypad — tighter so 6-digit + keypad + actions fits at 1024×768. */
.watch-pin-pad { margin: 10px 0; }
.watch-pin-pad .pin-display { margin: 6px 0 10px; }
.watch-pin-pad .pin-key { padding: 14px 0; font-size: 22px; }
.watch-pin-pad .pin-keypad { gap: 8px; }

/* Sign-on modal has the most fields — let it scroll internally
   if the device is narrow, but keep the Sign on / Cancel row visible. */
.watch-modal .watch-modal-label { margin-bottom: 8px; }
.watch-modal .watch-modal-label input,
.watch-modal .watch-modal-label select,
.watch-modal .watch-modal-label textarea { padding: 8px 12px; }
.watch-modal .watch-modal-label textarea { min-height: 56px; }

/* Walkabout modal — camera + status + list + actions all fit at
   landscape iPad. Camera capped, list scrolls internally. */
.watch-walkabout-card { max-height: 92vh; }
.watch-walkabout-camera { aspect-ratio: auto; max-height: 36vh; }
.watch-walkabout-list { max-height: 40vh; }

/* ============================================================
   R140u — Walkabout close button + backdrop fixes
   ------------------------------------------------------------
   Captain reported the × button didn't dismiss. Two real causes:
   • 28px font with no padding = ~28px tap target. iOS HIG says
     44×44 minimum — easy to miss with a finger.
   • The outer .watch-walkabout-modal had no onclick handler, so
     tapping the dim backdrop did nothing.
   ============================================================ */
.watch-walkabout-head {
  position: relative;
  z-index: 5;
}
.watch-walkabout-close {
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.20);
  color: #fff;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 28px; line-height: 1;
  border-radius: 10px;
  cursor: pointer;
  padding: 0;
  /* Sit above any subsequent camera layer just in case it gets a
     positive z-index from the browser's compositor. */
  position: relative;
  z-index: 10;
}
.watch-walkabout-close:hover { background: rgba(255,255,255,0.18); }
.watch-walkabout-close:active { transform: scale(0.94); }

/* Light theme — laptop portal */
.watch-modal.watch-walkabout-modal .watch-walkabout-close,
#page-watch .watch-walkabout-close {
  background: #fff;
  border: 1px solid var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}

/* ============================================================
   R140v — Walkabout modal layout + contrast rebuild
   ------------------------------------------------------------
   Reported bugs:
   • Camera was eating 36vh → list got pushed below the fold.
   • List text used rgba(255,255,255,0.85) but the modal-card is
     light by default and the .watch-walkabout-modal scope wasn't
     covered by the #page-watch light-theme overrides.
   ============================================================ */
.watch-walkabout-modal .modal-card { width: min(560px, 96vw); }
.watch-walkabout-card {
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.watch-walkabout-head { flex: 0 0 auto; }
.watch-walkabout-camera {
  flex: 0 0 auto;
  aspect-ratio: auto;
  height: 28vh;
  max-height: 280px;
}
.watch-walkabout-status { flex: 0 0 auto; }
.watch-walkabout-list   { flex: 1 1 auto; min-height: 0; }
.watch-walkabout-actions { flex: 0 0 auto; }

/* Always-light contrast — the modal is appended to <body> outside
   any #page-* parent, so we scope under .watch-walkabout-modal
   directly. Dark Jarvis theme override at the bottom. */
.watch-walkabout-modal .modal-card {
  background: #fff;
  color: var(--ink, #1A1A1A);
}
.watch-walkabout-modal .watch-walkabout-head {
  border-bottom-color: var(--line, #E5E0D5);
  background: var(--cream, #FAF7F2);
}
.watch-walkabout-modal .watch-walkabout-head h3 { color: var(--ink, #1A1A1A); }
.watch-walkabout-modal .watch-walkabout-close {
  background: #fff;
  border-color: var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}
.watch-walkabout-modal .watch-walkabout-status {
  background: var(--cream, #FAF7F2);
  color: var(--ink, #1A1A1A);
  border-color: var(--line, #E5E0D5);
}
.watch-walkabout-modal .watch-walkabout-status.is-success { background: rgba(22,101,52,0.12); color: var(--success, #166534); }
.watch-walkabout-modal .watch-walkabout-status.is-info    { background: rgba(106,163,255,0.10); color: #1e40af; }
.watch-walkabout-modal .watch-walkabout-group-head { border-bottom-color: var(--line, #E5E0D5); }
.watch-walkabout-modal .watch-walkabout-group-time  { color: #b45309; }
.watch-walkabout-modal .watch-walkabout-group-label { color: var(--ink, #1A1A1A); }
.watch-walkabout-modal .watch-walkabout-req         { color: var(--ink, #1A1A1A); }
.watch-walkabout-modal .watch-walkabout-req-tick    { border-color: rgba(11,37,69,0.30); color: rgba(11,37,69,0.40); }
.watch-walkabout-modal .watch-walkabout-req.is-done {
  background: rgba(22,101,52,0.10);
  color: var(--success, #166534);
}
.watch-walkabout-modal .watch-walkabout-req.is-skipped {
  background: rgba(180,83,9,0.10); color: #92400e;
}
.watch-walkabout-modal .watch-walkabout-req.is-skipped .watch-walkabout-req-reason { color: #92400e; }
.watch-walkabout-modal .watch-walkabout-req-skip {
  background: rgba(245,158,11,0.12); border-color: rgba(180,83,9,0.35); color: #92400e;
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-req.is-skipped {
  background: rgba(245,158,11,0.10); color: #fde68a;
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-req.is-skipped .watch-walkabout-req-reason { color: rgba(253,230,138,0.80); }
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-req-skip {
  background: rgba(245,158,11,0.12); border-color: rgba(245,158,11,0.40); color: #fde68a;
}
.watch-walkabout-modal .watch-walkabout-actions {
  border-top-color: var(--line, #E5E0D5);
  background: var(--cream, #FAF7F2);
}
.watch-walkabout-modal .watch-walkabout-fallback p { color: var(--ink-soft, #4A5568); }
.watch-walkabout-modal .watch-walkabout-fallback input {
  background: #fff;
  border-color: var(--line, #E5E0D5);
  color: var(--ink, #1A1A1A);
}

/* Jarvis dark theme — restore the original feel only when active */
[data-theme="jarvis"] .watch-walkabout-modal .modal-card {
  background: linear-gradient(180deg, #0f1b2d, #0a1424);
  color: #fff;
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-head {
  background: rgba(0,0,0,0.30);
  border-bottom-color: rgba(255,255,255,0.08);
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-head h3 { color: #fff; }
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-close {
  background: rgba(255,255,255,0.10);
  border-color: rgba(255,255,255,0.20);
  color: #fff;
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-status {
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.85);
  border-color: rgba(255,255,255,0.06);
}
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-group-label { color: #fff; }
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-req         { color: rgba(255,255,255,0.85); }
[data-theme="jarvis"] .watch-walkabout-modal .watch-walkabout-actions {
  background: rgba(0,0,0,0.20);
  border-top-color: rgba(255,255,255,0.08);
}

/* ============================================================
   R140w — "Make rounds" button promoted in the round body
   ------------------------------------------------------------
   Captain wanted the QR action front-and-centre on rounds that
   are physical walks. The button sits at the top of the round
   body (above the required-scans list and any tick items),
   reads "Make rounds" / "Continue rounds" depending on progress,
   and shows the scan count subtitle so the Watchkeeper knows
   what's left.
   ============================================================ */
.watch-make-rounds-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  padding: 16px 20px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.02em;
  margin-bottom: 12px;
}
.watch-make-rounds-sub {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  opacity: 0.85;
  text-transform: uppercase;
}
