/* ============================================================
   CHIEFMATE — Design System
   ============================================================
   All visual styling lives here. No inline styles anywhere.
   Import this once in base.html and every page gets it.

   Color palette:
     --bg-primary     Deep charcoal hull
     --bg-card        Raised surface
     --bg-input       Input field background
     --accent         Maritime steel blue
     --accent-warm    Navigation amber (alerts, highlights)
     --text-primary   Off-white readable text
     --text-muted     Subdued labels
     --border         Subtle separator
     --success        Positive / intercept toward
     --danger         Warning / intercept away
   ============================================================ */

/* ── Reset & Variables ──────────────────────────────────────── */

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

:root {
    --bg-primary:    #1a1d22;
    --bg-secondary:  #22262d;
    --bg-card:       #2c3038;
    --bg-input:      #1e222a;
    --bg-result:     #12151a;

    --accent:        #4a9fc8;
    --accent-dark:   #2d7fa8;
    --accent-light:  #58aed6;   /* marketing hover lighten — buttons brighten, not darken */
    --accent-warm:   #d4982a;
    --accent-warm-dk:#a87520;

    --text-primary:  #e8eaed;
    --text-muted:    #98a0a9;   /* brightened 2026-07-03 — old #8a9099 was hard to read on dark */
    --text-secondary: var(--text-muted);  /* alias — ~21 template usages predate the var existing */
    --text-label:    #b0b8c1;
    --text-result:   #a8d8f0;

    --border:        #3a3f48;
    --border-accent: #4a9fc8;
    --bg-raised:     rgba(255,255,255,0.04);   /* subtle raised-panel tint — theme-aware */

    /* Canvas / WebGL surfaces — read in JS via cmVar() at draw time so <canvas>
       modules (plotting sheet, maneuvering board, stability, signals, etc.)
       repaint correctly on day/night toggle. Night defaults here; day overrides
       under body.cm-day. */
    --canvas-bg:         #1a1e24;                 /* chart canvas background */
    --canvas-ink:        #e8eaed;                 /* solid marks/labels on canvas */
    --canvas-ink-faint:  rgba(232,234,237,0.55);  /* secondary canvas text */
    --canvas-ink-ghost:  rgba(232,234,237,0.25);  /* hint/placeholder canvas text */
    --canvas-grid:       rgba(74,159,200,0.14);   /* grid lines */
    --canvas-grid-text:  rgba(74,159,200,0.55);   /* grid labels */

    --success:       #3dba6a;
    --danger:        #d45050;
    --warning:       #d4982a;

    --radius:        4px;
    --radius-lg:     6px;

    --font-main:     'Arial', 'Helvetica', sans-serif;
    --font-mono:     'Courier New', 'Courier', monospace;

    --header-height: 78px;
    --button-min-h:  96px;
    --touch-target:  56px;
}

/* ── Base ───────────────────────────────────────────────────── */

html, body {
    height: 100%;
    background-color: var(--bg-primary);
    color: var(--text-primary);
    font-family: var(--font-main);
    font-size: 16px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    color: var(--text-primary);
}

/* ── Header / Wordmark ──────────────────────────────────────── */

.cm-header {
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--header-height);
    background: var(--bg-secondary);
    border-bottom: 2px solid var(--border);
    position: relative;
    flex-shrink: 0;
}

.cm-wordmark {
    display: inline-flex;
    align-items: center;
    line-height: 1;
    user-select: none;
}

/* Brand wordmark image — height tracks the header across every mode. */
.cm-wordmark-img { height: calc(var(--header-height) * 0.42); width: auto; display: block; }
.cm-wordmark-day { display: none; }               /* night (dark) is the default */
body.cm-day .cm-wordmark-night { display: none; }
body.cm-day .cm-wordmark-day   { display: block; }

.cm-version {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 11px;
    color: var(--text-muted);
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* ── Page Layout ────────────────────────────────────────────── */

.cm-page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.cm-body {
    flex: 1;
    padding: 20px 26px;
    max-width: 1360px;
    width: 100%;
    margin: 0 auto;
}

.cm-body--wide {
    max-width: 1300px;
}

.cm-body--narrow {
    max-width: 800px;
}

/* Wide displays (web/desktop) — use the screen. The Pi 7" (800×480) and the
   kiosk viewport never reach these breakpoints, so appliance mode is untouched. */
@media (min-width: 1440px) {
    .cm-body         { max-width: 1360px; padding: 32px 40px; }
    .cm-body--wide   { max-width: 1560px; }
    .cm-body--narrow { max-width: 880px; }
}
@media (min-width: 1920px) {
    .cm-body         { max-width: 1560px; }
    .cm-body--wide   { max-width: 1800px; }
}

/* ── Page Title Bar ─────────────────────────────────────────── */

.cm-page-title {
    font-size: 28px;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: 1px;
    text-transform: uppercase;
    margin-bottom: 24px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 14px;
}

.cm-page-title .title-icon {
    color: var(--accent);
    font-size: 22px;
}

/* The hidden attribute must win over any display rule on a class. The UA
   sheet's display:none loses to an author rule, so a hidden Install App
   button was still drawn wherever its class set a display (found 09-09 on
   the iPad web app). */
[hidden] { display: none !important; }

/* Back link — margin-left:auto pushes it to the right without disrupting
   pages that have no back link (their titles stay left-aligned naturally) */
.cm-back-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: none;
    color: var(--text);
    text-decoration: none;
    background: var(--bg-card);      /* opaque: the press base must not show through */
    border: 2px solid var(--border);
    border-radius: 7px;
    padding: 7px 16px;
    white-space: nowrap;
    margin-left: auto;
    cursor: pointer;
    flex-shrink: 0;
}
.cm-back-link:hover {
    color: var(--accent);
    border-color: var(--accent);
    --press-ring: var(--accent);
}

/* Main-menu A.I. Assistant shortcut — slim link pinned to the far right of the
   page-title row, same height as the row's other links (replaces the old grid
   card in the Vessel section) */
.cm-ai-link {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: none;
    color: var(--accent);
    text-decoration: none;
    border: 1px solid var(--accent);
    border-radius: 5px;
    padding: 5px 16px;
    white-space: nowrap;
    margin-left: auto;
    flex-shrink: 0;
    transition: color .15s, border-color .15s, background .15s;
}
.cm-ai-link:hover {
    background: rgba(74,159,200,.12);
}

/* ── Home Menu section dividers ─────────────────────────────── */
.cm-menu-section {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0 0;
}
.cm-menu-section-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--text-label);
    font-family: var(--font-mono);
    text-transform: uppercase;
    white-space: nowrap;
}
.cm-menu-section-line {
    flex: 1;
    height: 1px;
    background: var(--border);
    opacity: 0.45;
}

/* Empty placeholder grid cell */
.cm-menu-btn--placeholder {
    pointer-events: none;
    background: transparent;
    border: 1px dashed var(--border);
}

/* Coming-soon badge on menu buttons */
.cm-menu-btn--soon {
    opacity: 0.6;
    position: relative;
}
.cm-menu-btn--soon::after {
    content: 'SOON';
    position: absolute;
    top: 9px;
    right: 11px;
    font-size: 9px;
    letter-spacing: 1.5px;
    color: var(--accent-warm);
    font-family: var(--font-mono);
    opacity: 0.85;
}
.cm-menu-btn--soon:hover {
    opacity: 1;
}

/* Full-width button (Radio row) */
.cm-menu-btn--full {
    grid-column: 1 / -1;
    min-height: 80px;
    font-size: 20px;
}

/* ── Main Menu Grid ─────────────────────────────────────────── */

.cm-menu-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    margin-top: 20px;
}

.cm-menu-grid--2col {
    grid-template-columns: repeat(2, 1fr);
}

.cm-menu-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: var(--button-min-h);
    background: var(--bg-card);
    border: 2px solid var(--border);
    border-radius: 7px;
    color: var(--text-primary);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-align: center;
    padding: 16px 12px;
    cursor: pointer;
    text-decoration: none;
}

.cm-menu-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.cm-menu-btn .btn-sub {
    font-size: 13px;
    font-weight: 400;
    color: var(--text-muted);
    margin-top: 6px;
    letter-spacing: 0.5px;
}

.cm-menu-btn--back {
    background: var(--bg-secondary);
    border-color: var(--border);
    color: var(--text-muted);
    font-size: 18px;
}

.cm-menu-btn--back:hover {
    background: var(--bg-card);
    border-color: var(--border);
    color: var(--text-primary);
}

/* ── Cards ──────────────────────────────────────────────────── */

.cm-card {
    background: var(--bg-card);
    border: none;
    border-radius: var(--radius-lg);
    padding: 18px 20px;
    margin-bottom: 14px;
}

.cm-card__title {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 16px;
    padding-bottom: 10px;
}

/* ── Form Elements ──────────────────────────────────────────── */

.cm-form-row {
    display: flex;
    gap: 16px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.cm-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
    min-width: 120px;
}

.cm-field--fixed {
    flex: none;
}

.cm-label {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--text-label);
}

.cm-input,
.cm-select {
    height: var(--touch-target);
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-size: 20px;
    font-family: var(--font-mono);
    padding: 0 14px;
    width: 100%;
    transition: border-color 0.15s;
    appearance: none;
    -moz-appearance: textfield;
}

/* Textareas are multi-line, so they need real top/bottom padding — single-line
   inputs use a fixed height with vertically-centered text, which would otherwise
   pin a textarea's first line to the very top of the box. */
textarea.cm-input {
    height: auto;
    padding-top: 10px;
    padding-bottom: 10px;
    line-height: 1.45;
}

/* Remove number input spinners */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type="number"] {
    -moz-appearance: textfield;
}

.cm-input:focus,
.cm-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(74,159,200,0.2);
}

.cm-input::placeholder {
    color: var(--text-muted);
    font-size: 16px;
}

.cm-select {
    cursor: pointer;
    padding-right: 36px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%238a9099' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
}

select option {
    background: var(--bg-card);
    color: var(--text-primary);
}

.cm-input-group {
    display: flex;
    align-items: center;
    gap: 4px;
}

.cm-input-group .cm-input {
    flex: 1;
}

.cm-input-sep {
    font-size: 22px;
    color: var(--text-muted);
    font-weight: 700;
    padding: 0 2px;
    line-height: var(--touch-target);
}

.cm-unit-wrap { display: flex; align-items: center; gap: 6px; }

.cm-input-unit {
    font-size: 14px;
    color: var(--text-muted);
    white-space: nowrap;
    line-height: var(--touch-target);
    padding-left: 4px;
}

/* Single value + one trailing unit -> the unit is pinned INSIDE the input box,
   right-aligned and fixed (it stays put as the user types). Applies app-wide and
   is WRAPPER-AGNOSTIC (matches any container: cm-input-group, cm-flex-center,
   wx-inline, a plain div...). Multi-input groups (lat/lon deg-min, course+speed,
   time+ZD) are excluded by :only-of-type, so they keep their side-by-side layout;
   computed/no-input fields are excluded because there is no .cm-input to match. */
:has(> input:only-of-type) > .cm-input-unit:last-child {
    position: absolute;
    right: 11px;
    top: 50%;
    transform: translateY(-50%);
    padding-left: 0;
    font-size: 12px;
    font-family: var(--font-mono);
    pointer-events: none;
}
:has(> input:only-of-type):has(> .cm-input-unit:last-child) {
    position: relative;
}
:has(> input:only-of-type):has(> .cm-input-unit:last-child) > input {
    flex: 1 1 auto;      /* fill the wrapper so the absolute unit sits inside the box
                            even when a long label stretches the wrapper wider */
    padding-right: 44px;
    min-width: 96px;
}
:has(> input:only-of-type):has(> .cm-input-unit:last-child) > input[type="number"] {
    -moz-appearance: textfield;
}
:has(> input:only-of-type):has(> .cm-input-unit:last-child) > input::-webkit-outer-spin-button,
:has(> input:only-of-type):has(> .cm-input-unit:last-child) > input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.cm-field-help {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-top: 2px;
}

.cm-form-error {
    margin-bottom: 14px;
    padding: 12px 14px;
    border: 1px solid var(--danger);
    border-radius: var(--radius);
    background: rgba(212, 80, 80, 0.12);
    color: #ffd7d7;
    font-size: 14px;
    font-weight: 700;
}

.cm-input--invalid,
.cm-select.cm-input--invalid {
    border-color: var(--danger);
    box-shadow: 0 0 0 2px rgba(212, 80, 80, 0.18);
}

.hidden {
    display: none !important;
}

.cm-toggle-group {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 8px;
}

.cm-toggle-option {
    position: relative;
    display: inline-flex;
}

.cm-toggle-option input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.cm-toggle-option span {
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 18px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-input);
    color: var(--text-label);
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.cm-toggle-option input:checked + span {
    background: var(--accent-dark);
    border-color: var(--accent);
    color: #fff;
}

.cm-toggle-option input:focus + span {
    outline: none;
    box-shadow: 0 0 0 2px rgba(74,159,200,0.2);
}

.cm-tab-nav {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.cm-tab-btn {
    min-height: var(--touch-target);
    padding: 0 20px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card);
    color: var(--text-label);
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
}

.cm-tab-btn.is-active {
    background: var(--accent-dark);
    border-color: var(--accent);
    color: #fff;
}

.cm-tab-panel {
    display: none;
}

.cm-tab-panel.is-active {
    display: block;
}

/* ── Buttons ────────────────────────────────────────────────── */

.cm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--touch-target);
    padding: 0 28px;
    border: 2px solid var(--border); /* marketing button language: bordered pill */
    border-radius: 7px;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: 0.5px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
    text-decoration: none;
    /* bare .cm-btn (no variant) = marketing ghost; variants override below */
    background: var(--bg-card);
    color: var(--text-primary);
}

.cm-btn:not([class*="cm-btn--"]):hover {
    color: var(--accent);
    border-color: var(--accent);
}

.cm-btn--primary {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent-dark);
}

.cm-btn--primary:hover {
    background: var(--accent-light);
    color: #fff;
}

.cm-btn--success {
    background: var(--success);
    color: #fff;
    border-color: #2fa05a;
}

.cm-btn--success:hover {
    background: #4fcc7e;
    color: #fff;
}

.cm-btn--secondary {
    background: var(--bg-card);
    color: var(--text-primary);
    border-color: var(--border);
}

.cm-btn--secondary:hover {
    background: var(--bg-card);
    color: var(--accent);
    border-color: var(--accent);
}

.cm-btn--full {
    width: 100%;
}

/* size-only — pair with --primary/--secondary/--ghost for the color scheme */
.cm-btn--sm {
    height: auto;
    padding: 8px 18px;
    font-size: 13px;
}

.cm-btn--ghost {
    background: var(--bg-card);
    color: var(--text-primary);
    border-color: var(--border);
}

.cm-btn--ghost:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.cm-btn-row {
    display: flex;
    gap: 12px;
    margin-top: 20px;
    flex-wrap: wrap;
}

/* ── Result Block ───────────────────────────────────────────── */

.cm-result {
    background: var(--bg-result);
    border: 1px solid var(--border-accent);
    border-radius: var(--radius-lg);
    padding: 24px;
    margin-top: 24px;
}

.cm-result__title {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 20px;
}

.cm-result-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 16px;
}

.cm-result-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cm-result-item__label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--text-muted);
}

.cm-result-item__value {
    font-size: 24px;
    font-family: var(--font-mono);
    color: var(--text-result);
    font-weight: 700;
}

.cm-result-item__value--large {
    font-size: 32px;
}

.cm-result-item__value--toward {
    color: var(--success);
}

.cm-result-item__value--away {
    color: var(--danger);
}

.cm-result-divider {
    grid-column: 1 / -1;
    border: none;
    border-top: 1px solid var(--border);
    margin: 8px 0;
}

/* ── Worksheet Layout (traditional nav form style) ──────────── */

.cm-worksheet {
    font-family: var(--font-mono);
    font-size: 16px;
}

.cm-worksheet-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 6px 0;
    border-bottom: 1px solid rgba(58,63,72,0.5);
}

.cm-worksheet-row:last-child {
    border-bottom: none;
}

.cm-worksheet-row .ws-label {
    color: var(--text-muted);
    min-width: 220px;
    font-size: 14px;
}

.cm-worksheet-row .ws-value {
    color: var(--text-result);
    font-weight: 700;
    text-align: right;
    min-width: 120px;
}

.cm-worksheet-row--total .ws-label,
.cm-worksheet-row--total .ws-value {
    color: var(--text-primary);
    font-size: 18px;
}

.cm-worksheet-row--intercept .ws-value {
    font-size: 22px;
}

/* ── Status / Alert ─────────────────────────────────────────── */

.cm-alert {
    padding: 14px 18px;
    border-radius: var(--radius);
    font-size: 15px;
    margin-bottom: 16px;
    border-left: 4px solid;
}

.cm-alert--error {
    background: rgba(212,80,80,0.1);
    border-color: var(--danger);
    color: #f08080;
}

.cm-alert--success {
    background: rgba(61,186,106,0.1);
    border-color: var(--success);
    color: #7dd8a0;
}

.cm-alert--info {
    background: rgba(74,159,200,0.08);
    border-color: var(--accent);
    color: var(--accent);
}

/* ── Coming Soon ────────────────────────────────────────────── */

.cm-coming-soon {
    text-align: center;
    padding: 80px 20px;
    color: var(--text-muted);
}

.cm-coming-soon__icon {
    font-size: 48px;
    margin-bottom: 16px;
    display: block;
}

.cm-coming-soon__title {
    font-size: 28px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--text-label);
    margin-bottom: 8px;
}

.cm-coming-soon__sub {
    font-size: 15px;
    color: var(--text-muted);
}

/* ── Table ──────────────────────────────────────────────────── */

.cm-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15px;
}

.cm-table th {
    background: var(--bg-secondary);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
}

.cm-table td {
    padding: 9px 12px;
    border-bottom: 1px solid rgba(58,63,72,0.5);
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: 15px;
}

.cm-table tr:hover td,
.cm-table tr:active td {   /* :active = tap feedback where :hover never fires */
    background: rgba(74,159,200,0.05);
}

/* ── Reusable Tab Navigation ─────────────────────────────────── */

.cm-tab-nav {
    display: flex;
    gap: 0;
    margin-bottom: 24px;
    border-bottom: 2px solid var(--border);
}
.cm-tab-btn {
    padding: 10px 26px;
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    cursor: pointer;
    transition: color .2s, border-color .2s;
    margin-bottom: -2px;
    white-space: nowrap;
}
.cm-tab-btn:hover  { color: var(--text-primary); }
.cm-tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }

.cm-tab-panel         { display: none; }
.cm-tab-panel.active  { display: block; }

/* ── Form section headers (used across ship specs & weather) ──── */

.cm-section-hdr {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--accent);
    font-family: var(--font-mono);
    text-transform: uppercase;
    padding-bottom: 8px;
    margin-top: 22px;
    margin-bottom: 14px;
    border-bottom: 1px solid rgba(74,159,200,0.2);
}
.cm-section-hdr:first-child { margin-top: 0; }

/* ── Dynamic machinery / equipment rows ─────────────────────── */

.dyn-list { margin-bottom: 6px; }

.dyn-row {
    display: flex;
    gap: 10px;
    align-items: flex-end;
    flex-wrap: wrap;
    padding: 10px 12px;
    margin-bottom: 8px;
    background: var(--bg-raised);
    border: 1px solid var(--border);
    border-radius: 6px;
    position: relative;
}
.dyn-row-num {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--accent);
    min-width: 22px;
    padding-bottom: 8px;
    flex-shrink: 0;
    align-self: flex-end;
}
.dyn-remove {
    padding: 5px 9px;
    background: transparent;
    border: 1px solid rgba(200,70,70,0.3);
    border-radius: 4px;
    color: rgba(200,70,70,0.55);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: all .15s;
    flex-shrink: 0;
    align-self: flex-end;
    margin-bottom: 0;
    min-height: 0;
}
.dyn-remove:hover { border-color: #c84646; color: #e05050; background: rgba(200,70,70,0.1); }
.dyn-add-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: 100%;
    padding: 8px 14px;
    background: rgba(74,159,200,0.06);
    border: 1px dashed rgba(74,159,200,0.3);
    border-radius: 5px;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background .15s, border-color .15s;
    margin-top: 4px;
    min-height: 0;
}
.dyn-add-btn:hover { background: rgba(74,159,200,0.12); border-color: var(--accent); }

/* ── Footer ─────────────────────────────────────────────────── */

.cm-footer {
    background: var(--bg-secondary);
    border-top: 1px solid var(--border);
    padding: 10px 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.cm-footer .vessel-name {
    color: var(--text-label);
    font-weight: 700;
    letter-spacing: 1px;
}

/* ── Utility ────────────────────────────────────────────────── */

.hidden   { display: none !important; }
.text-mono{ font-family: var(--font-mono); }
.text-accent { color: var(--accent); }
.text-muted  { color: var(--text-muted); }
.text-nowrap { white-space: nowrap; }
.overflow-x-auto { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Wide-grid scroll wrapper: any grid too wide for the viewport (Work/Rest day
   grid, crew coverage grid) goes inside this so IT scrolls sideways, not the
   page. Pair with a min-width on the inner grid element. */
.cm-grid-scroll {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    border: 1px solid var(--border); border-radius: 10px;
    background: var(--bg-secondary);
}
.cm-flex-center { display: flex; gap: 8px; align-items: center; }
.cm-sub-label { font-weight: 400; font-size: 13px; color: var(--text-muted); margin-left: 8px; }
.lb-val { font-family: var(--font-mono); text-align: right; white-space: nowrap; }
.lb-mono-sm { font-family: var(--font-mono); font-size: 13px; white-space: nowrap; }
.lb-empty { color: var(--text-muted); font-style: italic; padding: 8px 0; }
.mb-0 { margin-bottom: 0; }
.mt-4 { margin-top: 16px; }
.mt-6 { margin-top: 24px; }

/* ── Scrollbar ──────────────────────────────────────────────── */

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg-primary); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ── Touchscreen adjustments ────────────────────────────────── */

@media (max-width: 900px) {
    .cm-wordmark { font-size: 56px; }
    .cm-menu-grid { grid-template-columns: repeat(2, 1fr); }
    .cm-body { padding: 20px 16px; }
    .cm-result-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
    .cm-wordmark { font-size: 44px; }
    .cm-menu-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
    .cm-menu-btn { font-size: 18px; min-height: 90px; }
    /* Phone: the title row (title + theme toggle + back/AI link) can exceed
       the viewport on long titles and push the whole page sideways — wrap. */
    .cm-page-title { flex-wrap: wrap; row-gap: 10px; font-size: 22px; }
    /* Tab strips scroll sideways instead of stretching the page; the
       buttons keep their full-size touch targets. */
    .cm-tab-nav { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .cm-tab-btn { padding: 10px 16px; }
}

/* ── Phone (iPhone SE / mini, 375px min width) ──────────────── */
/* Width-only guard: never matches the Pi 7" kiosk (800px wide) or
   its dedicated width+height query below. Tightens chrome so the
   narrowest supported phone viewport never scrolls sideways.      */

@media (max-width: 430px) {
    /* Smaller wordmark so it clears the absolutely-positioned version tag */
    .cm-wordmark-img  { height: calc(var(--header-height) * 0.30); }
    .cm-body          { padding: 16px 12px; }
    .cm-page-title    { font-size: 20px; }
    .cm-btn           { padding: 0 18px; font-size: 16px; }

    /* Long mono values (coordinates, station ids) stay inside their
       result column instead of pushing the grid past the viewport. */
    .cm-result-item__value          { font-size: 20px; overflow-wrap: anywhere; }
    .cm-result-item__value--large   { font-size: 26px; }

    /* Worksheet label/value pairs wrap rather than force overflow. */
    .cm-worksheet-row               { flex-wrap: wrap; }
    .cm-worksheet-row .ws-label     { min-width: 0; }
    .cm-worksheet-row .ws-value     { min-width: 0; }

    /* Footer: vessel name, clock, and system label stack cleanly. */
    .cm-footer { flex-wrap: wrap; justify-content: center; gap: 4px 14px; text-align: center; }
}

/* ── 7" Pi touchscreen (800×480) ────────────────────────────── */
/* Targets the Pi official display: tighten vertical rhythm so   */
/* form pages fit without scrolling.                             */

@media (max-width: 860px) and (max-height: 520px) {
    :root {
        --header-height:  52px;
        --touch-target:   44px;
        --button-min-h:   72px;
    }

    .cm-wordmark      { font-size: 38px; letter-spacing: -1px; }
    .cm-version       { font-size: 10px; }
    .cm-body          { padding: 10px 12px; }

    .cm-page-title    { font-size: 20px; padding-bottom: 10px; }
    .cm-back-link     { font-size: 12px; padding: 4px 10px; }

    .cm-card          { padding: 14px 16px; margin-bottom: 12px; }
    .cm-card__title   { font-size: 11px; margin-bottom: 10px; padding-bottom: 7px; }

    .cm-form-row      { gap: 10px; margin-bottom: 10px; }
    .cm-field         { gap: 4px; }
    .cm-label         { font-size: 10px; letter-spacing: 1px; }
    .cm-input,
    .cm-select        { font-size: 16px; padding: 0 10px; }
    .cm-input::placeholder { font-size: 13px; }

    .cm-field-help    { font-size: 12px; }
    .cm-alert         { padding: 10px 14px; font-size: 13px; }
    .cm-btn-row       { gap: 10px; margin-top: 12px; margin-bottom: 12px; }

    .cm-result        { padding: 16px; }
    .cm-result__title { font-size: 14px; padding-bottom: 12px; margin-bottom: 12px; }
    .cm-result-grid   { gap: 10px; grid-template-columns: repeat(2, 1fr); }
    .cm-result-item   { padding: 10px 12px; }
    .cm-result-item__value--large { font-size: 22px; }

    .cm-table th,
    .cm-table td      { padding: 8px 10px; font-size: 13px; }
}

/* ── TV / large display (75" at 1080p, etc.) ─────────────────── */
/* TO REVERT: delete from this comment down to the closing brace  */
@media (min-width: 1600px) {
    /* Large desktops: keep fonts generous but rein in the chrome — 2026-07-03
       density pass (old values made the layout only fit at 90% browser zoom). */
    :root {
        --header-height: 88px;
        --button-min-h:  118px;
        --touch-target:  64px;
    }

    html, body        { font-size: 18px; }

    .cm-wordmark      { font-size: 68px; letter-spacing: -1px; }
    .cm-version       { font-size: 14px; }

    .cm-body          { padding: 20px 32px; max-width: 1680px; }
    .cm-body--wide    { max-width: 1800px; }

    .cm-page-title    { font-size: 30px; padding-bottom: 12px; }
    .cm-back-link     { font-size: 15px; padding: 6px 14px; }

    .cm-card          { padding: 18px 22px; margin-bottom: 14px; }
    .cm-card__title   { font-size: 14px; margin-bottom: 12px; padding-bottom: 8px; }

    .cm-label         { font-size: 14px; letter-spacing: 1.5px; }
    .cm-input,
    .cm-select        { font-size: 18px; height: 46px; padding: 0 14px; }
    .cm-input::placeholder { font-size: 16px; }

    .cm-field-help    { font-size: 15px; }
    .cm-alert         { padding: 12px 16px; font-size: 16px; }
    .cm-btn-row       { gap: 14px; margin-top: 16px; margin-bottom: 16px; }

    .cm-btn           { font-size: 16px; padding: 12px 22px; min-height: 50px; }

    .cm-result        { padding: 18px; }
    .cm-result__title { font-size: 18px; padding-bottom: 12px; margin-bottom: 12px; }
    .cm-result-grid   { gap: 12px; }
    .cm-result-item   { padding: 12px 14px; }
    .cm-result-item__value--large { font-size: 34px; }

    .cm-table th,
    .cm-table td      { padding: 10px 14px; font-size: 15px; }

    .cm-menu-btn      { font-size: 26px; }
    .cm-menu-btn .btn-sub { font-size: 16px; }
    .cm-menu-section-label { font-size: 14px; }
}

/* ── Screenshot / export floating button (added to all pages via base.html) ── */
/* Screenshot / export — stationary button in the footer, left of the system label */
.cm-footer-end {
    display: inline-flex;
    align-items: center;
    gap: 12px;
}
.cm-export-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 24px;
    padding: 0;
    border-radius: 5px;
    background: transparent;
    border: 1px solid rgba(74,159,200,0.35);
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
.cm-export-btn:hover,
.cm-export-btn:active {
    border-color: var(--accent);
    color: var(--text-primary);
    background: rgba(74,159,200,0.12);
}
@media (pointer: coarse) {
    .cm-export-btn { width: 44px; height: 36px; }
}

/* ── Display mode toggle + dev package toggle (home.html) ─────────────── */
#cm-display-btn,
#cm-dev-pkg-btn {
    font-size: 11px;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: 4px;
    padding: 4px 10px;
    cursor: pointer;
    font-family: var(--font-mono);
    transition: color .15s, border-color .15s;
    white-space: nowrap;
}
#cm-display-btn { margin-left: 0; }
#cm-dev-pkg-btn { color: var(--accent); border-color: rgba(74,159,200,0.35); -webkit-appearance: none; appearance: none; }
#cm-display-btn:hover { color: var(--accent-warm); border-color: var(--accent-warm); }
#cm-dev-pkg-btn:hover { color: var(--accent-warm); border-color: var(--accent-warm); }
#cm-dev-pkg-btn option { background: var(--bg-card, #1a2030); color: var(--text-primary, #e8edf5); }

/* ── Body-class-driven display modes ──────────────────────────────────── */

/* Pi 7" mode — mirrors @media (max-width:860px and max-height:520px) */
body.cm-mode-pi {
    --header-height:  52px;
    --touch-target:   44px;
    --button-min-h:   72px;
}
body.cm-mode-pi .cm-wordmark      { font-size: 38px; letter-spacing: -1px; }
body.cm-mode-pi .cm-version       { font-size: 10px; }
body.cm-mode-pi .cm-body          { padding: 10px 12px; }
body.cm-mode-pi .cm-page-title    { font-size: 20px; padding-bottom: 10px; }
body.cm-mode-pi .cm-back-link     { font-size: 12px; padding: 4px 10px; }
body.cm-mode-pi .cm-card          { padding: 14px 16px; margin-bottom: 12px; }
body.cm-mode-pi .cm-card__title   { font-size: 11px; margin-bottom: 10px; padding-bottom: 7px; }
body.cm-mode-pi .cm-form-row      { gap: 10px; margin-bottom: 10px; }
body.cm-mode-pi .cm-label         { font-size: 10px; letter-spacing: 1px; }
body.cm-mode-pi .cm-input,
body.cm-mode-pi .cm-select        { font-size: 16px; padding: 0 10px; }
body.cm-mode-pi .cm-field-help    { font-size: 12px; }
body.cm-mode-pi .cm-btn-row       { gap: 10px; margin-top: 12px; margin-bottom: 12px; }
body.cm-mode-pi .cm-result        { padding: 16px; }
body.cm-mode-pi .cm-result__title { font-size: 14px; padding-bottom: 12px; margin-bottom: 12px; }
body.cm-mode-pi .cm-result-grid   { gap: 10px; grid-template-columns: repeat(2, 1fr); }
body.cm-mode-pi .cm-result-item   { padding: 10px 12px; }
body.cm-mode-pi .cm-result-item__value--large { font-size: 22px; }
body.cm-mode-pi .cm-table th,
body.cm-mode-pi .cm-table td      { padding: 8px 10px; font-size: 13px; }
body.cm-mode-pi .cm-menu-btn      { font-size: 18px; }
body.cm-mode-pi .cm-menu-btn .btn-sub { font-size: 12px; }

/* TV / large display mode — mirrors @media (min-width:1600px) */
body.cm-mode-tv {
    --header-height: 110px;
    --button-min-h:  150px;
    --touch-target:  70px;
    font-size: 20px;
}
body.cm-mode-tv .cm-wordmark      { font-size: 88px; letter-spacing: -1px; }
body.cm-mode-tv .cm-version       { font-size: 14px; }
body.cm-mode-tv .cm-body          { padding: 28px 40px; }
body.cm-mode-tv .cm-body--wide    { max-width: 1400px; }
body.cm-mode-tv .cm-page-title    { font-size: 36px; padding-bottom: 18px; }
body.cm-mode-tv .cm-back-link     { font-size: 15px; padding: 7px 16px; }
body.cm-mode-tv .cm-card          { padding: 24px 28px; margin-bottom: 20px; }
body.cm-mode-tv .cm-card__title   { font-size: 14px; margin-bottom: 14px; padding-bottom: 10px; }
body.cm-mode-tv .cm-label         { font-size: 13px; letter-spacing: 1.5px; }
body.cm-mode-tv .cm-input,
body.cm-mode-tv .cm-select        { font-size: 18px; height: 52px; padding: 0 16px; }
body.cm-mode-tv .cm-field-help    { font-size: 15px; }
body.cm-mode-tv .cm-btn-row       { gap: 16px; margin-top: 20px; margin-bottom: 20px; }
body.cm-mode-tv .cm-btn           { font-size: 16px; padding: 14px 24px; min-height: 54px; }
body.cm-mode-tv .cm-result        { padding: 24px; }
body.cm-mode-tv .cm-result__title { font-size: 18px; padding-bottom: 16px; margin-bottom: 16px; }
body.cm-mode-tv .cm-result-grid   { gap: 14px; }
body.cm-mode-tv .cm-result-item   { padding: 14px 16px; }
body.cm-mode-tv .cm-result-item__value--large { font-size: 36px; }
body.cm-mode-tv .cm-table th,
body.cm-mode-tv .cm-table td      { padding: 12px 16px; font-size: 15px; }
body.cm-mode-tv .cm-menu-btn      { font-size: 28px; }
body.cm-mode-tv .cm-menu-btn .btn-sub { font-size: 16px; }
body.cm-mode-tv .cm-menu-section-label { font-size: 13px; }

/* ════════════════════════════════════════════════════════════════════════════
   UI COMPONENTS (uiverse-derived, theme-matched) — shared across the app
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Segmented hemisphere toggle (N|S · E|W) — replaces native selects ─────── */
.cm-seg {
    position: relative; display: inline-flex; align-items: center;
    width: auto; min-width: 56px; height: 30px; flex: 0 0 auto; vertical-align: middle;
    border-radius: 15px; cursor: pointer; user-select: none; overflow: hidden;
    background: var(--bg-raised); border: 1px solid var(--border);
    -webkit-tap-highlight-color: transparent;
}
.cm-seg-opt {
    flex: 1 1 auto; text-align: center; z-index: 2; pointer-events: none; padding: 0 9px;
    font-family: var(--font-mono); font-size: 13px; font-weight: 700; line-height: 28px;
    white-space: nowrap; color: var(--text-muted); transition: color .2s;
}
.cm-seg .cm-seg-opt:first-of-type           { color: var(--accent); }
.cm-seg.cm-seg--b .cm-seg-opt:first-of-type { color: var(--text-muted); }
.cm-seg.cm-seg--b .cm-seg-opt:last-of-type  { color: var(--accent); }
.cm-seg-thumb {
    position: absolute; top: 2px; left: 2px; width: calc(50% - 3px); height: 24px; z-index: 1;
    border-radius: 13px; background: rgba(74,159,200,0.16); border: 1px solid var(--accent);
    transition: transform .22s cubic-bezier(.4,0,.2,1);
}
.cm-seg.cm-seg--b .cm-seg-thumb { transform: translateX(calc(100% + 2px)); }
.cm-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Tap dropdown — enhances a native <select> (kept hidden for submission) ── */
.cm-dd { position: relative; display: inline-block; vertical-align: middle; }
.cm-dd > select { display: none !important; }
.cm-dd-btn {
    display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 100%; min-width: 92px; cursor: pointer; font-family: inherit; font-size: 13px;
    background: var(--bg-raised); border: 1px solid var(--border);
    color: var(--text-primary); border-radius: 5px; padding: 6px 10px; text-align: left;
    transition: border-color .15s; -webkit-tap-highlight-color: transparent;
}
.cm-dd-btn:hover, .cm-dd-btn.open { border-color: var(--accent); }
.cm-dd-arrow { font-size: 10px; color: var(--text-muted); transition: transform .2s; }
.cm-dd-btn.open .cm-dd-arrow { transform: rotate(180deg); color: var(--accent); }
.cm-dd-list {
    position: absolute; top: calc(100% + 4px); left: 0; min-width: 100%; z-index: 9000;
    background: #1b2230; border: 1px solid var(--border); border-radius: 6px;
    padding: 4px; box-shadow: 0 10px 28px rgba(0,0,0,0.55);
    max-height: 264px; overflow-y: auto; display: none;
}
.cm-dd-list.open { display: block; }
.cm-dd-opt {
    padding: 7px 10px; border-radius: 4px; font-size: 13px; color: var(--text-primary);
    cursor: pointer; white-space: nowrap;
}
.cm-dd-opt:hover { background: rgba(74,159,200,0.18); }
.cm-dd-opt.sel  { background: rgba(74,159,200,0.28); color: #fff; }

/* ── Neon on/off switch (uiverse by preet_7613, recoloured for CHIEFMATE) ──── */
.cm-switch { display: block; position: relative; width: 80px; height: 48px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.cm-switch__base-outer {
    display: block; position: absolute; border-radius: 20px;
    box-shadow: -2px -2px 4px hsl(210,10%,28%), 2px 2px 2px hsl(210,10%,28%) inset,
                2px 2px 4px hsl(0,0%,0%), -2px -2px 2px hsl(210,10%,5%) inset;
    top: 2px; left: 2px; width: 76px; height: 44px;
}
.cm-switch__base-inner {
    display: block; position: absolute; border-radius: 18px;
    box-shadow: -3px -3px 4px hsl(210,10%,28%) inset, 1px 1px 2px hsla(210,10%,28%,1),
                2px 3px 4px hsl(210,10%,5%) inset, -1px -1px 2px hsla(210,10%,5%,1);
    top: 6px; left: 6px; width: 68px; height: 36px;
}
.cm-switch__base-neon { display: block; overflow: visible; position: absolute; top: 0; left: 0; width: 100%; height: auto; }
.cm-switch__base-neon path { stroke-dasharray: 0 104.26 0; transition: stroke-dasharray 0.6s cubic-bezier(0.65,0,0.35,1); }
.cm-switch__input { outline: transparent; position: relative; width: 100%; height: 100%; -webkit-appearance: none; appearance: none; cursor: pointer; }
.cm-switch__knob-container { border-radius: 16px; display: block; position: absolute; overflow: hidden; top: 8px; left: 8px; width: 64px; height: 32px; }
.cm-switch__knob {
    border-radius: 16px; display: block; position: absolute;
    background-color: hsl(210,10%,15%);
    background-image: radial-gradient(88% 88% at 50% 50%,hsl(210,10%,20%) 47%,hsla(210,10%,20%,0) 50%),
                      radial-gradient(88% 88% at 47% 47%,hsl(210,10%,80%) 45%,hsla(210,10%,80%,0) 50%),
                      radial-gradient(65% 70% at 40% 60%,hsl(210,10%,20%) 46%,hsla(210,10%,20%,0) 50%);
    box-shadow: -1px -1px 1px hsl(210,10%,15%) inset, -2px -2px 1px hsl(210,10%,5%) inset, 10px 3px 2px hsla(0,0%,0%,0.8);
    width: 32px; height: 32px; transition: transform 0.6s cubic-bezier(0.65,0,0.35,1);
}
.cm-switch__knob-shadow {
    border-radius: 50%; box-shadow: 2px 2px 2px hsla(0,0%,0%,0.9);
    display: block; position: absolute; top: 8px; left: 8px; width: 32px; height: 32px;
    transition: transform 0.6s cubic-bezier(0.65,0,0.35,1);
}
.cm-switch__led {
    background-color: hsl(3,90%,65%); border-radius: 50%;
    box-shadow: 0 -1px 1px hsl(3,90%,35%) inset, 0 0 2px hsla(3,90%,65%,0.3), 2px 2px 2px hsla(0,0%,0%,0.5);
    display: block; position: absolute; top: 2px; left: 2px; width: 5px; height: 5px;
    transition: background-color 0.6s cubic-bezier(0.65,0,0.35,1), box-shadow 0.6s cubic-bezier(0.65,0,0.35,1);
}
.cm-switch__text { overflow: hidden; position: absolute; width: 1px; height: 1px; }
.cm-switch__input:checked ~ .cm-switch__led {
    background-color: hsl(204,90%,60%);
    box-shadow: 0 -1px 1px hsl(204,90%,35%) inset, 0 -2px 2px hsla(204,90%,60%,0.3),
                0 2px 2px hsla(204,90%,60%,0.3), 2px 2px 2px hsla(0,0%,0%,0.5);
}
.cm-switch__input:checked ~ .cm-switch__base-neon path { stroke-dasharray: 52.13 0 52.13; }
.cm-switch__input:checked ~ .cm-switch__knob-shadow,
.cm-switch__input:checked ~ .cm-switch__knob-container .cm-switch__knob { transform: translateX(32px); }

/* ── Uiverse loader (.pl) — buffering / fetch spinner ─────────────────────── */
.pl { display: block; width: 9.375em; height: 9.375em; }
.pl__arrows,
.pl__ring-rotate,
.pl__ring-stroke,
.pl__tick { animation-duration: 2s; animation-timing-function: linear; animation-iteration-count: infinite; }
.pl__arrows { animation-name: arrows42; transform: rotate(45deg); transform-origin: 16px 52px; }
.pl__ring-rotate,
.pl__ring-stroke { transform-origin: 80px 80px; }
.pl__ring-rotate { animation-name: ringRotate42; }
.pl__ring-stroke { animation-name: ringStroke42; transform: rotate(-45deg); }
.pl__tick        { animation-name: tick42; }
.pl__tick:nth-child(2) { animation-delay: -1.75s; }
.pl__tick:nth-child(3) { animation-delay: -1.5s; }
.pl__tick:nth-child(4) { animation-delay: -1.25s; }
.pl__tick:nth-child(5) { animation-delay: -1s; }
.pl__tick:nth-child(6) { animation-delay: -0.75s; }
.pl__tick:nth-child(7) { animation-delay: -0.5s; }
.pl__tick:nth-child(8) { animation-delay: -0.25s; }
@keyframes arrows42 { from { transform: rotate(45deg); } to { transform: rotate(405deg); } }
@keyframes ringRotate42 { from { transform: rotate(0); } to { transform: rotate(720deg); } }
@keyframes ringStroke42 {
    from, to { stroke-dashoffset: 452; transform: rotate(-45deg); }
    50%       { stroke-dashoffset: 169.5; transform: rotate(-180deg); }
}
@keyframes tick42 {
    from, 3%, 47%, to { stroke-dashoffset: -12; }
    14%, 36%          { stroke-dashoffset: 0; }
}

/* ── Day / Night theme toggle ────────────────────────────────────────────── */
/* html paints the area outside the body box (zoom-out, overscroll) — must
   match the day background or a navy band appears past the page bottom */
html.cm-day {
    background-color: #f4efe0;
}

body.cm-day {
    --bg-primary:    #f4efe0;   /* aged nautical chart paper */
    --bg-secondary:  #ece6d2;
    --bg-card:       #f9f5eb;
    --bg-input:      #f9f5eb;
    --bg-result:     #f0ead8;
    --text-primary:  #5c4e38;
    --text-muted:    #5c4e38;
    --text-label:    #5c4e38;
    --text-result:   #2d5a8a;
    --border:        #c8b898;
    --border-accent: #4a9fc8;
    --bg-raised:     rgba(92,78,56,0.06);      /* day mode: brown tint so panels stay visible on paper */
    --accent:        #2d6fa8;
    --accent-dark:   #1a5080;
    --success:       #2e7d4f;
    --danger:        #b03a2e;

    /* Canvas surfaces — day: aged chart-paper background with dark ink so
       plotting/manboard/signals canvases stay readable on the light theme. */
    --canvas-bg:         #efe7d0;                 /* chart paper (slightly deeper than page bg for contrast) */
    --canvas-ink:        #3a3020;                 /* dark ink for marks/labels */
    --canvas-ink-faint:  rgba(58,48,32,0.60);     /* secondary canvas text */
    --canvas-ink-ghost:  rgba(58,48,32,0.32);     /* hint/placeholder canvas text */
    --canvas-grid:       rgba(45,111,168,0.24);   /* grid lines (accent, denser on paper) */
    --canvas-grid-text:  rgba(45,111,168,0.65);   /* grid labels */
}

/* Pin MATE colour so it stays the same regardless of theme */
body.cm-day .cm-wordmark .mate {
    color: #1a1d22;
}

/* Day mode: ensure all inputs/selects/textareas use readable text */
body.cm-day input,
body.cm-day select,
body.cm-day textarea {
    color: #5c4e38 !important;
    background-color: #f9f5eb !important;
    border-color: #c8b898 !important;
}
body.cm-day input::placeholder,
body.cm-day textarea::placeholder {
    color: #9a8a72 !important;
}

/* Uiverse sun/moon toggle switch — scaled down */
.switch {
    font-size: 17px; position: relative; display: inline-block;
    width: 48px; height: 26px; flex-shrink: 0;
}
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
    position: absolute; cursor: pointer;
    top: 0; left: 0; right: 0; bottom: 0;
    background-color: #73C0FC; transition: .4s; border-radius: 30px;
}
.slider:before {
    position: absolute; content: ""; height: 22px; width: 22px;
    border-radius: 20px; left: 2px; bottom: 2px; z-index: 2;
    background-color: #e8e8e8; transition: .4s;
}
.sun svg {
    position: absolute; top: 4px; left: 26px; z-index: 1; width: 18px; height: 18px;
    animation: rotate 15s linear infinite;
}
.moon svg {
    fill: #73C0FC; position: absolute; top: 4px; left: 4px; z-index: 1;
    width: 18px; height: 18px; animation: tilt 5s linear infinite;
}
@keyframes rotate { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes tilt {
    0%   { transform: rotate(0deg); }
    25%  { transform: rotate(-10deg); }
    75%  { transform: rotate(10deg); }
    100% { transform: rotate(0deg); }
}
.input:checked + .slider { background-color: #183153; }
.input:focus  + .slider  { box-shadow: 0 0 1px #183153; }
.input:checked + .slider:before { transform: translateX(22px); }
/* Full-screen overlay for page-level loading (optional) */
.cm-loader-overlay {
    position: fixed; inset: 0; z-index: 9999;
    background: rgba(10,15,22,0.82); backdrop-filter: blur(4px);
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
}
.cm-loader-overlay .cm-loader-label {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: 3px;
    text-transform: uppercase; color: var(--accent);
}
/* ── Expanding icon buttons (Charts + Weather toolbars) ──────────────────────
   Adapted from Uiverse (kennyotsu-monochromia). Collapsed: 36px icon square.
   Hover: expands to --xw and reveals the label (icon zone fixed 44px so long
   labels never clip — set --xw to label width + ~56px). */
.cxb {
    display: flex; align-items: center; justify-content: flex-start;
    width: 36px; height: 36px; padding: 0; flex-shrink: 0;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 5px;
    cursor: pointer; position: relative; overflow: hidden; text-decoration: none;
    transition: width .3s, border-color .15s, background .15s;
}
.cxb .sign {
    width: 100%; display: flex; align-items: center; justify-content: center;
    transition: width .3s, padding .3s;
}
.cxb .sign svg { width: 18px; height: 18px; color: var(--text-label); transition: color .15s; display: block; }
.cxb .text {
    position: absolute; right: 0; width: 0; opacity: 0; overflow: hidden;
    color: var(--text-label); font-size: 11px; font-weight: 700; letter-spacing: .5px;
    text-transform: uppercase; white-space: nowrap; transition: opacity .3s, width .3s;
}
.cxb:hover { width: var(--xw, 140px); border-color: var(--accent); background: rgba(74,159,200,.08); }
.cxb:hover .sign { width: 36px; padding-left: 8px; justify-content: flex-start; }
.cxb:hover .text { opacity: 1; width: calc(100% - 44px); padding-right: 8px; color: var(--accent); }
.cxb:hover .sign svg { color: var(--accent); }
.cxb.active { border-color: var(--accent); background: rgba(74,159,200,.15); }
.cxb.active .sign svg { color: var(--accent); }
.cxb:active { transform: translate(1px, 1px); }

/* Inline mini spinner (16 px, for buttons / small areas) */
.cm-spin {
    display: inline-block; width: 16px; height: 16px; border-radius: 50%;
    border: 2px solid rgba(74,159,200,0.25); border-top-color: var(--accent);
    animation: cmSpin 0.7s linear infinite; vertical-align: middle;
}
@keyframes cmSpin { to { transform: rotate(360deg); } }

/* Inline status dot — replaces colored circle emojis */
.status-dot {
    display: inline-block; width: 10px; height: 10px; border-radius: 50%;
    vertical-align: middle; margin-right: 4px; flex-shrink: 0;
}
@keyframes cm-pulse { 0%,100% { opacity:1; } 50% { opacity:0.4; } }

/* ── CMDatePicker component ───────────────────────────────────────────────── */
.cmdp-wrap { position: relative; display: inline-block; }
/* visible/typeable mode: text input stays on-screen, calendar icon sits beside it */
.cmdp-wrap--inline { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; }
.cmdp-icon-btn {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--touch-target); height: var(--touch-target);
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--accent);
    cursor: pointer;
    transition: border-color .15s;
}
.cmdp-icon-btn:hover,
.cmdp-icon-btn.cmdp-open { border-color: var(--accent); }
.cmdp-icon-btn svg { display: block; }

/* ── Unified date + time field (datetime_field macro) ─────────────────────── */
.cm-dt-field { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cm-dt-date  { width: 150px; }            /* fits MM/DD/YYYY at 20px mono */
.cm-dt-time  { width: 104px; text-align: center; }  /* fits HH:MM — no "15:3" */
.cm-dt-at    { color: var(--text-muted); padding: 0 2px; }
.cm-dt-now   { padding: 8px 16px; min-height: 0; font-size: 12px; }
.cmdp-trigger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: border-color .15s;
    white-space: nowrap;
    min-height: 38px;
}
.cmdp-trigger:hover { border-color: var(--accent); }
.cmdp-trigger.cmdp-open { border-color: var(--accent); }
.cmdp-trigger svg { flex-shrink: 0; color: var(--accent); }
.cmdp-trigger .cmdp-placeholder { color: var(--text-muted); }

.cmdp-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 9999;
    background: #12161e;
    border: 1px solid var(--accent);
    border-radius: 12px;
    padding: 16px;
    width: 290px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.55);
    display: none;
}
.cmdp-dropdown.cmdp-open { display: block; }

.cmdp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}
.cmdp-month-label {
    font-size: 15px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.5px;
}
.cmdp-nav {
    display: flex;
    gap: 6px;
}
.cmdp-nav-btn {
    width: 32px; height: 32px;
    border-radius: 8px;
    background: rgba(74,159,200,0.15);
    border: 1px solid rgba(74,159,200,0.35);
    color: var(--accent);
    font-size: 14px;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background .12s;
}
.cmdp-nav-btn:hover, .cmdp-nav-btn:active { background: rgba(74,159,200,0.28); }
@media (pointer: coarse) { .cmdp-nav-btn { width: 44px; height: 44px; } }

.cmdp-grid { width: 100%; border-collapse: collapse; }
.cmdp-grid th {
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
    color: #5a6070;
    padding: 0 0 8px;
}
.cmdp-grid td { padding: 3px; text-align: center; }
.cmdp-day {
    width: 34px; height: 34px;
    border-radius: 8px;
    background: #1e2330;
    border: none;
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background .1s;
    display: inline-flex; align-items: center; justify-content: center;
    width: 100%; box-sizing: border-box;
}
.cmdp-day:hover { background: rgba(74,159,200,0.22); }
.cmdp-day.cmdp-other { color: #3a4050; background: transparent; }
.cmdp-day.cmdp-today { outline: 1px solid rgba(74,159,200,0.4); }
.cmdp-day.cmdp-selected {
    background: rgba(74,159,200,0.18);
    border: 1.5px solid var(--accent);
    color: var(--accent);
    font-weight: 700;
}
@media (max-width: 860px) {
    .cmdp-dropdown { width: 260px; }
    .cmdp-day { font-size: 12px; height: 30px; }
}

/* ── Field-source help (cmWireFieldHelp) ──────────────────────────────── */
.cm-fieldhelp-lbl { cursor: pointer; }
.cm-fieldhelp-lbl:hover { color: var(--text-primary); }
.cm-fieldhelp-chev {
    display: inline-block; margin-right: 5px; font-size: 9px;
    color: var(--accent); transition: transform 0.15s;
}
.cm-fieldhelp-lbl.open .cm-fieldhelp-chev { transform: rotate(90deg); }
.cm-fieldhelp-box, .cm-fieldhelp-row td {
    background: rgba(74,159,200,0.05);
    border-left: 2px solid var(--accent);
    color: var(--text-muted);
    font-family: var(--font-main);
    font-size: 12.5px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.55;
    padding: 7px 12px;
    border-radius: 0 4px 4px 0;
}
.cm-fieldhelp-box { margin-top: 6px; }
.cm-fieldhelp-box strong, .cm-fieldhelp-row td strong { color: var(--text-primary); font-weight: 600; }

/* ── 3D press buttons ──────────────────────────────────────────────────────
   Same mechanic as the marketing site (adapted from Uiverse.io by Madflows,
   MIT): every action button is TWO layers — the face, and a ::before base
   layer sitting --press-depth below it with a ring outline and a soft drop
   shadow. Hover sinks the face 45% of the depth; :active bottoms it out.
   Knobs per class: --press-depth / --press-base / --press-ring /
   --press-ring-w (match the face's own border width).
   Faces must be OPAQUE (a translucent face shows the base through it).
   Tabs, segmented toggles, icon buttons, map controls and dashed add-rows
   stay flat by design. */
.cm-btn, .cm-menu-btn,
.stab-btn, .sy-btn, .sy-add-btn, .uscg-btn, .em-reset-btn,
.vp-btn, .vp-new-btn, .pm-btn, .dr-btn, .clv-btn, .lic-btn, .lw-btn, .su-btn,
.cc-print-btn, .adm-btn, .rvm-btn, .dl-btn, .upd-btn, .cancel-btn,
.wpt-footer-btn, .spec-btn, .ai-send-btn, .wr-btn, .rt-btn, .exp-btn,
.jn-btn, .df-btn, .flt-btn, .rq-btn, .radio-emergency-btn,
.cm-back-link {
    --press-depth: 0.28em;
    --press-base: #14171c;
    --press-ring: var(--border);
    --press-ring-w: 2px;
    position: relative;
    transform-style: preserve-3d;
    outline: none;
    transition: transform 150ms cubic-bezier(0, 0, 0.58, 1),
                background 150ms cubic-bezier(0, 0, 0.58, 1),
                color 150ms cubic-bezier(0, 0, 0.58, 1),
                border-color 150ms cubic-bezier(0, 0, 0.58, 1);
}
.cm-btn::before, .cm-menu-btn::before,
.stab-btn::before, .sy-btn::before, .sy-add-btn::before, .uscg-btn::before,
.em-reset-btn::before, .vp-btn::before, .vp-new-btn::before, .pm-btn::before,
.dr-btn::before, .clv-btn::before, .lic-btn::before, .lw-btn::before,
.su-btn::before, .cc-print-btn::before, .adm-btn::before, .rvm-btn::before,
.dl-btn::before, .upd-btn::before, .cancel-btn::before,
.wpt-footer-btn::before, .spec-btn::before, .ai-send-btn::before,
.wr-btn::before, .rt-btn::before, .exp-btn::before,
.jn-btn::before, .df-btn::before, .flt-btn::before, .rq-btn::before,
.cm-back-link::before, .radio-emergency-btn::before {
    position: absolute; content: ''; width: 100%; height: 100%;
    top: 0; left: 0; right: 0; bottom: 0; border-radius: inherit;
    background: var(--press-base);
    box-shadow: 0 0 0 var(--press-ring-w) var(--press-ring),
                0 0.35em 0.7em rgba(0, 0, 0, 0.45);
    transform: translate3d(0, var(--press-depth), -1em);
    transition: transform 150ms cubic-bezier(0, 0, 0.58, 1),
                box-shadow 150ms cubic-bezier(0, 0, 0.58, 1);
}
.cm-btn:hover, .cm-menu-btn:hover,
.stab-btn:hover, .sy-btn:hover, .sy-add-btn:hover, .uscg-btn:hover,
.em-reset-btn:hover, .vp-btn:hover, .vp-new-btn:hover, .pm-btn:hover,
.dr-btn:hover, .clv-btn:hover, .lic-btn:hover, .lw-btn:hover,
.su-btn:hover, .cc-print-btn:hover, .adm-btn:hover, .rvm-btn:hover,
.dl-btn:hover, .upd-btn:hover, .cancel-btn:hover,
.wpt-footer-btn:hover, .spec-btn:hover, .ai-send-btn:hover,
.wr-btn:hover, .rt-btn:hover, .exp-btn:hover,
.jn-btn:hover, .df-btn:hover, .flt-btn:hover, .rq-btn:hover,
.cm-back-link:hover,
.radio-emergency-btn:hover {
    transform: translate(0, calc(var(--press-depth) * 0.45));
}
.cm-btn:hover::before, .cm-menu-btn:hover::before,
.stab-btn:hover::before, .sy-btn:hover::before, .sy-add-btn:hover::before,
.uscg-btn:hover::before, .em-reset-btn:hover::before, .vp-btn:hover::before,
.vp-new-btn:hover::before, .pm-btn:hover::before, .dr-btn:hover::before,
.clv-btn:hover::before, .lic-btn:hover::before, .lw-btn:hover::before,
.su-btn:hover::before, .cc-print-btn:hover::before, .adm-btn:hover::before,
.rvm-btn:hover::before, .dl-btn:hover::before, .upd-btn:hover::before,
.cancel-btn:hover::before, .wpt-footer-btn:hover::before,
.spec-btn:hover::before, .ai-send-btn:hover::before, .wr-btn:hover::before,
.rt-btn:hover::before, .exp-btn:hover::before, .jn-btn:hover::before,
.df-btn:hover::before, .flt-btn:hover::before, .rq-btn:hover::before,
.cm-back-link:hover::before, .radio-emergency-btn:hover::before {
    transform: translate3d(0, calc(var(--press-depth) * 0.55), -1em);
}
.cm-btn:active, .cm-menu-btn:active,
.stab-btn:active, .sy-btn:active, .sy-add-btn:active, .uscg-btn:active,
.em-reset-btn:active, .vp-btn:active, .vp-new-btn:active, .pm-btn:active,
.dr-btn:active, .clv-btn:active, .lic-btn:active, .lw-btn:active,
.su-btn:active, .cc-print-btn:active, .adm-btn:active, .rvm-btn:active,
.dl-btn:active, .upd-btn:active, .cancel-btn:active,
.wpt-footer-btn:active, .spec-btn:active, .ai-send-btn:active,
.wr-btn:active, .rt-btn:active, .exp-btn:active,
.jn-btn:active, .df-btn:active, .flt-btn:active, .rq-btn:active,
.cm-back-link:active, .radio-emergency-btn:active {
    transform: translate(0, var(--press-depth));
}
.cm-btn:active::before, .cm-menu-btn:active::before,
.stab-btn:active::before, .sy-btn:active::before, .sy-add-btn:active::before,
.uscg-btn:active::before, .em-reset-btn:active::before, .vp-btn:active::before,
.vp-new-btn:active::before, .pm-btn:active::before, .dr-btn:active::before,
.clv-btn:active::before, .lic-btn:active::before, .lw-btn:active::before,
.su-btn:active::before, .cc-print-btn:active::before, .adm-btn:active::before,
.rvm-btn:active::before, .dl-btn:active::before, .upd-btn:active::before,
.cancel-btn:active::before, .wpt-footer-btn:active::before,
.spec-btn:active::before, .ai-send-btn:active::before, .wr-btn:active::before,
.rt-btn:active::before, .exp-btn:active::before, .jn-btn:active::before,
.df-btn:active::before, .flt-btn:active::before, .rq-btn:active::before,
.cm-back-link:active::before, .radio-emergency-btn:active::before {
    transform: translate3d(0, 0, -1em);
    box-shadow: 0 0 0 var(--press-ring-w) var(--press-ring),
                0 0.05em 0.25em rgba(0, 0, 0, 0.4);
}

/* Press knobs per face style: the base/ring under an accent-filled face is
   accent-dark (marketing primary); card-faced ghosts keep the near-black
   base and take their ring from the face border. */
.cm-btn--primary { --press-base: var(--accent-dark); --press-ring: var(--accent-dark); }
.cm-btn--success { --press-base: #2fa05a; --press-ring: #2fa05a; }
.cm-btn--secondary { --press-base: #14171c; --press-ring: var(--border); }
.cm-btn--secondary:hover { --press-ring: var(--accent); }
.cm-btn:not([class*="cm-btn--"]):hover { --press-ring: var(--accent); }
.cm-btn--ghost { --press-base: #14171c; --press-ring: var(--border); }
.cm-btn--ghost:hover { --press-ring: var(--accent); }
.cm-menu-btn:hover { --press-ring: var(--accent); }

/* ── Print: paper is white ─────────────────────────────────────────────────
   Every print path (crewing calendar, USCG checklist, voyage plan, any
   window.print) must come out as dark text on a white page — never the
   night theme, never dark ink-heavy tiles. The whole app paints from the
   variables above, so re-pointing them to a light palette flips every
   module at once; the rules after the variables catch hard-coded darks,
   the press-button base layers, and screen chrome. */
@media print {
    :root {
        --bg-primary:   #ffffff;
        --bg-secondary: #ffffff;
        --bg-card:      #ffffff;
        --bg-input:     #ffffff;
        --bg-raised:    transparent;
        --text-primary: #000000;
        --text-muted:   #444444;
        --text-secondary: #444444;
        --text-label:   #333333;
        --text-result:  #000000;
        --border:       #999999;
        --border-accent:#666666;
        --accent:       #1d5e80;   /* darker steel blue — readable on white */
        --accent-dark:  #1d5e80;
        --accent-light: #1d5e80;
        --accent-warm:  #8a6516;
        --canvas-bg:        #ffffff;
        --canvas-ink:       #000000;
        --canvas-ink-faint: rgba(0,0,0,0.55);
        --canvas-ink-ghost: rgba(0,0,0,0.25);
        --canvas-grid:      rgba(0,0,0,0.15);
        --canvas-grid-text: rgba(0,0,0,0.45);
    }
    html, body {
        background: #fff !important;
        color: #000 !important;
    }
    * {
        box-shadow: none !important;
        text-shadow: none !important;
    }
    /* flatten the 3D press buttons — no base slabs of ink */
    .cm-btn::before, .cm-menu-btn::before,
    .stab-btn::before, .sy-btn::before, .sy-add-btn::before, .uscg-btn::before,
    .em-reset-btn::before, .vp-btn::before, .vp-new-btn::before, .pm-btn::before,
    .dr-btn::before, .clv-btn::before, .lic-btn::before, .lw-btn::before,
    .su-btn::before, .cc-print-btn::before, .adm-btn::before, .rvm-btn::before,
    .dl-btn::before, .upd-btn::before, .cancel-btn::before,
    .wpt-footer-btn::before, .spec-btn::before, .ai-send-btn::before,
    .wr-btn::before, .rt-btn::before, .exp-btn::before,
    .jn-btn::before, .df-btn::before, .flt-btn::before, .rq-btn::before,
    .radio-emergency-btn::before {
        display: none !important;
    }
    /* screen chrome never prints */
    header, footer, nav, .cm-back-link { display: none !important; }
}

/* iOS app only: the footer link back to the on-device offline tools. */
.cm-offline-link { color: var(--accent); text-decoration: none; margin-right: 12px; font-family: var(--font-mono); font-size: 12px; letter-spacing: 1px; text-transform: uppercase; }
.cm-offline-link:hover { text-decoration: underline; }

/* ── iOS app chrome ─────────────────────────────────────────── */
/* Safe areas on both apps. iOS WKWebView and new Android WebViews resolve
   env(); Capacitor 8 on an older Android WebView injects the same values as
   --safe-area-inset-* custom properties instead. Take the larger of the two. */
:root {
    --cm-safe-top: max(env(safe-area-inset-top, 0px), var(--safe-area-inset-top, 0px));
    --cm-safe-bottom: max(env(safe-area-inset-bottom, 0px), var(--safe-area-inset-bottom, 0px));
}

/* Rendered only when config.is_app_request() is true, the WebView of the
   CHIEFMATE iOS or Android app. A compact sticky header, a fixed
   bottom tab bar, the phone home rows and the app sign in screen. The
   module pages under it are the same templates the desktop renders, so
   nothing else changes when this block is active. */

body.cm-app { padding-bottom: calc(64px + var(--cm-safe-bottom)); }
body.cm-app .cm-page { min-height: auto; }

.app-header {
    position: sticky; top: 0; z-index: 50;
    display: grid; grid-template-columns: 56px 1fr auto; align-items: center;
    min-height: 52px;
    padding-top: var(--cm-safe-top);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
}
.app-header__back {
    display: flex; align-items: center; justify-content: center;
    width: 56px; height: 52px; color: var(--accent); text-decoration: none;
}
.app-header__back svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.app-header__brand { display: flex; align-items: center; height: 52px; padding-left: 14px; }
.app-header__brand img { height: 22px; width: auto; display: block; }
.app-header--home { grid-template-columns: 1fr auto; }
/* In the app the sticky header already carries the page title, so the in-page
   title row keeps only its links (back link, hub link) as a slim right-aligned
   row. The desktop and phone browsers keep the full title row. */
body.cm-app .cm-page-title > span:first-child { display: none; }
body.cm-app .cm-page-title { border-bottom: 0; padding-bottom: 0; margin-bottom: 12px; min-height: 0; }
body.cm-app .cm-page-title .cm-back-link { min-height: 40px; }
.app-header__title {
    text-align: center; font-size: 15px; font-weight: 700; letter-spacing: 0.5px;
    text-transform: uppercase; color: var(--text-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 4px;
}
.app-header__clock {
    font-family: var(--font-mono); font-size: 12px; color: var(--text-muted);
    padding: 0 14px 0 6px; white-space: nowrap;
}

.app-tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    display: grid; grid-template-columns: repeat(5, 1fr);
    background: var(--bg-secondary); border-top: 1px solid var(--border);
    padding-bottom: var(--cm-safe-bottom);
}
.app-tab {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; height: 60px; color: var(--text-muted); text-decoration: none;
    font-size: 11px; font-weight: 600; letter-spacing: 0.3px;
}
.app-tab svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.app-tab.is-active { color: var(--accent); }

.app-home__vessel { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 2px 4px 16px; }
.app-home__vessel .name { font-weight: 700; letter-spacing: 1px; font-size: 15px; color: var(--text-label); text-transform: uppercase; }
.app-home__vessel .plan { font-size: 12px; color: var(--text-muted); white-space: nowrap; }

.app-group { margin-bottom: 22px; }
.app-group__label { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--text-muted); margin: 0 0 8px 4px; }
.app-group__note { font-size: 12.5px; color: var(--text-muted); margin: -4px 0 8px 4px; }
.app-rows {
    display: flex; flex-direction: column;
    border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
    background: var(--bg-card);
}
.app-row {
    display: grid; grid-template-columns: 44px 1fr 20px; align-items: center; gap: 12px;
    min-height: 64px; padding: 10px 14px;
    color: var(--text-primary); text-decoration: none;
    border-bottom: 1px solid var(--border);
    background: none; border-left: 0; border-right: 0; border-top: 0;
    width: 100%; text-align: left; font: inherit; cursor: pointer;
}
.app-row:last-child { border-bottom: 0; }
.app-row:active { background: var(--bg-raised); }
.app-row__icon {
    width: 44px; height: 44px; border-radius: 10px;
    background: rgba(74,159,200,0.14); color: var(--accent);
    display: flex; align-items: center; justify-content: center;
}
.app-row__icon svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.app-row__name { font-size: 16px; font-weight: 700; line-height: 1.2; }
.app-row__sub { font-size: 12.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.3; }
.app-row__chev { color: var(--text-muted); display: flex; }
.app-row__chev svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.app-row--desk .app-row__icon { background: rgba(212,152,42,0.14); color: var(--accent-warm); }
.app-row--danger .app-row__icon { background: rgba(212,80,80,0.14); color: var(--danger); }
.app-row--danger .app-row__name { color: var(--danger); }

.app-banner {
    background: rgba(212,152,42,0.10); border: 1px solid rgba(212,152,42,0.4);
    border-radius: 10px; padding: 14px 16px; margin-bottom: 18px;
    display: flex; flex-direction: column; gap: 12px; font-size: 14px; color: var(--text-primary);
}
.app-banner a {
    display: block; text-align: center; min-height: 48px; line-height: 48px;
    background: var(--accent); color: #fff; border-radius: 8px; font-weight: 700;
    font-size: 14px; text-decoration: none;
}

/* The sign in, forgot and reset screens inside the app (templates/app/shell.html). */
.app-shell {
    min-height: 100vh; display: flex; flex-direction: column;
    background: var(--bg-primary); color: var(--text-primary);
    padding: calc(20px + var(--cm-safe-top)) 22px calc(20px + var(--cm-safe-bottom));
}
.app-shell__brand { text-align: center; padding: 36px 0 26px; }
.app-shell__brand img { height: 30px; width: auto; }
.app-shell__brand .tag { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--text-muted); margin-top: 10px; }
.app-auth .auth-wrap, .app-auth .auth-card { padding: 0; margin: 0; max-width: none; background: none; border: 0; }
.app-auth h1 { font-size: 24px; margin-bottom: 4px; }
.app-auth .auth-sub { font-size: 14px; color: var(--text-muted); margin-bottom: 22px; }
.app-auth .field { margin-bottom: 14px; }
.app-auth .field label { display: block; font-size: 12px; letter-spacing: 1px; text-transform: uppercase; color: var(--text-label); margin-bottom: 6px; }
.app-auth .field input {
    width: 100%; min-height: 52px; padding: 12px 14px; font-size: 16px;
    background: var(--bg-input); color: var(--text-primary);
    border: 1px solid var(--border); border-radius: 10px; -webkit-appearance: none;
}
.app-auth .field input:focus { outline: none; border-color: var(--accent); }
.app-auth .field-hint { font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.app-auth .pw-wrap { position: relative; display: flex; align-items: center; }
.app-auth .pw-wrap input { padding-right: 48px; flex: 1; }
.app-auth .pw-eye {
    position: absolute; right: 4px; width: 44px; height: 44px;
    background: none; border: 0; color: var(--text-muted);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.app-auth .pw-eye svg { width: 20px; height: 20px; }
.app-auth .checkbox-row { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--text-label); margin: 4px 0 18px; }
.app-auth .checkbox-row input { width: 20px; height: 20px; accent-color: var(--accent); }
.app-auth .btn-block {
    display: block; width: 100%; min-height: 56px; border: 0; border-radius: 10px;
    background: var(--accent); color: #fff; font-size: 17px; font-weight: 700;
    letter-spacing: 0.5px; cursor: pointer;
}
.app-auth .btn-block:disabled { opacity: 0.7; }
.app-auth .auth-alt { text-align: center; font-size: 14px; color: var(--text-muted); margin-top: 18px; }
.app-auth .auth-alt a { color: var(--accent); }
.app-auth .flash { padding: 11px 14px; border-radius: 8px; font-size: 14px; margin-bottom: 16px; }
.app-auth .flash.error { background: rgba(212,80,80,0.12); border: 1px solid rgba(212,80,80,0.4); color: #f0a0a0; }
.app-auth .flash.ok { background: rgba(61,186,106,0.12); border: 1px solid rgba(61,186,106,0.4); color: #8fe0ac; }
.app-shell__foot { margin-top: auto; text-align: center; font-size: 12px; color: var(--text-muted); padding-top: 28px; line-height: 1.8; }
.app-shell__foot a { color: var(--text-muted); }

/* ── Phone patterns shared by the module pages ──────────────── */
/* .cm-grid-2: a two column layout that drops to one column on a phone.
   .cm-table-cards: a table whose rows become stacked cards under 480 px;
   chiefmate.js stamps each cell with its column header as data-label. */
.cm-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 480px) {
    .cm-grid-2 { grid-template-columns: 1fr; gap: 14px; }
    .cm-table-cards thead { display: none; }
    .cm-table-cards, .cm-table-cards tbody, .cm-table-cards tr { display: block; width: 100%; }
    .cm-table-cards tr {
        background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
        padding: 6px 12px; margin-bottom: 10px;
    }
    .cm-table-cards tr:hover td, .cm-table-cards tr:active td { background: none; }
    .cm-table-cards td {
        display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
        padding: 7px 0; border-bottom: 1px solid rgba(58,63,72,0.5); text-align: right;
        font-size: 14px;
    }
    .cm-table-cards td:last-child { border-bottom: 0; }
    .cm-table-cards td:empty { display: none; }
    .cm-table-cards td::before {
        content: attr(data-label); font-family: var(--font-main); font-size: 11px;
        letter-spacing: 1px; text-transform: uppercase; color: var(--text-muted);
        text-align: left; flex-shrink: 0;
    }
}

/* Phone datetime field (every page that uses the datetime_field macro):
   the Now stamp comes first and full width, the date and time inputs
   share the row below it, and the "@" separator goes. */
@media (max-width: 480px) {
    .cm-dt-field { gap: 8px; }
    .cm-dt-field .cm-dt-now:not(.cm-dt-tz) { order: -1; flex: 1 1 100%; min-height: 44px; font-size: 13px; }
    .cm-dt-field .cm-dt-at { display: none; }
    .cm-dt-field .cm-dt-tz { min-height: 40px; }
    /* Enhanced selects copy the select's inline width as a minimum; on a
       phone they must never push past their container. */
    .cm-dd { max-width: 100%; }
    .cm-dd-btn { min-width: 0 !important; max-width: 100%; }
}

/* Phone tab strip: every page on .cm-tab-nav gets one row of 44 px tabs
   that scrolls sideways and sticks under the app header. */
@media (max-width: 480px) {
    .cm-tab-nav {
        position: sticky; top: 0; z-index: 20; background: var(--bg-primary);
        flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
        gap: 6px; padding: 6px 0 8px; margin-bottom: 14px; border-bottom: 0;
    }
    body.cm-app .cm-tab-nav { top: 52px; }
    .cm-tab-nav::-webkit-scrollbar { display: none; }
    .cm-tab-btn {
        flex: 0 0 auto; min-height: 44px; height: 44px; padding: 0 14px;
        font-size: 12px; letter-spacing: 1px; border-radius: 22px; margin-bottom: 0;
        border: 1px solid var(--border); background: var(--bg-card); color: var(--text-muted);
    }
    .cm-tab-btn.active, .cm-tab-btn.is-active { color: var(--accent); border-color: var(--accent); background: rgba(74,159,200,0.12); }
}

/* The desk tools' one line note on a phone in the app (base.html renders it
   for the stability, charts, voyage, engineering, towing and study paths). */
.app-desk-note { display: none; }
@media (max-width: 480px) {
    body.cm-app .app-desk-note {
        display: block; padding: 8px 14px; font-size: 12.5px; text-align: center;
        color: var(--accent-warm); background: rgba(212,152,42,0.10);
        border-bottom: 1px solid rgba(212,152,42,0.35);
    }
}
