/* PPU Bench: the Signal Code world, v3.
   Flag cloth primaries on bunting white. Blue owns the top bar, yellow is caution and injected
   faults, red is invalid and this vessel. Sentence flags appear only in sentence cells and the
   hoist. Flat colour fields; depth is shadow (ink-tinted on light, an edge plus dark shadow on
   dusk), never glass, glow or gradient.

   Two themes from one set of tokens, via light-dark(). Dark is "Bridge dusk", after the IHO S-52
   DUSK table: chrome never emits more light than the chart.

   One aesthetic risk: Barlow Semi Condensed (a DIN-like signage face) for instrument readouts. */

@layer reset, tokens, base, shell, panels, chart, drawer, editor, phone;

@font-face { font-family: "Barlow Semi Condensed"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/vendor/fonts/barlow-semi-condensed-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Barlow Semi Condensed"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/vendor/fonts/barlow-semi-condensed-latin-700-normal.woff2") format("woff2"); }

@layer reset {
  *, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  body, h1, h2, h3, h4, p, ul, ol, dl, dd { margin: 0; }
  ul, ol { padding: 0; }
  button, input, select { font: inherit; color: inherit; }
  dialog, [popover] { padding: 0; border: 0; color: inherit; }
}

@layer tokens {
  :root {
    color-scheme: light dark;
    /* primaries */
    --bar:        light-dark(oklch(0.386 0.148 261), oklch(0.245 0.062 261));
    --on-bar:     light-dark(oklch(1 0 0), oklch(0.93 0.012 250));
    --blue:       light-dark(oklch(0.386 0.148 261), oklch(0.470 0.120 260));
    --blue-ink:   light-dark(oklch(0.386 0.148 261), oklch(0.760 0.095 255));
    --yellow:     light-dark(oklch(0.857 0.165 87),  oklch(0.800 0.135 85));
    --red:        light-dark(oklch(0.530 0.207 22),  oklch(0.660 0.175 22));
    /* surfaces: chart < panel < raised */
    --ground:     light-dark(oklch(0.963 0.005 258), oklch(0.150 0.010 222));
    --panel:      light-dark(oklch(1 0 0),           oklch(0.182 0.011 222));
    --raised:     light-dark(oklch(1 0 0),           oklch(0.228 0.012 222));
    --well:       light-dark(oklch(0.967 0.005 258), oklch(0.152 0.010 222));
    --hover:      light-dark(oklch(0.19 0.007 258 / .045), oklch(1 0 0 / .05));
    --water:      light-dark(oklch(0.926 0.019 248), oklch(0.150 0.014 225));
    /* ink */
    --ink:        light-dark(oklch(0.190 0.007 258), oklch(0.880 0.010 215));
    --ink-2:      light-dark(oklch(0.426 0.015 260), oklch(0.740 0.012 215));
    --ink-3:      light-dark(oklch(0.541 0.017 251), oklch(0.630 0.013 215));
    --on-ink:     light-dark(oklch(1 0 0),           oklch(0.170 0.010 222));
    --line:       light-dark(oklch(0.909 0.010 262), oklch(0.292 0.011 220));
    --line-2:     light-dark(oklch(0.945 0.006 255), oklch(0.245 0.010 220));
    /* state tints, each meaning one thing */
    --ok:         light-dark(oklch(0.513 0.118 154), oklch(0.720 0.115 155));
    --ok-soft:    light-dark(oklch(0.945 0.019 158), oklch(0.290 0.045 155));
    --ok-ink:     light-dark(oklch(0.415 0.094 154), oklch(0.820 0.095 155));
    --caution-soft: light-dark(oklch(0.970 0.042 92), oklch(0.295 0.045 85));
    --caution-ink:  light-dark(oklch(0.439 0.090 82), oklch(0.860 0.095 88));
    --doubt-ring: light-dark(oklch(0.780 0.149 87),  oklch(0.700 0.120 87));
    --invalid:    var(--red);
    --invalid-soft: light-dark(oklch(0.945 0.022 7), oklch(0.290 0.060 20));
    --warning:    light-dark(oklch(0.684 0.185 45),  oklch(0.710 0.150 48));
    --warning-soft: light-dark(oklch(0.952 0.029 57), oklch(0.295 0.050 50));
    --sel-soft:   light-dark(oklch(0.945 0.016 263), oklch(0.300 0.045 258));
    --link-live:  oklch(0.723 0.170 154);
    --link-idle:  oklch(0.660 0.022 257);
    --scrollbar:  light-dark(oklch(0.83 0.012 258), oklch(0.36 0.012 220));
    --scrim:      light-dark(oklch(0.19 0.007 258 / .22), oklch(0.05 0.01 222 / .5));

    /* elevation: ink-tinted shadows on light; on dusk a 1 px edge carries the shape */
    --edge:   transparent;
    --elev-1: 0 1px 2px oklch(0.19 0.007 258 / .07);
    --elev-2: 0 2px 8px oklch(0.19 0.007 258 / .12);
    --elev-3: 0 8px 24px oklch(0.19 0.007 258 / .18);
    --elev-4: 0 24px 48px oklch(0.19 0.007 258 / .28);

    --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    --instr: "Barlow Semi Condensed", "DIN Alternate", var(--font);
    --ease: cubic-bezier(.16, 1, .3, 1);

    /* the 8 px grid; controls are 32 px, 44 px under a finger */
    --ctl: 32px;
    --chip: 28px;
    --bar-h: 52px;
  }
  @media (pointer: coarse) { :root { --ctl: 44px; --chip: 36px; --bar-h: 60px; } .mitem kbd { display: none; } }

  /* Dusk depth: no blur, no glow. An edge, plus a dark shadow from elev-2 up. */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --edge: oklch(0.320 0.012 220);
      --elev-1: 0 0 0 transparent;
      --elev-2: 0 2px 8px oklch(0 0 0 / .4);
      --elev-3: 0 8px 24px oklch(0 0 0 / .5);
      --elev-4: 0 24px 48px oklch(0 0 0 / .6);
    }
  }
  :root[data-theme="dark"] {
    --edge: oklch(0.320 0.012 220);
    --elev-1: 0 0 0 transparent;
    --elev-2: 0 2px 8px oklch(0 0 0 / .4);
    --elev-3: 0 8px 24px oklch(0 0 0 / .5);
    --elev-4: 0 24px 48px oklch(0 0 0 / .6);
  }
  :root[data-theme="light"] { color-scheme: light; }
  :root[data-theme="dark"]  { color-scheme: dark; }
}

@layer base {
  html, body { height: 100%; }
  body {
    font: 13px/1.4 var(--font); color: var(--ink); background: var(--ground);
    font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased; overflow: hidden;
  }
  html, body { overscroll-behavior: none; }   /* no pull-to-refresh or rubber-band on the shell */
  /* biome-ignore lint/suspicious/noDuplicateProperties: 100% is the fallback where dvh is unknown */ .app { height: 100%; height: 100dvh; display: grid; grid-template-rows: var(--bar-h) minmax(0, 1fr) auto; grid-template-columns: minmax(0, 1fr); }
  ::selection { background: var(--blue); color: #fff; }

  /* Focus: a ring for the keyboard only. */
  :focus { outline: none; }
  :focus-visible { outline: 2px solid var(--blue-ink); outline-offset: 2px; }
  html[data-input="pointer"] :focus-visible { outline: none; }

  input { caret-color: var(--red); accent-color: var(--blue); }
  * { scrollbar-width: thin; scrollbar-color: var(--scrollbar) transparent; }
  /* With a mouse, macOS and Windows draw scrollbars that take width: reserve that strip on every
     scrolling panel so opening an accordion that overflows does not push the content sideways.
     Where scrollbars overlay (touch, trackpad-only Macs) the gutter is zero. */
  .sheet-b, .pane, .ed-body, .stream, [popover].pop { scrollbar-gutter: stable; }
  .sheet-b { scrollbar-gutter: stable both-edges; }
  /* Side panels: no native scrollbar at all, a thumb drawn over the content (flags.js overlay). */
  .side-body { scrollbar-gutter: auto; scrollbar-width: none; }
  .side-body::-webkit-scrollbar { display: none; }
  .ovs-thumb { position: absolute; top: 0; right: 3px; z-index: 4; width: 6px; border-radius: 3px; background: var(--scrollbar);
               opacity: 0; pointer-events: none; transition: opacity .35s var(--ease), width .15s var(--ease), right .15s var(--ease); }
  .ovs-thumb.can.on, .side:hover > .ovs-thumb.can { opacity: 1; pointer-events: auto; }
  .ovs-thumb:hover, .ovs-thumb.drag { width: 9px; right: 2px; background: color-mix(in oklch, var(--scrollbar), var(--ink) 25%); }
  .num { font-variant-numeric: tabular-nums; }
  .ro { font-family: var(--instr); font-weight: 600; letter-spacing: .01em; }
  .mono { font-family: var(--mono); font-size: 12px; }
  .small { font-size: 12px; }
  .calm { color: var(--ink-3); }
  .vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .skip { position: absolute; left: 8px; top: -48px; z-index: 100; background: var(--raised); color: var(--ink); padding: 8px 12px; border-radius: 8px; box-shadow: var(--elev-3); }
  .skip:focus { top: 8px; }
  svg.i { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.7;
          stroke-linecap: round; stroke-linejoin: round; flex: none; }
  kbd { font: 600 11px/18px var(--mono); border: 1px solid var(--line); border-bottom-width: 2px;
        border-radius: 4px; padding: 0 5px; background: var(--well); color: var(--ink-2); }

  /* buttons */
  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--ctl); padding: 0 12px;
    border-radius: 8px; border: 1px solid var(--line); background: var(--raised); color: var(--ink);
    font-weight: 600; font-size: 12.5px; cursor: pointer; white-space: nowrap; box-shadow: var(--elev-1);
    transition: background-color .15s var(--ease), border-color .15s var(--ease), transform .1s var(--ease);
  }
  .btn:hover:not(:disabled) { border-color: var(--ink-3); }
  .btn:active:not(:disabled) { transform: translateY(.5px); }
  .btn.primary { background: var(--blue); border-color: var(--blue); color: #fff; }
  .btn.ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--ink-2); }
  .btn.ghost:hover:not(:disabled) { background: var(--hover); border-color: transparent; color: var(--ink); }
  .btn.small { height: 28px; padding: 0 10px; font-size: 12px; }
  .btn.small svg.i { width: 14px; height: 14px; }
  .btn.icon { width: var(--ctl); padding: 0; }
  .btn.wide { width: 100%; }
  .btn:disabled { opacity: .45; cursor: default; }
  svg.i.dots { stroke-width: 3.2; }
  .recdot { fill: var(--red); stroke: none; }

  /* segmented control and chips */
  .segm { display: inline-flex; padding: 2px; gap: 2px; border-radius: 8px; background: var(--well); box-shadow: inset 0 0 0 1px var(--line-2); flex: none; }
  .segm button { border: 0; background: transparent; height: calc(var(--ctl) - 4px); padding: 0 12px; border-radius: 6px; font-size: 12px; font-weight: 600; color: var(--ink-2); cursor: pointer; white-space: nowrap; }
  .segm button:hover { color: var(--ink); }
  .segm button[aria-pressed="true"] { background: var(--blue); color: var(--on-bar); box-shadow: var(--elev-2); }
  .segm.full { display: flex; }
  .segm.full button { flex: 1; }
  .chips { display: flex; gap: 6px; flex-wrap: wrap; }
  .chip { display: inline-flex; align-items: center; height: var(--chip); white-space: nowrap; border: 1px solid var(--line); background: transparent;
          border-radius: 999px; padding: 0 10px; font-size: 12px; font-weight: 600; color: var(--ink-2); cursor: pointer; }
  .chip:hover { border-color: var(--ink-3); }
  .chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }

  /* fields */
  .field { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
  .field.col { display: grid; gap: 4px; }
  .field.grow, .grow { flex: 1; min-width: 0; }
  input[type=number], input[type=text], input[type=url], input[type=password], input[type=search], select:not(.ctl select) {
    height: var(--ctl); border: 1px solid var(--line); border-radius: 8px; padding: 0 8px; background: var(--raised); color: var(--ink); min-width: 0;
    transition: border-color .15s var(--ease);
  }
  select:not(.ctl select) { appearance: none; padding-right: 28px; cursor: pointer;
    background: var(--raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23878d96' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 10px center; }
  input:hover, select:not(.ctl select):hover { border-color: var(--ink-3); }
  input:focus, select:not(.ctl select):focus { border-color: var(--blue-ink); }
  input[type=number] { width: 8ch; text-align: right; }
  input[type=range] { accent-color: var(--blue); min-width: 0; height: var(--ctl); margin: 0; }

  /* switches: a visually hidden checkbox followed by .track */
  .switch { display: inline-flex; align-items: center; gap: 8px; min-height: var(--ctl); cursor: pointer; font-weight: 600; font-size: 12.5px; }
  input[role=switch] { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
  .track { width: 32px; height: 20px; border-radius: 999px; background: var(--line); position: relative; flex: none; transition: background-color .15s var(--ease); }
  .track::after { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: oklch(1 0 0); box-shadow: 0 1px 2px oklch(0 0 0 / .25); transition: transform .18s var(--ease); }
  input[role=switch]:checked + .track { background: var(--blue); }
  input[role=switch]:checked + .track::after { transform: translateX(12px); }
  input[role=switch]:focus-visible + .track { outline: 2px solid var(--blue-ink); outline-offset: 2px; }
  html[data-input="pointer"] input[role=switch]:focus-visible + .track { outline: none; }
  input[role=switch]:disabled ~ * { opacity: .45; }

  /* A refused command, beside the control that sent it. Caution, not invalid. */
  .cmd-err { display: flex; gap: 8px; align-items: baseline; margin-top: 8px; padding: 6px 8px; border-radius: 8px;
             background: var(--caution-soft); color: var(--ink); font-size: 12px; font-weight: 500; overflow-wrap: anywhere; }
  .cmd-err .sh { width: 8px; height: 8px; background: var(--yellow); flex: none; box-shadow: 0 0 0 1px oklch(0.439 0.090 82 / .35); }
  .armed { background: var(--yellow); color: oklch(0.19 0.007 258); font-weight: 700; font-size: 11px; line-height: 18px; padding: 0 6px; border-radius: 4px; }

  .sub { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
  .sub .aux { margin-left: auto; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-3); }
  .sub { margin: 16px 0 8px; }
  .meter { height: 4px; border-radius: 2px; background: var(--line); margin-top: 8px; overflow: hidden; }
  .meter i { display: block; height: 100%; background: var(--yellow); }
  .meter.wide i { background: var(--blue); }
  .row-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
  .empty { color: var(--ink-3); }

  .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--link-idle); flex: none; }
  .dot.on { background: var(--link-live); }
  .dot.wait { background: transparent; box-shadow: inset 0 0 0 2px var(--yellow); }
  .dot.off { background: var(--yellow); }

  /* Sentence flags: true 16:11 rectangles, two stripes, a hairline so white holds on white. */
  .flag { display: inline-flex; width: 16px; height: 11px; border-radius: 1.5px; overflow: hidden; flex: none;
          vertical-align: -1px; margin-right: 8px;
          box-shadow: 0 0 0 1px light-dark(oklch(0.19 0.007 258 / .2), oklch(0.93 0.012 250 / .38));
          transition: opacity .4s var(--ease), transform .4s var(--ease); }
  .flag.big { width: 24px; height: 16px; margin: 0; }
  .flag i { flex: 1; }

  /* accordions */
  .acc { border-bottom: 1px solid var(--line-2); }
  .acc > summary { list-style: none; display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 12px 0 16px; cursor: pointer; user-select: none; }
  .acc > summary::-webkit-details-marker { display: none; }
  .acc > summary:hover { background: var(--hover); }
  .acc-t { flex: 1 0 auto; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
  .acc > summary .aux { flex: 0 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; color: var(--ink-3);
                        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .acc-chev { color: var(--ink-3); width: 16px; height: 16px; transition: rotate .2s var(--ease); }
  .acc[open] > summary .acc-chev { rotate: 180deg; }
  .acc-b { padding: 6px 16px 16px; }
}

/* ---------------------------------------------------------------- top bar, menus, sheets */
@layer base {
  /* The one tooltip (flags.js initTips): ink on paper, flips with dusk, no arrow. */
  #tip { --tip-from: 0 4px; position: fixed; inset: 0 auto auto 0; margin: 0; border: 0; max-width: 280px; padding: 6px 9px; border-radius: 8px;
         background: var(--ink); color: var(--on-ink); font: 500 12px/1.4 var(--font); overflow-wrap: anywhere; pointer-events: auto;
         box-shadow: 0 0 0 1px var(--edge), var(--elev-1), 0 6px 18px -6px oklch(0.19 0.007 258 / .32);
         opacity: 0; transform: translate(var(--tip-from));
         /* fades and slides out as well as in: display/overlay stay put until the fade ends */
         transition: opacity .14s var(--ease), transform .18s var(--ease), display .18s allow-discrete, overlay .18s allow-discrete; }
  #tip[data-side="bottom"] { --tip-from: 0 -4px; }
  #tip[data-side="left"] { --tip-from: 4px 0; }
  #tip[data-side="right"] { --tip-from: -4px 0; }
  #tip:popover-open { opacity: 1; transform: none; @starting-style { opacity: 0; transform: translate(var(--tip-from)); } }
  @media (prefers-reduced-motion: reduce) { #tip, #tip:popover-open { --tip-from: 0 0; transition-property: opacity, display, overlay; } }
  #tip kbd { display: inline-block; margin-left: 8px; padding: 0 5px; border-radius: 4px; font: 600 11px/16px var(--mono);
             background: color-mix(in oklch, var(--on-ink) 18%, transparent); color: var(--on-ink); }
}

@layer shell {
  .bar {
    display: flex; align-items: center; gap: 8px; padding: 0 12px 0 16px; min-width: 0;
    background: var(--bar); color: var(--on-bar); position: relative; z-index: 20;
    box-shadow: var(--elev-2);
  }
  .bar :focus-visible:not(.pop *) { outline-color: var(--on-bar); }
  .bar > * { flex: none; }
  .bar > .ctl-wrap:has(> .ctl) { flex: 0 1 auto; }
  .bar .btn:not(.pop *) { height: 32px; background: oklch(1 0 0 / .08); border-color: oklch(1 0 0 / .2); color: var(--on-bar); box-shadow: none; }
  .bar .btn:not(.pop *).icon { width: 32px; }
  .bar .btn:not(.pop *):hover:not(:disabled) { background: oklch(1 0 0 / .16); border-color: oklch(1 0 0 / .32); }
  .bar .btn:not(.pop *)[aria-pressed="false"] { opacity: .6; }
  .bar .btn:not(.pop *)[aria-expanded="true"] { background: oklch(1 0 0 / .2); }
  .pair { display: flex; gap: 4px; }
  .grow { flex: 1; }

  /* the wordmark: a signboard plate in the instrument face */
  .wm { display: flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; margin-right: 8px; }
  .wm b { font: 700 15px/20px var(--instr); letter-spacing: .06em; padding: 0 5px; border-radius: 4px; background: var(--on-bar); color: var(--bar); }
  .wm.big { font-size: 19px; color: var(--ink); }
  .wm.big b { font-size: 19px; line-height: 26px; background: var(--blue); color: #fff; padding: 0 7px; }

  .ctl-wrap { position: relative; display: flex; align-items: center; gap: 8px; min-width: 0; }
  .ctl { display: flex; height: 32px; min-width: 0; border: 1px solid oklch(1 0 0 / .2); border-radius: 8px; background: oklch(1 0 0 / .08); }
  .ctl:hover { border-color: oklch(1 0 0 / .32); }
  .ctl-in { display: flex; align-items: center; min-width: 0; padding-left: 12px; cursor: pointer; }
  button.ctl-in { gap: 8px; height: 30px; padding: 0 10px 0 12px; border: 0; background: transparent; color: inherit; font: inherit; border-radius: 7px 0 0 7px; }
  button.ctl-in:hover { background: oklch(1 0 0 / .12); }
  button.ctl-in svg.i { width: 14px; height: 14px; opacity: .8; }
  .ctl-v { font-weight: 600; font-size: 13px; max-width: 220px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Trim each run to its cap height so the small caps label and the name centre on the same line. */
  .ctl-lbl, .ctl-v { text-box: trim-both cap alphabetic; }
  .ctl-btn.icon { padding: 0 9px; }
  .ctl-btn.icon svg.i { width: 15px; height: 15px; }
  .ctl-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; opacity: .7; white-space: nowrap; }
  .ctl select {
    appearance: none; border: 0; background: transparent; color: inherit; font-weight: 600; font-size: 13px; cursor: pointer;
    height: 30px; padding: 0 28px 0 8px; max-width: 220px; min-width: 0; text-overflow: ellipsis;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='white' stroke-width='1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 10px center;
  }
  .ctl select { field-sizing: content; } /* hug the chosen option, not the longest one */
  .ctl select:focus-visible { outline: 2px solid var(--on-bar); outline-offset: -2px; border-radius: 7px; }
  .ctl select option { color: var(--ink); background: var(--raised); }
  .ctl-btn { border: 0; border-left: 1px solid oklch(1 0 0 / .2); background: transparent; color: inherit; font-weight: 600; padding: 0 12px; cursor: pointer; border-radius: 0 7px 7px 0; }
  .ctl-btn:hover { background: oklch(1 0 0 / .12); }
  .bar .cmd-err:not(.pop *) { position: absolute; top: calc(100% + 8px); left: 0; width: max-content; max-width: 320px; margin: 0; box-shadow: var(--elev-3); z-index: 40; }

  .sure { font: 700 10.5px/20px var(--font); letter-spacing: .06em; text-transform: uppercase; padding: 0 6px; border-radius: 4px; white-space: nowrap; cursor: help;
          color: var(--yellow); box-shadow: inset 0 0 0 1px var(--yellow); }

  .bar .btn:not(.pop *).armed { background: var(--yellow); border-color: var(--yellow); color: oklch(0.19 0.007 258); }
  .count { min-width: 18px; line-height: 18px; padding: 0 5px; border-radius: 9px; background: oklch(0 0 0 / .16); text-align: center; font-size: 11.5px; }

  .pill { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 4px 0 12px; border-radius: 8px; font-weight: 600; font-size: 12.5px; white-space: nowrap;
          background: oklch(1 0 0 / .1); }
  .pill.held { padding-right: 12px; box-shadow: inset 0 0 0 1px oklch(1 0 0 / .3); }
  .pill.mine { background: oklch(1 0 0 / .16); }
  .pill-btn { height: 24px; border: 0; border-radius: 6px; padding: 0 8px; background: oklch(1 0 0 / .14); color: inherit; font-weight: 600; cursor: pointer; }
  .pill-btn:hover { background: oklch(1 0 0 / .24); }
  .conn { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 12.5px; white-space: nowrap; }

  /* popovers: menus under their button */
  [popover].pop {
    position: fixed; inset: auto; margin: 0; padding: 8px; overflow: auto; overscroll-behavior: contain;
    max-height: calc(100dvh - 80px); background: var(--raised); color: var(--ink); border-radius: 12px;
    box-shadow: var(--elev-3), 0 0 0 1px var(--edge);
  }
  [popover].pop:popover-open { animation: pop .18s var(--ease); }
  [popover].pop::backdrop { background: transparent; }
  @keyframes pop { from { opacity: 0; transform: translateY(-4px) scale(.98); } }
  .pop .grip { display: none; }
  .faults-menu { width: 400px; padding: 0 0 8px; }
  .more-menu, .layers-menu { width: 288px; }
  .layers-menu { padding: 8px 12px 12px; }
  .pop-h { font-size: 13px; font-weight: 700; padding: 12px 16px 8px; }
  .layers-menu .pop-h { padding: 4px 0 8px; }
  .faults-menu .pop-h { display: none; }
  .pop .acc:last-child { border-bottom: 0; }
  .mgroup { padding: 4px 0; border-bottom: 1px solid var(--line-2); }
  .mgroup:last-of-type { border-bottom: 0; }
  .mgroup > .frow { padding: 4px 8px 8px; }
  .mgroup > .ctl-wrap { padding: 0; }
  .mitem { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 40px; padding: 0 8px; border: 0; border-radius: 8px; background: transparent;
           color: var(--ink); font-weight: 600; font-size: 13px; text-align: left; cursor: pointer; }
  .mitem:hover { background: var(--hover); }
  .mitem svg.i { color: var(--ink-2); }
  .mitem kbd { margin-left: auto; }
  .mitem .mk { color: var(--ink-2); font-weight: 500; }
  .mitem .mv { margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .more-menu .pill { color: var(--ink); background: var(--well); width: 100%; height: 40px; }
  .more-menu .pill-btn { margin-left: auto; background: var(--raised); box-shadow: 0 0 0 1px var(--line); }
  .mfoot { padding: 8px 8px 2px; color: var(--ink-3); font-size: 12px; }

  /* a row in a menu: label then control */
  .frow { display: flex; align-items: center; gap: 12px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); margin-bottom: 8px; }
  .frow > select { margin-left: auto; }
  .frow.col { flex-direction: column; align-items: stretch; gap: 8px; }
  .frow.col b { color: var(--ink); }

  /* switch rows (faults, layers, vessel form) */
  .opt { display: flex; gap: 16px; align-items: center; padding: 8px 0; cursor: pointer; }
  .opt + .opt { border-top: 1px solid var(--line-2); }
  .opt-t { flex: 1; min-width: 0; }
  .opt b { display: block; font-weight: 600; }
  .opt small { display: block; color: var(--ink-2); font-size: 12px; margin-top: 2px; }
  .opt.act { cursor: default; }
  .msub { color: var(--ink-2); font-size: 12px; margin-bottom: 12px; }
  .presets { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
  .slider-row { display: grid; grid-template-columns: 112px minmax(0, 1fr) 48px; align-items: center; gap: 12px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
  .slider-row output { text-align: right; font-size: 14px; color: var(--ink); }

  /* modal sheets (native dialog): a centred card on a desktop, a bottom sheet on a phone */
  dialog.sheet { width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 64px); background: var(--raised); border-radius: 16px; overflow: hidden;
                 box-shadow: var(--elev-4), 0 0 0 1px var(--edge); }
  dialog.sheet[open] { display: flex; flex-direction: column; animation: pop .2s var(--ease); }
  /* Modals sit over a lightly frosted page: a 6 px blur is enough to separate layers while the
     chart stays legible behind (Apple's thin material, not the heavy one). Fades in with the sheet. */
  dialog::backdrop { background: var(--scrim); -webkit-backdrop-filter: blur(6px) saturate(1.15); backdrop-filter: blur(6px) saturate(1.15);
                     transition: opacity .25s var(--ease), display .25s allow-discrete, overlay .25s allow-discrete; }
  dialog[open]::backdrop { @starting-style { opacity: 0; } }
  @media (prefers-reduced-transparency: reduce) { dialog::backdrop { -webkit-backdrop-filter: none; backdrop-filter: none; } }
  .sheet-h { flex: none; position: relative; display: flex; align-items: center; gap: 8px; padding: 16px 12px 8px 24px; }
  .sheet-h h2 { flex: 1; min-width: 0; font-size: 17px; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .grip { display: none; position: absolute; left: 50%; top: 8px; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--line); }
  .sheet-b { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 0 24px 24px; }
  .help h3 { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); margin: 16px 0 8px; }
  .help p, .help li, .help dd { color: var(--ink-2); max-width: 70ch; }
  .help ul { padding-left: 18px; display: grid; gap: 4px; }
  .keys { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; align-items: center; }
  .keys dt { white-space: nowrap; }
  .choices { display: grid; gap: 2px; }
  .choices button { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 12px; border: 0; border-radius: 10px; background: transparent; text-align: left; font-size: 14px; cursor: pointer; }
  .choices button::before { content: ""; width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--ink-3); flex: none; }
  .choices button[aria-checked="true"] { background: var(--sel-soft); font-weight: 600; }
  .choices button[aria-checked="true"]::before { box-shadow: inset 0 0 0 5px var(--blue); }
  .choices small { margin-left: auto; color: var(--ink-3); font-size: 12px; }
  .sheet-acts { position: sticky; bottom: -16px; padding: 16px 0 0; background: var(--raised); }

  .gate { position: fixed; inset: 0; overflow: auto; display: grid; place-items: center; padding: 24px 16px; background: var(--ground); }
  .gate-card { width: min(440px, 100%); background: var(--raised); border-radius: 16px; padding: 24px; display: grid; gap: 12px;
               box-shadow: var(--elev-3), 0 0 0 1px var(--edge); }
  .gate-card h2 { font-size: 17px; margin-top: 8px; }
  .gate-card p { color: var(--ink-2); }
  .gate-card input { font-family: var(--mono); }
  .gate-card .btn { justify-self: start; }
  .gate-card .cmd-err { margin: 0; }
  .gate-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
  .gate-acts .btn { text-decoration: none; height: var(--ctl); }
  .account .who { display: flex; align-items: center; gap: 12px; padding: 6px 8px; }
  .account .who svg.i { color: var(--ink-2); flex: none; }
  .account .who span { display: grid; min-width: 0; }
  .account .who b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .account .who small { color: var(--ink-3); font-size: 12px; }
  .account form { margin: 0; }

  /* frame */
  .work { position: relative; display: grid; grid-template-columns: var(--left) minmax(0, 1fr) var(--right); grid-template-rows: minmax(0, 1fr); min-height: 0; }
  .work > .side.left { grid-column: 1; } .work > .chart { grid-column: 2; } .work > .side.right { grid-column: 3; }
  .resizer { position: absolute; z-index: 5; touch-action: none; }
  .resizer.x { top: 0; bottom: 0; width: 9px; cursor: col-resize; }
  .side.left .resizer { right: -5px; } .side.right .resizer { left: -5px; }
  .resizer.y { left: 0; right: 0; top: -5px; height: 9px; cursor: row-resize; }
  .resizer::after { content: ""; position: absolute; background: var(--blue-ink); opacity: 0; transition: opacity .15s var(--ease); pointer-events: none; }
  .resizer.x::after { top: 0; bottom: 0; left: 4px; width: 2px; }
  .resizer.y::after { left: 0; right: 0; top: 4px; height: 2px; }
  /* Every panel edge works the same way: hovering it shows the blue line, with a small blue tab
     fixed to the line on the chart side (a drawer pull). Click the tab to hide the panel; drag
     anywhere on the edge to resize. A hidden panel leaves a slim tab on the chart's edge. */
  .resizer:hover::after, .resizer:focus-visible::after, html[data-resizing] .resizer:active::after { opacity: 1; }
  .resizer:focus-visible { outline: none; }
  .edge-grip { position: absolute; z-index: 1; display: grid; place-items: center; padding: 0; border: 0;
               background: var(--blue-ink); color: var(--on-ink); box-shadow: var(--elev-2); cursor: pointer;
               opacity: 0; transition: opacity .15s var(--ease), translate .15s var(--ease); }
  .edge-grip svg.i { width: 14px; height: 14px; stroke-width: 2.4; color: currentColor; }
  /* The line is 2 px at 4-6 px inside the 9 px edge; each tab starts where the line ends. */
  .edge-grip.left { left: 6px; top: 50%; width: 18px; height: 44px; border-radius: 0 8px 8px 0; translate: -4px -50%; }
  .edge-grip.right { right: 5px; top: 50%; width: 18px; height: 44px; border-radius: 8px 0 0 8px; translate: 4px -50%; }
  .edge-grip.bottom { bottom: 5px; left: 50%; width: 44px; height: 18px; border-radius: 8px 8px 0 0; translate: -50% 4px; }
  .resizer:hover .edge-grip, .edge-grip:focus-visible { opacity: 1; }
  .resizer:hover .edge-grip.left, .edge-grip.left:focus-visible { translate: 0 -50%; }
  .resizer:hover .edge-grip.right, .edge-grip.right:focus-visible { translate: 0 -50%; }
  .resizer:hover .edge-grip.bottom, .edge-grip.bottom:focus-visible { translate: -50% 0; }
  html[data-resizing] .edge-grip { opacity: 0; }

  .edge-tab { position: absolute; z-index: 4; display: flex; align-items: center; gap: 6px; border: 0; cursor: pointer;
              background: var(--raised); color: var(--ink-2); box-shadow: var(--elev-2), 0 0 0 1px var(--edge);
              font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
  .edge-tab:hover { color: var(--on-ink); background: var(--blue-ink); box-shadow: var(--elev-2); }
  .edge-tab svg.i { width: 14px; height: 14px; stroke-width: 2.2; }
  .edge-tab.left, .edge-tab.right { top: 50%; translate: 0 -50%; flex-direction: column; padding: 10px 4px; }
  .edge-tab.left { left: 0; border-radius: 0 10px 10px 0; } .edge-tab.right { right: 0; border-radius: 10px 0 0 10px; }
  .edge-tab.left span, .edge-tab.right span { writing-mode: vertical-rl; }
  .edge-tab.left span { transform: rotate(180deg); }
  .edge-tab.bottom { bottom: 0; left: 50%; translate: -50% 0; padding: 4px 12px 4px 10px; border-radius: 10px 10px 0 0; }
  html[data-resizing] { cursor: col-resize; user-select: none; }
  html[data-resizing="y"] { cursor: row-resize; }
}

/* ---------------------------------------------------------------- side panels */
@layer panels {
  .side { position: relative; z-index: 2; display: flex; flex-direction: column; min-height: 0; min-width: 0; background: var(--panel); }
  .side.left { box-shadow: 1px 0 0 var(--line), var(--elev-2); }
  .side.right { box-shadow: -1px 0 0 var(--line), var(--elev-2); }
  .side-body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; }

  /* the pinned identity row */
  .ident { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; row-gap: 2px; align-items: center;
           padding: 16px; border-bottom: 1px solid var(--line); }
  .ident .name { font-size: 17px; font-weight: 700; letter-spacing: -0.015em; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ident .maker { grid-row: 2; color: var(--ink-2); font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: default; }
  .batt-wrap { grid-row: 1 / 3; grid-column: 2; margin: -4px -6px; padding: 4px 6px; border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; cursor: pointer; }
  .batt-wrap:hover { background: var(--hover); }

  .batt { display: flex; align-items: center; gap: 8px; }
  .cell { position: relative; width: 36px; height: 18px; border: 1.6px solid var(--ink); border-radius: 4px; padding: 2px; display: flex; gap: 2px; }
  .cell::after { content: ""; position: absolute; right: -4.5px; top: 4.5px; width: 2.6px; height: 6px; border-radius: 0 1.5px 1.5px 0; background: var(--ink); }
  .cell .fill { height: 100%; background: var(--ink); border-radius: 1.5px; transition: width .3s var(--ease); }
  .cell .seg { flex: 1; border-radius: 1.5px; background: var(--ink); }
  .cell .seg.off { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
  .batt.low .cell { border-color: var(--red); }
  .batt.low .cell::after, .batt.low .fill, .batt.low .seg:not(.off) { background: var(--red); }
  .batt.none .cell { border-style: dashed; border-color: var(--ink-3); }
  .batt.none .cell::after { background: var(--ink-3); }
  .batt.none .cell::before { content: ""; position: absolute; left: 3px; right: 3px; top: 50%; height: 1.6px; background: var(--ink-3); transform: rotate(-24deg); }
  .batt .val { font-size: 22px; font-weight: 700; line-height: 1; white-space: nowrap; }
  .batt .val small { font: 600 12px var(--font); color: var(--ink-2); margin-left: 1px; }
  .batt .val.quiet { font: 600 12px var(--font); color: var(--ink-3); }

  /* link steps */
  .steps { display: grid; gap: 12px; }
  .step { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 8px; align-items: start; }
  .step .ic { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; }
  .step .ic svg { width: 12px; height: 12px; stroke-width: 2.2; }
  .step.done .ic { background: var(--ok-soft); color: var(--ok-ink); }
  .step.wait .ic { background: var(--caution-soft); color: var(--caution-ink); }
  .step.todo .ic { box-shadow: inset 0 0 0 1.5px var(--ink-3); color: var(--ink-3); }
  .step.fail .ic { background: var(--invalid-soft); color: var(--invalid); }
  .step .t { font-weight: 600; line-height: 20px; }
  .step .s { color: var(--ink-2); font-size: 12px; overflow-wrap: anywhere; }
  .step .age { color: var(--ink-3); font-size: 12px; line-height: 20px; white-space: nowrap; }
  .link-foot { margin-top: 12px; }

  /* S-Mode lines: quantity | value | sentence | status */
  table { width: 100%; border-collapse: collapse; }
  .q td { height: 40px; padding: 0; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
  .q tr:last-child td { border-bottom: 0; }
  .q .k { width: 48px; font-size: 11px; font-weight: 700; letter-spacing: .06em; color: var(--ink-3); }
  .q .v { font-size: 13.5px; font-weight: 600; }
  .q .v.ro { font-size: 21px; font-weight: 600; line-height: 1; }
  .q .v small { font: 500 12px var(--font); color: var(--ink-2); margin-left: 3px; }
  .q .src { text-align: right; color: var(--ink-3); font: 11.5px var(--mono); padding-right: 8px; }
  .q .st { width: 36px; text-align: right; }
  .st b { font: 700 11px/18px var(--mono); padding: 0 5px; border-radius: 4px; white-space: nowrap; display: inline-block; }
  .st b.A { background: var(--ok-soft); color: var(--ok-ink); }
  .st b.V { background: var(--invalid-soft); color: var(--invalid); }
  .st b.stale, .st b.none { color: var(--ink-3); box-shadow: inset 0 0 0 1px currentColor; }
  .st b.doubt { background: var(--caution-soft); color: var(--caution-ink); box-shadow: inset 0 0 0 1px var(--doubt-ring); }
  .q tr.why td { height: auto; padding: 0 0 8px; color: var(--caution-ink); font-size: 12px; }
  .q tr:has(+ tr.why) td { border-bottom: 0; }
  .q tr.none .v, .q tr.stale .v { color: var(--ink-3); font: 500 13px var(--font); }
  .q tr.V .v { color: var(--invalid); }

  /* sentence rows: flag + type share one cell */
  .sent td { height: 32px; padding: 0; border-bottom: 1px solid var(--line-2); font-size: 12px; }
  .sent tr:last-child td { border-bottom: 0; }
  .sent td.n { text-align: right; color: var(--ink-2); width: 64px; white-space: nowrap; }
  .sent td.n.ro { font-size: 13.5px; color: var(--ink); }
  .ty { font: 600 12px var(--mono); white-space: nowrap; }
  .ty .tk { color: var(--ink-3); }
  .ty .calm { font: 500 11px var(--font); margin-left: 4px; }
  tr.late .flag { opacity: .55; }
  tr.lost .flag { opacity: .2; transform: translateY(3px); }
  tr.lost td { color: var(--ink-3); }
  .ph { font: 700 10.5px var(--font); letter-spacing: .04em; text-transform: uppercase; color: var(--caution-ink); background: var(--caution-soft); padding: 1px 4px; border-radius: 4px; margin-left: 8px; }

  /* Test controls */
  .tc-block + .tc-block { border-top: 1px solid var(--line-2); margin-top: 16px; }
  .tc-block > .sub:first-child { margin-top: 16px; }
  .tc-block:first-child > .sub:first-child { margin-top: 0; }
  .tc .slider-row { grid-template-columns: minmax(0, 1fr) 72px auto; margin-bottom: 8px; }
  .tc .slider-row output { text-align: left; }
  .tc .row-wrap { gap: 4px 16px; }
  .tc-sent td { height: 40px; padding: 0; border-bottom: 1px solid var(--line-2); }
  .tc-sent tr:last-child td { border-bottom: 0; }
  .tc-sent td.mono { font-weight: 600; }
  .tc-sent td.n { text-align: right; width: 128px; }
  .tc-sent td:nth-child(2) { width: 88px; }
  .tc-sent select { width: 100%; font-size: 12px; }
  .tc-sent .chip[aria-pressed="false"] { color: var(--caution-ink); border-color: var(--doubt-ring); background: var(--caution-soft); }
  .tc-sent .chip[aria-pressed="true"] { background: transparent; color: var(--ink-2); border-color: var(--line); }
  .grid2 { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 8px 12px; align-items: center; }
  .grid2 .fl { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
  .grid2 > select, .grid2 > input { justify-self: start; }
  .grid2 > select { width: 100%; }
  .grid2 > input { width: 12ch; text-align: left; }
  .grid2 .segm { justify-self: start; }
  .tc-foot { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-2); }

  .setup { list-style: none; display: grid; gap: 8px; }
  .setup li { display: flex; gap: 12px; align-items: baseline; }
  .setup li b { font-weight: 600; }
  .setup li span { margin-left: auto; color: var(--ink-2); text-align: right; }
  .setup li.addr span { font: 12px var(--mono); }
  .real { margin-top: 12px; color: var(--ink-3); font-size: 12px; }
  .real + .real { margin-top: 4px; }

  /* alerts: BAM shapes. caution = yellow square, warning = orange circle */
  .alerts { display: grid; gap: 8px; }
  .alert { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 12px; padding: 10px 12px; border-radius: 10px; background: var(--caution-soft); }
  .alert .sh { width: 12px; height: 12px; background: var(--yellow); margin-top: 3px; box-shadow: 0 0 0 1px oklch(0.439 0.090 82 / .35); }
  .alert.warning { background: var(--warning-soft); }
  .alert.warning .sh { background: var(--warning); border-radius: 50%; box-shadow: none; }
  .alert b { font-weight: 600; }
  .alert p { color: var(--ink-2); font-size: 12px; margin-top: 2px; }
  .alert time { color: var(--ink-3); font-size: 12px; }

  /* wire */
  .wire-ctl { display: flex; margin-bottom: 12px; }
  .wire-ctl .segm { flex: 1; } .wire-ctl .segm button { flex: 1; }
  .acc-b > .chips { margin-bottom: 12px; }
  .wt th { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); font-weight: 600; text-align: left; padding: 0 0 8px; }
  .wt td { height: 32px; padding: 0; border-bottom: 1px solid var(--line-2); font-size: 12px; }
  .wt th.n, .wt td.n { text-align: right; }
  .wt td.n.ro { font-size: 13.5px; }
  .wt .dir { width: 20px; color: var(--ink-3); }
  .wt tr.in td, .wt tr.in .dir { color: var(--blue-ink); font-weight: 600; }
  .wt tbody tr { cursor: pointer; }
  .wt tbody tr:hover td { background: var(--hover); }
  .wt tbody tr[aria-selected="true"] td { background: var(--sel-soft); }
  .wt tbody tr:focus-visible { outline: 2px solid var(--blue-ink); outline-offset: -2px; }
  .foot { margin-top: 8px; font-size: 12px; }
  .acc-b > .sub { margin-top: 16px; }
  .stream { font: 11.5px/1.6 var(--mono); background: var(--well); border-radius: 10px; padding: 8px 12px; max-height: 192px; overflow: auto; box-shadow: inset 0 0 0 1px var(--line-2); }
  .stream.tall { max-height: none; height: min(60vh, 520px); }
  .stream div { white-space: pre-wrap; word-break: break-all; padding-left: 1.6em; text-indent: -1.6em; }
  .stream .in { color: var(--blue-ink); font-weight: 600; }
  .stream .ph { display: block; font: inherit; background: none; padding: 0 0 0 1.6em; margin: 0; text-transform: none; letter-spacing: 0; color: var(--caution-ink); }
  .stream .t { color: var(--ink-3); }
  .wfilter { width: 100%; margin-bottom: 12px; }
  .decode { margin-top: 12px; border-radius: 10px; background: var(--well); padding: 12px; box-shadow: inset 0 0 0 1px var(--line-2); }
  .decode .raw { font: 11.5px var(--mono); overflow-wrap: anywhere; margin-bottom: 8px; }
  .decode dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; font-size: 12px; }
  .decode dt { color: var(--ink-3); }
}

/* ---------------------------------------------------------------- chart */
@layer chart {
  /* The map runs under the side panels and the drawer (--ml/--mr/--mb), so a resize only slides an opaque
     panel over it: the canvas keeps its size and never blanks. map.js pads the camera to match. */
  .chart { --ml: var(--left, 0px); --mr: var(--right, 0px); --mb: var(--below, 0px); position: relative; z-index: 1; min-width: 0; min-height: 0; background: var(--water); container-type: inline-size; }
  .chart-tools { position: absolute; left: 12px; top: 12px; z-index: 3; display: flex; gap: 8px; }
  .nav { position: absolute; right: 12px; top: 12px; z-index: 3; display: flex; flex-direction: column; align-items: center; gap: 8px; }

  /* one material for every chart control: raised, elev-2, 8 px corners, 32 px */
  .tool, .segm.view, .zoom, .compass, .hoist, .readout {
    background: var(--raised); box-shadow: var(--elev-2), 0 0 0 1px var(--edge);
  }
  .tool { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px; color: var(--ink-2); cursor: pointer; }
  .tool:hover { color: var(--ink); }
  .tool[aria-expanded="true"] { color: var(--blue-ink); }
  .segm.view { padding: 0; gap: 0; border-radius: 8px; overflow: hidden; }
  .segm.view button { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 0; color: var(--ink-2); }
  .segm.view button + button { box-shadow: inset 1px 0 var(--line-2); }
  .segm.view button[aria-pressed="true"] { background: var(--blue); color: #fff; box-shadow: none; }
  /* Orientation under the compass: North / Course / Head up, letters in the readout face. */
  .zoom { display: flex; flex-direction: column; border-radius: 8px; overflow: hidden; }
  .zoom .tool { box-shadow: none; border-radius: 0; background: transparent; }
  .zoom .tool + .tool { box-shadow: inset 0 1px var(--line-2); }

  /* The compass: rose turned by the map bearing, this vessel's heading as a solid needle, the
     course over ground as a hollow chevron. An invalid value is dashed; an absent one is not drawn. */
  .compass { display: grid; justify-items: center; gap: 6px; min-width: 112px; width: auto; padding: 10px 8px 9px; border-radius: 16px; color: var(--ink); }
  .cdial { display: grid; justify-items: center; gap: 4px; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: 10px; }
  .cdial:hover .disc { stroke: var(--ink-3); }
  .compass svg { width: 96px; height: 96px; display: block; overflow: visible; }
  .compass .disc { fill: var(--panel); stroke: var(--line); stroke-width: 1; }
  .compass .rose, .compass .hdg, .compass .cog { transform-origin: 50px 50px; transform-box: view-box; }
  .compass .hdg, .compass .cog { transition: transform .2s ease-out; }
  .compass line.min { stroke: var(--ink-3); stroke-width: .8; }
  .compass line.maj { stroke: var(--ink-2); stroke-width: 1.3; }
  .compass .north { fill: var(--ink); }
  .compass .card { font: 700 10px var(--instr); fill: var(--ink-3); text-anchor: middle; }
  .compass .card.n { fill: var(--ink); font-size: 11px; }
  .compass .hdg path { fill: var(--red); stroke: var(--panel); stroke-width: .8; stroke-linejoin: round; }
  .compass .hdg.bad path { fill: none; stroke: var(--red); stroke-width: 1.4; stroke-dasharray: 3 2.2; }
  .compass .cog path, .compass .cog line { fill: none; stroke: var(--ink); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
  .compass .cog line { stroke-width: 1.1; stroke-dasharray: 1.5 2; stroke: var(--ink-2); }
  .compass .cog.bad path { stroke: var(--ink-3); stroke-dasharray: 2.6 2; stroke-width: 1.6; }
  .compass .absent { fill: none; stroke: var(--ink-3); stroke-width: 1.2; stroke-dasharray: 2.5 2; }
  .compass .hub { fill: var(--ink); }
  .cread { display: grid; font-size: 12px; line-height: 1.35; text-align: center; min-width: max-content; }
  .cread .h { font-size: 15px; font-weight: 700; }
  .cread span { white-space: nowrap; }
  .cread .h { color: var(--red); }
  .cread .bad { text-decoration: underline dashed; text-underline-offset: 2px; }
  .cread .absent { color: var(--ink-3); }

  .hoist { position: absolute; left: 12px; bottom: 12px; z-index: 2; width: 108px; display: grid; gap: 4px; padding: 8px 12px 10px; border-radius: 10px; }
  .hoist small { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px; }
  .hoist .hl { display: flex; align-items: center; gap: 8px; font: 600 11px var(--mono); transition: opacity .4s var(--ease); }
  .hoist .hl.lost { opacity: .28; }
  .readout { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); z-index: 2; font-size: 11.5px; font-weight: 600; color: var(--ink-2);
             border-radius: 8px; padding: 4px 8px; pointer-events: none; white-space: nowrap; }
  .readout:empty { display: none; }
  /* the collapsed bottom panel's tab sits where the readout does: lift the readout over it */
  .work:has(> .edge-tab.bottom) .readout { bottom: 40px; }
  .hint { position: absolute; left: 50%; top: 56px; transform: translateX(-50%); z-index: 4; background: var(--ink); color: var(--on-ink); font-weight: 600; font-size: 12px;
          border-radius: 8px; padding: 8px 12px; pointer-events: none; opacity: 0; transition: opacity .2s var(--ease); max-width: calc(100% - 24px); box-shadow: var(--elev-3); }
  .hint.show { opacity: 1; }

  @container (max-width: 520px) { .compass { min-width: 96px; } .compass svg { width: 84px; height: 84px; } .cread { font-size: 11px; } .cread .h { font-size: 13px; } }
}

/* ---------------------------------------------------------------- drawer */
@layer drawer {
  .drawer { position: relative; z-index: 3; display: flex; flex-direction: column; height: var(--drawer, 200px); min-height: 0; background: var(--panel);
            box-shadow: 0 -1px 0 var(--line), 0 -2px 8px oklch(0.19 0.007 258 / .06); }
  .tabs { flex: none; display: flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 12px 0 8px; border-bottom: 1px solid var(--line-2); min-width: 0; }
  .tabs [role="tab"] { height: 44px; border: 0; background: transparent; padding: 0 12px; font-weight: 600; color: var(--ink-2); box-shadow: inset 0 -2px transparent; cursor: pointer; white-space: nowrap; }
  .tabs [role="tab"]:hover { color: var(--ink); }
  .tabs [role="tab"][aria-selected="true"] { color: var(--ink); box-shadow: inset 0 -2px var(--blue-ink); }
  .dtitle { margin: 0; padding: 0 8px; font: 700 11px var(--font); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
  .tabs em { font-style: normal; color: var(--ink-3); font-weight: 500; margin-left: 4px; }
  .tabnote { margin-left: auto; color: var(--ink-3); font-size: 12px; margin-right: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .add-wrap { display: flex; align-items: center; gap: 8px; margin-left: auto; }
  .tabnote + .add-wrap { margin-left: 0; }
  .add-wrap .cmd-err { margin: 0; }
  .pane { flex: 1; min-height: 0; overflow: auto; padding: 0 16px 12px; }

  /* fixed layout: a value or a select's chosen option changing width must not move any column */
  .vessels { min-width: 980px; table-layout: fixed; width: 100%; }
  .vessels th { position: sticky; top: 0; z-index: 1; background: var(--panel); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); text-align: left; padding: 12px 8px 8px 0; font-weight: 600; }
  .vessels td { height: 40px; padding: 0 8px 0 0; border-top: 1px solid var(--line-2); vertical-align: middle; }
  .vessels th.n { text-align: right; }
  .vessels tbody tr { cursor: pointer; }
  .vessels tbody tr:hover td { background: var(--hover); }
  .vessels tr.sel td { background: var(--sel-soft); }
  .vessels input { width: 100%; border-color: transparent; background: transparent; padding: 0 8px; }
  .vessels input:hover { border-color: var(--line); }
  .vessels input:focus { border-color: var(--blue-ink); background: var(--raised); }
  .vessels input[type=number] { text-align: right; min-width: 7ch; }
  /* input.mmsi, so it outranks input[type=number]: 9 digits, the padding and the spin box's room */
  .vessels input.mmsi { text-align: left; min-width: 13ch; }
  .vessels .nm { font-weight: 600; min-width: 12ch; text-overflow: ellipsis; }
  .vessels select { font-size: 12px; max-width: 176px; }
  .sel-cell { width: 32px; }
  .pick { width: 28px; height: 28px; display: grid; place-items: center; border: 0; border-radius: 6px; background: transparent; cursor: pointer; color: var(--ink-3); }
  .pick:hover { background: var(--hover); }
  .pick .dot, .vmark .dot { width: 8px; height: 8px; background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
  .pick[aria-pressed="true"] .dot { background: var(--blue-ink); box-shadow: none; }
  /* This vessel: pinned first, labelled, and the only red in the drawer. */
  .hullmark { width: 14px; height: 14px; fill: var(--red); }
  .vessels tr.own + tr:not(.own):not(.row-err) td { border-top: 1px solid var(--line); }
  .namecell { position: relative; }
  .this { position: absolute; left: 8px; top: 3px; font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--red); line-height: 1; pointer-events: none; }
  .vessels tr.own .nm { color: var(--red); padding-top: 10px; }
  .emit { display: inline-flex; gap: 4px; }
  .emit button { height: 26px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--line); background: transparent; font: 600 11px var(--mono); color: var(--ink-3); cursor: pointer; }
  .emit button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
  .rm { width: 28px; height: 28px; border: 0; background: transparent; color: var(--ink-3); border-radius: 6px; cursor: pointer; display: grid; place-items: center; }
  .rm:hover { background: var(--hover); color: var(--ink); }
  /* biome-ignore lint/complexity/noImportantStyles: the error row joins the row above it */ .row-err td { border-top: 0 !important; height: auto; padding-bottom: 4px; }
  .row-err .cmd-err { margin: 0; display: inline-flex; }

  .log { list-style: none; font-size: 12.5px; padding-top: 4px; }
  .log li { padding: 6px 0; border-bottom: 1px solid var(--line-2); overflow-wrap: anywhere; }
  .log li.err { color: var(--caution-ink); }

  .rec { padding-top: 12px; display: grid; gap: 12px; }
  .feeds { list-style: none; display: grid; gap: 4px; margin: 0 0 8px; }
  .feeds li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
  .feeds .btn { margin-left: auto; }
  .addlink { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
  .addlink input[type=number] { width: 9ch; }
  .addlink .cmd-err { margin: 0; }
  .rec { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px 32px; }
  .rec .sub { margin-top: 4px; }
  .rec-live { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .rec-live .btn { margin-left: auto; }
  .rec select.grow { flex: 1; min-width: 0; }
  .led { width: 8px; height: 8px; border-radius: 50%; flex: none; }
  .led.rec { background: var(--red); }
  .tool-check { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 12.5px; color: var(--ink-2); cursor: pointer; }

  /* phone vessel list + edit form */
  .vlist { list-style: none; }
  .vitem { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto 16px; gap: 12px; align-items: center; width: 100%; min-height: 56px; padding: 0 4px;
           border: 0; border-bottom: 1px solid var(--line-2); background: transparent; text-align: left; cursor: pointer; color: var(--ink-3); }
  .vmark { display: grid; place-items: center; }
  .vname b { display: block; color: var(--ink); font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .vitem.own .vname b { color: var(--red); }
  .vname small { color: var(--ink-3); font-size: 12px; }
  .vnum { color: var(--ink); font-size: 16px; }
  .vnum small { font: 500 11px var(--font); color: var(--ink-3); }
  .vform { display: grid; gap: 12px; }
  .ff { display: grid; gap: 4px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
  .ff input, .ff select { width: 100%; font-size: 16px; font-weight: 500; text-align: left; }
  .ff-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .ff .emit button { height: var(--ctl); padding: 0 16px; font-size: 12px; }
  .vform .opt { border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); }
  .vform-acts { display: flex; gap: 8px; margin-top: 4px; }
  .vform-acts .btn { flex: 1; }
}

/* ---------------------------------------------------------------- scenario library and editor */
@layer editor {
  .ctl-btn { display: inline-flex; align-items: center; gap: 6px; }
  .ctl-btn svg.i { width: 15px; height: 15px; }
  .tag { font: 700 10.5px/18px var(--font); letter-spacing: .04em; text-transform: uppercase; padding: 0 6px; border-radius: 4px;
         background: var(--sel-soft); color: var(--blue-ink); white-space: nowrap; }
  .tag.quiet { background: var(--well); color: var(--ink-3); box-shadow: inset 0 0 0 1px var(--line); }

  /* fields: a label over its control, a hint line under it */
  .ff > span i { font-style: normal; font-weight: 500; color: var(--ink-3); }
  .ed .ff input, .ed .ff select, .lib-form .ff input { font-size: 13px; height: var(--ctl); }
  .nm-in { font-family: var(--mono); }
  .hint-line { font-size: 11.5px; font-weight: 500; color: var(--ink-3); line-height: 1.35; }
  .hint-line.warn, .hint-line.bad { color: var(--caution-ink); }
  .hint-line.bad::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 6px; background: var(--yellow); vertical-align: 0; }
  input[aria-invalid="true"], input[aria-invalid="true"]:focus { border-color: var(--doubt-ring); }

  /* library sheet */
  dialog.sheet.lib { width: min(640px, calc(100vw - 32px)); height: min(760px, calc(100dvh - 64px)); }
  /* The PPU modal: the list, and the chosen unit turning beside it */
  dialog.sheet.ppu-pick { width: min(1040px, calc(100vw - 32px)); }
  .ppu-pick .sheet-b { overflow: hidden; display: flex; padding-bottom: 0; }
  /* Each pane scrolls on its own: its bar sits at the pane's outer edge, in padding of its own, so it
     never lies over the text. The grid reaches 14px into the sheet's margin to give it room. */
  .pp { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 10px; margin-right: -14px; }
  .pp-list { min-height: 0; overflow: auto; padding: 2px 14px 24px 2px; scrollbar-width: thin; }
  .pp-view { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 16px; padding: 0 14px 24px 14px; scrollbar-width: thin; }
  /* No box: the unit floats on the modal's own surface. It clips at the stage's edge only while it slides. */
  .pstage { position: relative; flex: none; aspect-ratio: 4 / 3; overflow: hidden; }
  .pstage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: pan-y; cursor: grab; }
  .pp-info .corrected { display: flex; align-items: center; gap: 6px; margin: -6px 0 12px; color: var(--ink-3); }
  .pstage canvas:active { cursor: grabbing; }
  .pstage-msg { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 8px; font-size: 13px; color: var(--ink-3); }
  .pstage-msg svg.i { width: 64px; height: 64px; stroke-width: 1; color: var(--ink-3); }
  /* a picture or the cube: the same slide as the 3D units. Quadratic ease: in is ease-out, out is ease-in.
     --d is 1 going down the list (leaves to the right, arrives from the left) and -1 going back up. */
  .slot { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
  .slot.in { animation: slot-in 300ms cubic-bezier(.25, .46, .45, .94) both; }
  .slot.out { animation: slot-out 240ms cubic-bezier(.55, .085, .68, .53) both; }
  @keyframes slot-in { from { transform: translateX(calc(var(--d) * -70%)); opacity: 0; } }
  @keyframes slot-out { to { transform: translateX(calc(var(--d) * 70%)); opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .slot { animation: none !important; } }
  /* a picture and its shadow are two things: the picture never carries one */
  .still { width: 84%; display: grid; justify-items: center; }
  .still img { display: block; width: 100%; height: auto; max-height: 100%; user-select: none; }
  .still .sh { width: 80%; aspect-ratio: 8 / 1; margin-top: -15%; border-radius: 50%; filter: blur(5px);
               background: radial-gradient(closest-side, oklch(0.2 0.01 258 / .34), oklch(0.2 0.01 258 / .14) 55%, transparent); }
  .pstage-hint { position: absolute; left: 14px; bottom: 12px; font-size: 11.5px; color: var(--ink-3); }
  .pp-info .maker { margin: 0; font: 700 11px var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
  .pp-info h3 { margin: 2px 0 6px; font: 700 24px/1.15 var(--instr); }
  .pp-info > .calm { margin: 0 0 12px; }
  .pp-dl { display: grid; grid-template-columns: auto minmax(0, 1fr); margin: 0 0 16px; }
  .pp-dl dt, .pp-dl dd { margin: 0; padding: 7px 0; border-bottom: 1px solid var(--line-2); font-size: 13px; }
  .pp-dl dt { color: var(--ink-2); padding-right: 16px; }
  .pp-dl dd { text-align: right; font-weight: 600; }
  .pp-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
  .pcard .tag.inuse { background: var(--blue-ink); color: var(--on-ink); }
  @media (max-width: 760px) {
    .ppu-pick .sheet-b { overflow: auto; display: block; }
    .pp { grid-template-columns: minmax(0, 1fr); margin-right: 0; }
    .pp-view { order: -1; overflow: visible; padding: 0; }
    .pp-list { overflow: visible; }
  }
  .lib-top { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 0 16px; border-bottom: 1px solid var(--line-2); }
  .lib-top .btn[aria-pressed="true"] { background: var(--sel-soft); border-color: var(--blue-ink); }
  /* the PPU chooser: one card per unit */
  .ppu-pick .sheet-b > .calm { margin: 0 0 12px; }
  .pcards { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 6px; }
  .pcards li { position: relative; }
  .pcard { display: grid; gap: 3px; width: 100%; padding: 10px 44px 10px 12px; border: 0; border-radius: 10px; background: transparent; color: var(--ink);
           text-align: left; font: inherit; cursor: pointer; box-shadow: inset 0 0 0 1px var(--line-2); }
  .pcard:hover { background: var(--hover); }
  .pcard[aria-checked="true"] { background: var(--sel-soft); box-shadow: inset 0 0 0 1.5px var(--blue-ink); }
  .pc-t { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
  .pc-t b { font-weight: 600; }
  .pc-t .calm { font-size: 12px; }
  .pc-d { font-size: 12.5px; color: var(--ink-2); }
  .pc-m { font-size: 11.5px; color: var(--ink-3); }
  .pcard .tag.CONFIRMED, .pcard .tag.OFF, .pcard .tag.FIELD { background: var(--ok-soft); color: var(--ok-ink); }
  .pcard .tag.ASSUMED { background: var(--caution-soft); color: var(--caution-ink); }
  .pc-link { position: absolute; top: 8px; right: 8px; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; color: var(--ink-2); }
  .pc-link:hover { background: var(--hover); color: var(--ink); }
  .pc-link svg.i { width: 15px; height: 15px; }

  /* Manage PPUs: the add / edit form */
  .ppu-form .sub { margin: 8px 0 -4px; }
  .pic-row { display: flex; align-items: center; gap: 8px; }
  .pic-prev { width: 72px; height: 54px; object-fit: contain; border-radius: 8px; background: var(--well); box-shadow: inset 0 0 0 1px var(--line-2); }
  .pic-prev.empty { display: grid; place-items: center; color: var(--ink-3); }
  .pic-prev svg.i { width: 26px; height: 26px; stroke-width: 1.2; }
  .pp-info .ppu-form { margin-top: 4px; padding: 0; background: none; box-shadow: none; }
  .pp-acts.admin { margin-top: -6px; }
  .pp-acts.confirm { align-items: center; margin-top: -6px; }
  .pp-acts.confirm > span { flex: 1 1 200px; font-size: 12.5px; }
  .ff-row.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .chks { display: flex; flex-wrap: wrap; gap: 8px 20px; }
  .chk { display: inline-flex; align-items: center; gap: 8px; font: 600 12px var(--mono); color: var(--ink); cursor: pointer; }
  .chk input { width: 16px; height: 16px; margin: 0; accent-color: var(--blue-ink); }
  .setup-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
  .setup-rows li { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 8px; align-items: center; }
  .setup-rows input { height: var(--ctl); font-size: 13px; }
  .ppu-form .add-row { justify-self: start; }
  .ppu-form .mono { font-family: var(--mono); }
  .lib-top .calm { margin: 0; flex: 1 1 240px; }
  .lib-form { display: grid; gap: 12px; padding: 16px; margin-top: 16px; border-radius: 10px; background: var(--well); box-shadow: inset 0 0 0 1px var(--line-2); }
  .lib-form .msub { margin: 0; }
  .lib-form .cmd-err { margin: 0; }
  .lib-form-acts, .ed-f-row { display: flex; gap: 8px; justify-content: flex-end; align-items: center; }
  .lib-g .sub { margin: 24px 0 8px; }
  .lrows { list-style: none; display: grid; gap: 4px; }
  .lrow { border-radius: 10px; }
  .lrow.open { background: var(--well); box-shadow: inset 0 0 0 1px var(--line-2); }
  .lrow-h { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; row-gap: 2px; width: 100%; padding: 10px 12px; border: 0;
            border-radius: 10px; background: transparent; text-align: left; cursor: pointer; color: var(--ink); }
  .lrow-h:hover { background: var(--hover); }
  .lrow.open .lrow-h:hover { background: transparent; }
  .lrow-t { display: flex; align-items: center; gap: 8px; min-width: 0; }
  .lrow-t b { font: 600 13px var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .lrow-d { grid-column: 1; color: var(--ink-2); font-size: 12px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .lrow-m { grid-column: 2; grid-row: 1; color: var(--ink-3); font-size: 12px; white-space: nowrap; align-self: center; }
  .lrow-a { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 12px 12px; }
  .lrow-a.confirm { align-items: center; }
  .lrow-a.confirm > span { flex: 1 1 200px; font-size: 12.5px; }
  .lrow-err:empty { display: none; }
  .lrow-err { padding: 0 12px 12px; }
  .lrow-err .cmd-err { margin: 0; }
  .lib-empty { padding: 8px 12px; font-size: 12.5px; }

  /* the editor: header, a scrolling body of accordions, a footer that stays put */
  .editor-side { box-shadow: -1px 0 0 var(--line), var(--elev-2); }
  .ed { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .ed-h { flex: none; display: flex; align-items: center; gap: 4px; min-height: 52px; padding: 0 8px 0 16px; border-bottom: 1px solid var(--line); }
  .ed-h h2 { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; font-size: 15px; letter-spacing: -0.01em;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ed-body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; }
  .ed-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: start; }
  .ed-grid > .wide, .ed-grid > .ff.wide, .ed-grid > .wide-btn { grid-column: 1 / -1; }
  .ed-grid .segm { justify-self: start; }
  .ed-grid .segm button { min-width: 44px; }
  .ed-grid + .opt { margin-top: 8px; border-top: 1px solid var(--line-2); }
  .ed .opt { padding: 10px 0; }
  .wide-btn { grid-column: 1 / -1; justify-self: start; }
  .btn[aria-pressed="true"]:not(.bar *) { background: var(--sel-soft); border-color: var(--blue-ink); color: var(--blue-ink); }
  .dims { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
  .dims legend { padding: 0 0 4px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
  .route-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .route-row .calm { margin-right: auto; font-size: 12.5px; }
  .ed-acts { display: flex; justify-content: flex-end; margin-top: 12px; }
  .ed-add { margin-top: 12px; }
  .ed-empty { font-size: 12.5px; margin-bottom: 4px; }
  .sel-add { display: block; }
  .sel-add select { width: 100%; font-weight: 600; color: var(--ink-2); }
  .ev-act { font-size: 13px; line-height: var(--ctl); }

  /* vessel and event rows: cards inside their section, not accordions inside accordions */
  .vaccs { display: grid; gap: 8px; }
  .acc.vacc, .acc.evacc { border: 0; border-radius: 10px; box-shadow: inset 0 0 0 1px var(--line-2); }
  .acc.evacc { margin-top: 8px; }
  .acc.vacc[open], .acc.evacc[open] { box-shadow: inset 0 0 0 1px var(--line), var(--elev-1); }
  .vacc > summary, .evacc > summary { min-height: 48px; padding: 0 12px; border-radius: 10px; gap: 12px; }
  .vacc[open] > summary, .evacc[open] > summary { border-radius: 10px 10px 0 0; }
  .vacc > .acc-b, .evacc > .acc-b { padding: 4px 12px 12px; }
  .vacc-t { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
  .vacc-t b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .vacc-t b.own { color: var(--red); }
  .vacc-t small { color: var(--ink-3); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .dot.ring { background: transparent; box-shadow: inset 0 0 0 1.5px var(--ink-3); margin: 0 3px; }
  .ev-t { min-width: 44px; font: 600 15px var(--instr); color: var(--ink); }

  /* the timeline: a time axis with draggable chips */
  .axis { padding: 4px 0 8px; margin-bottom: 24px; }
  .axis-track { --lane-h: 32px; position: relative; height: calc(var(--lanes) * var(--lane-h) + 8px); margin: 0 4px; border-bottom: 1px solid var(--line); }
  .tick { position: absolute; bottom: -22px; translate: -50% 0; display: grid; justify-items: center; gap: 2px; pointer-events: none; }
  .tick i { width: 1px; height: 6px; background: var(--line); }
  .tick small { font: 600 11px var(--instr); color: var(--ink-3); }
  .evchip { position: absolute; display: flex; align-items: center; gap: 6px; width: 116px; height: 28px; padding: 0 10px; border: 1px solid var(--line);
            border-radius: 999px; background: var(--raised); color: var(--ink-2); font-size: 11.5px; font-weight: 600; cursor: grab; touch-action: none;
            box-shadow: var(--elev-1); user-select: none; }
  .evchip b { font: 600 12px var(--instr); color: var(--ink); flex: none; }
  .evchip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .evchip:hover { border-color: var(--ink-3); }
  .evchip.sel { border-color: var(--blue-ink); background: var(--sel-soft); }
  .evchip.drag { cursor: grabbing; box-shadow: var(--elev-3); z-index: 2; }

  /* footer: problems, notes, actions */
  .ed-f { flex: none; display: grid; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--line); background: var(--panel); }
  .ed-f .cmd-err { margin: 0; }
  .ed-f .lib-form { margin: 0; padding: 0; background: none; box-shadow: none; }
  .ed-f.ask { background: var(--caution-soft); }
  .ed-f.ask p { font-size: 12.5px; }
  .ed-probs { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--caution-ink); }
  .ed-probs .sh { width: 7px; height: 7px; flex: none; background: var(--yellow); }
  .ed-note { font-size: 12px; color: var(--ok-ink); }
  .ed-fine { font-size: 11.5px; color: var(--ink-3); }
  .ed-f-row .grow { flex: 1; }

  /* the chart while drawing */
  .drawbar { position: absolute; left: 50%; bottom: 48px; translate: -50% 0; z-index: 5; display: flex; align-items: center; gap: 12px;
             width: max-content; max-width: calc(100% - 24px); padding: 8px 8px 8px 16px; border-radius: 12px; box-shadow: var(--elev-3), 0 0 0 1px var(--edge); background: var(--raised); }
  .drawbar-t { display: grid; min-width: 0; font-size: 12.5px; }
  .drawbar-t small { color: var(--ink-2); font-size: 12px; }
  .pt-menu { width: 200px; }
  .sheet-acts.pair { display: flex; gap: 8px; }
  .sheet-acts.pair .btn:first-child { flex: none; }

  @media (pointer: coarse) {
    .ed .ff input, .ed .ff select, .lib-form .ff input { font-size: 16px; }
    .evchip { height: 36px; }
    .axis-track { --lane-h: 40px; }
  }
}

/* ---------------------------------------------------------------- narrower screens and the phone */
@layer phone {
  @media (max-width: 1440px) { .ctl select, .ctl-v { max-width: 180px; } }
  @media (max-width: 1280px) { .tabnote { display: none; } }
  @media (max-width: 1180px) {
    .ctl-lbl { display: none; }
    .ctl-in { padding-left: 4px; }
    .ctl select, .ctl-v { max-width: 150px; }
    .bar .btn:not(.pop *) .bl, .ctl-btn .bl { display: none; }
    .bar .btn:not(.pop *):has(.bl) { width: 32px; padding: 0; }
    .bar .btn:not(.pop *).faults-btn:has(.count) { width: auto; padding: 0 8px; }
  }

  @media (max-width: 860px) {
    /* The compass is the main heading instrument on a phone: larger, and its caption never clipped. */
    .compass { min-width: 112px; padding: 10px 10px 8px; }
    .compass svg { width: 96px; height: 96px; }
    .cread { font-size: 13px; }
    .cread .h { font-size: 16px; }
    /* Notch and home-bar safe areas in landscape and when added to the home screen. */
    /* One padding rule: a later shorthand used to reset these and the bar ignored the notch. */
    .bar { gap: 8px; padding: env(safe-area-inset-top) max(8px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); }
    .tabbar { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
    .bar .btn:not(.pop *) { height: 44px; }
    .bar .btn:not(.pop *).icon, .bar .btn:not(.pop *):has(.bl) { width: 44px; }
    .bar .btn:not(.pop *).faults-btn { width: auto; padding: 0 12px; }
    .bar .btn:not(.pop *).faults-btn .bl { display: inline; }
    .hoist, .readout { display: none; }
    /* biome-ignore lint/complexity/noImportantStyles: the phone layout wins over the sidebar widths */ .work { grid-template-columns: minmax(0, 1fr) !important; }
    .work > .chart { grid-column: 1; --ml: 0px; --mr: 0px; --mb: 0px; }

    /* tab bar */
    .tabbar { display: grid; grid-template-columns: repeat(4, 1fr); background: var(--panel); z-index: 3;
              box-shadow: 0 -1px 0 var(--line), 0 -2px 8px oklch(0.19 0.007 258 / .06); padding-bottom: env(safe-area-inset-bottom); }
    .tabbar button { display: grid; justify-items: center; align-content: center; gap: 2px; min-height: 56px; border: 0; background: transparent;
                     color: var(--ink-3); font-size: 11px; font-weight: 600; cursor: pointer; }
    .tabbar button[aria-current="page"] { color: var(--blue-ink); }
    .tabbar .ti { position: relative; display: grid; place-items: center; width: 48px; height: 28px; border-radius: 14px; }
    .tabbar button[aria-current="page"] .ti { background: var(--sel-soft); }
    .tabbar svg.i { width: 20px; height: 20px; }
    .badge { position: absolute; top: -2px; right: 2px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--yellow);
             color: oklch(0.19 0.007 258); font: 700 10px/16px var(--font); font-style: normal; }

    /* sheets rise from the bottom */
    dialog.sheet { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: 20px 20px 0 0; max-height: 92dvh; }
    dialog.sheet[open] { animation: sheet-up .28s var(--ease); }
    dialog.sheet.tall { height: 92dvh; }
    .sheet-h { padding: 24px 8px 8px 16px; touch-action: none; }
    .grip { display: block; }
    .sheet-b { padding: 0 16px calc(16px + env(safe-area-inset-bottom)); }
    .sheet.tall .sheet-b { padding: 0 0 env(safe-area-inset-bottom); display: flex; flex-direction: column; }
    .sheet.tall .side-body { overflow: visible; }
    .sheet.tall .ident { border-top: 1px solid var(--line-2); }
    .sheet.tall .tabs { padding: 0 8px; overflow-x: auto; scrollbar-width: none; }
    .vlist + .add-wrap { margin: 16px 0 0; }
    .vlist + .add-wrap .btn { width: 100%; height: var(--ctl); }
    .sheet.tall .pane { padding: 0 16px 16px; overflow: visible; }
    .editor-sheet .sheet-h { padding-right: 8px; }
    .editor-sheet .sheet-b { padding: 0; }
    .editor-sheet .ed-f { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
    .sheet.tall.lib .sheet-b { display: block; padding: 0 16px calc(24px + env(safe-area-inset-bottom)); }
    .lib-top .btn { flex: 1 1 auto; }
    .lrow-h { grid-template-columns: minmax(0, 1fr); }
    .lrow-m { grid-column: 1; grid-row: auto; }
    .drawbar { bottom: 12px; }
    .sheet .links { overflow-x: auto; }

    /* popovers become bottom sheets too */
    /* biome-ignore lint/complexity/noImportantStyles: beats the UA popover inset and width */ [popover].pop { inset: auto 0 0 0 !important; width: 100% !important; max-width: none; max-height: 85dvh; border-radius: 20px 20px 0 0;
                    padding: 24px 8px calc(16px + env(safe-area-inset-bottom)); box-shadow: var(--elev-4), 0 0 0 1px var(--edge); }
    [popover].pop:popover-open { animation: sheet-up .28s var(--ease); }
    [popover].pop::backdrop { background: var(--scrim); -webkit-backdrop-filter: blur(6px) saturate(1.15); backdrop-filter: blur(6px) saturate(1.15); }
    .pop .grip { display: block; }
    .faults-menu { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
    .faults-menu .pop-h { display: block; padding: 0 16px 8px; font-size: 17px; }
    .layers-menu { padding-left: 16px; padding-right: 16px; }
    .layers-menu .pop-h, .more-menu .pop-h { font-size: 17px; }
    .mitem { min-height: 48px; }
  }
  @keyframes sheet-up { from { transform: translateY(100%); } }

  @media (prefers-reduced-motion: reduce) {
    /* biome-ignore lint/complexity/noImportantStyles: reduced motion must win everywhere */ *, *::before, *::after { transition-duration: 0s !important; animation: none !important; }
  }
}

/* Outside every layer on purpose: maplibre-gl.css is unlayered, and unlayered rules beat layered
   ones whatever their specificity, so inside a layer its ".maplibregl-map { position: relative }"
   won and the map collapsed to 0 px tall. The attribution and scale overrides live here too. */
#map { position: absolute; inset: 0 calc(-1 * var(--mr)) calc(-1 * var(--mb)) calc(-1 * var(--ml)); }
.chart .maplibregl-ctrl-bottom-left, .chart .maplibregl-ctrl-bottom-right { bottom: var(--mb); }
.chart .maplibregl-ctrl-bottom-left, .chart .maplibregl-ctrl-top-left { left: var(--ml); }
.chart .maplibregl-ctrl-bottom-right, .chart .maplibregl-ctrl-top-right { right: var(--mr); }
.chart .maplibregl-ctrl-attrib-button { background-image: none; background-color: transparent; }
.chart .maplibregl-ctrl-attrib-button::after { content: ""; position: absolute; inset: 0; background: var(--ink-2);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 4a6 6 0 1 0 0 12a6 6 0 1 0 0-12zm-.8 2.8h1.6v1.6H9.2zm0 3h1.6v4.4H9.2z'/%3E%3C/svg%3E") center / 20px no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 4a6 6 0 1 0 0 12a6 6 0 1 0 0-12zm-.8 2.8h1.6v1.6H9.2zm0 3h1.6v4.4H9.2z'/%3E%3C/svg%3E") center / 20px no-repeat; }
.chart .maplibregl-ctrl-attrib.maplibregl-compact-show { background: color-mix(in oklch, var(--raised) 92%, transparent); }
.chart .maplibregl-ctrl-scale { background-color: color-mix(in oklch, var(--raised) 85%, transparent); border-color: var(--ink-2); color: var(--ink);
  font: 600 11px/16px var(--instr); letter-spacing: .02em; padding: 0 6px; border-width: 0 1.5px 1.5px; }
.chart:has(.hoist) .maplibregl-ctrl-bottom-left { left: calc(var(--ml) + 120px); }
@media (max-width: 860px) { .chart:has(.hoist) .maplibregl-ctrl-bottom-left { left: 0; } }
.chart .maplibregl-ctrl-attrib { background-color: color-mix(in oklch, var(--raised) 88%, transparent); font-size: 11px; }
.chart .maplibregl-ctrl-attrib a, .chart .maplibregl-ctrl-attrib-inner, .chart .maplibregl-ctrl-attrib-inner * { color: var(--ink-2); }
.chart .maplibregl-ctrl-bottom-left .maplibregl-ctrl, .chart .maplibregl-ctrl-bottom-right .maplibregl-ctrl { margin-bottom: 12px; }
