/* ═══════════════════════ MERIDIAN — HELM (editorial layout theme) ═══════════════════════
   The first LAYOUT theme: unlike the colour themes in themes.css, this restructures the shell.
   Activated by webapp/theme.js setting html[data-theme-layout="helm"] (alongside
   data-theme="helm" + data-theme-kind="light", so it also inherits the shared light-family
   structural layer in themes.css and the token block there).

   WHAT CHANGES vs the stock console
     · the left rail becomes a FLOATING GLASS COMMAND BAR docked under the header — the nav
       reads as one horizontal strip of pills instead of a 210px vertical column;
     · the header itself becomes a translucent editorial masthead bar on paper;
     · view headings promote to a large Georgia display serif ("the verdict is a word");
     · every card/box becomes a frosted-glass panel with hover-lift;
     · type moves to an editorial serif + humanist sans pairing, mono reserved for instrument values.

   CONSTRAINTS HONOURED
     · Fonts are INSTALLED faces only (Georgia / -apple-system) — zero network fetch, so the
       CSP (font-src 'self') is untouched and there is no FOUT.
     · The GO/CAUTION/NO-GO verdict triad and the wind ramp are never redefined (safety palette).
     · TYPE FLOOR: nothing here declares a font-size below 11px (tests/test_type_floor.py).
     · Layout is additive and fully reversible — switching to any other theme removes
       data-theme-layout and the stock rail/grid returns untouched.
     · Colour tokens come from the `helm` block in themes.css; this file is structure + type. */

/* ── shell: paper ground, no hard column ── */
html[data-theme-layout="helm"] body{
  background:
    radial-gradient(120% 90% at 12% -10%, #fbf7ef 0%, transparent 55%),
    radial-gradient(120% 120% at 100% 0%, #eae3d4 0%, transparent 45%),
    var(--page);
}
html[data-theme-layout="helm"] #app{ background:transparent; }

/* ── header → editorial masthead bar ── */
html[data-theme-layout="helm"] .topbar{
  background:color-mix(in srgb, #ffffff 62%, transparent);
  backdrop-filter:saturate(160%) blur(20px); -webkit-backdrop-filter:saturate(160%) blur(20px);
  border-bottom:1px solid var(--edge);
  padding:14px 26px; min-height:64px;
}
html[data-theme-layout="helm"] .lock{
  font-family:var(--serif-disp); font-size:24px; font-weight:600; letter-spacing:.4px;
}
html[data-theme-layout="helm"] .lock b{ font-weight:600; color:var(--ink); }
html[data-theme-layout="helm"] .lock::before{
  content:"\2726"; color:var(--brand); font-size:15px; margin-right:9px; text-shadow:none;
}
html[data-theme-layout="helm"] .tag{
  font-size:11px; letter-spacing:2.4px; color:var(--dim); font-family:var(--sans-ui); font-weight:600;
}
html[data-theme-layout="helm"] .search-trigger{
  border-radius:12px; width:38px; height:38px; background:var(--card-solid); border:1px solid var(--edge);
}
html[data-theme-layout="helm"] .search-trigger:hover{
  border-color:var(--brand); box-shadow:0 4px 16px -8px color-mix(in srgb, var(--brand) 75%, transparent);
}

/* ── rail → horizontal floating command bar ──
   The rail keeps its DOM position (first child of #shell) but is re-laid-out as a full-width
   strip above the content, so no JS or markup has to change. */
html[data-theme-layout="helm"] #shell{ display:block; }
html[data-theme-layout="helm"] #rail{
  position:static; width:auto; flex-basis:auto; max-width:none;
  padding:12px 16px; margin:18px 22px 4px;
  border-right:0; border:1px solid rgba(255,255,255,.7); border-radius:20px;
  background:var(--card); backdrop-filter:saturate(160%) blur(20px);
  -webkit-backdrop-filter:saturate(160%) blur(20px);
  box-shadow:0 1px 0 rgba(255,255,255,.6) inset, 0 22px 50px -24px rgba(37,28,15,.45);
  overflow-x:auto; overflow-y:hidden; transform:none;
}
html[data-theme-layout="helm"] #rail .tabs{
  flex-direction:row; align-items:center; gap:4px; width:auto; flex-wrap:wrap;
}
html[data-theme-layout="helm"] .rail-sec{
  flex-direction:row; align-items:center; gap:4px; flex-wrap:wrap;
}
html[data-theme-layout="helm"] .rail-sec + .rail-sec{
  margin-top:0; padding-top:0; border-top:0;
  margin-left:10px; padding-left:12px; border-left:1px solid var(--line2);
}
/* Section captions become quiet inline eyebrows rather than stacked headers. They are set clearly
   BELOW the pills in weight and size so the bar reads as one strip of destinations with dividers,
   not two competing levels. A section whose caption duplicates its only tab (e.g. CLIENTS/CLIENTS)
   would read as a stutter, so a caption immediately followed by a tab of the same name is hidden
   by the :has() rule further down. */
html[data-theme-layout="helm"] .rail-sec-h{
  padding:0 9px 0 0; font-size:11px; letter-spacing:1.7px; color:var(--faint); opacity:.7;
  font-family:var(--sans-ui); font-weight:700; white-space:nowrap; text-transform:uppercase;
}
html[data-theme-layout="helm"] .rail-phase{ display:none; }   /* phase captions are vertical furniture */
/* A one-tab section repeats its own name (CLIENTS ▸ CLIENTS). In a vertical rail that reads as a
   heading; in a horizontal strip it is a visible stutter, so drop the caption and let the pill speak.
   :has() is supported by every browser this PWA targets; where it is not, the caption simply stays. */
html[data-theme-layout="helm"] .rail-sec:has(> .tab:only-of-type) > .rail-sec-h{ display:none; }
html[data-theme-layout="helm"] #rail .tab{
  display:inline-flex; align-items:center; width:auto; white-space:nowrap;
  padding:9px 15px; border-radius:11px; font-family:var(--sans-ui); font-size:13px; font-weight:600;
  letter-spacing:.2px; line-height:1.1; text-align:left;
}
html[data-theme-layout="helm"] #rail .tab.active{
  color:#fff; background:linear-gradient(180deg, var(--sea2), var(--sea));
  box-shadow:0 6px 16px -6px color-mix(in srgb, var(--sea) 70%, transparent);
}
html[data-theme-layout="helm"] #rail .tab.active::before{ display:none; }   /* the vertical edge marker */
html[data-theme-layout="helm"] #rail .tab:hover{ background:color-mix(in srgb, var(--ink) 6%, transparent); }
html[data-theme-layout="helm"] #rail .tab.active:hover{
  background:linear-gradient(180deg, var(--sea2), var(--sea));
}
html[data-theme-layout="helm"] #railScrim{ display:none; }

/* ── content column ── */
html[data-theme-layout="helm"] #main{ overflow:visible; }
html[data-theme-layout="helm"] .view-pad{ padding:26px 26px 40px; background:transparent; }
html[data-theme-layout="helm"] .panel{ background:transparent; }

/* The console's animated ocean canvas paints its own dark scene (app.js drawFrame), which on paper
   reads as a slab bleeding to the frame edge. It stays dark — it is a data-viz surface, like a map
   tile — but it is INSET as a deliberate framed plate: rounded, hairlined and shadowed, so the
   darkness looks chosen rather than left over. */
html[data-theme-layout="helm"] .stage{ padding:0 26px 22px; gap:22px; }
html[data-theme-layout="helm"] .chart-wrap{
  border-right:0; border-radius:20px; overflow:hidden; border:1px solid var(--edge);
  box-shadow:0 22px 50px -24px rgba(37,28,15,.45);
}
html[data-theme-layout="helm"] .stage-anchor .panel-left{ border-right:0; }
html[data-theme-layout="helm"] .stage-anchor .panel-right{ border-left:0; }
/* the HUD sits on the dark plate, so it keeps light ink regardless of the paper theme */
html[data-theme-layout="helm"] .hud-loc{ color:#f2ede3; }

/* ── view headings → editorial display type ── */
html[data-theme-layout="helm"] .vh-title{
  font-family:var(--serif-disp); font-size:clamp(30px,3.4vw,46px); line-height:1.02;
  letter-spacing:-.9px; font-weight:600;
}
html[data-theme-layout="helm"] .vh-eyebrow{
  color:var(--brass-ink); font-family:var(--sans-ui); font-size:11.5px; letter-spacing:3px; font-weight:700;
}
html[data-theme-layout="helm"] .vh-eyebrow::before{ box-shadow:none; }
html[data-theme-layout="helm"] .vhead{ margin-bottom:20px; }

/* ── cards → frosted glass panels with hover lift ── */
html[data-theme-layout="helm"] .box,
html[data-theme-layout="helm"] .cmp-card,
html[data-theme-layout="helm"] .now-card,
html[data-theme-layout="helm"] .stub-card,
html[data-theme-layout="helm"] .ob-metric,
html[data-theme-layout="helm"] .cmd-hero,
html[data-theme-layout="helm"] .kpi{
  background:var(--card); backdrop-filter:saturate(160%) blur(20px);
  -webkit-backdrop-filter:saturate(160%) blur(20px);
  border:1px solid rgba(255,255,255,.7); border-radius:20px;
  box-shadow:0 1px 0 rgba(255,255,255,.6) inset, 0 22px 50px -24px rgba(37,28,15,.4);
  transition:transform .28s cubic-bezier(.2,.8,.2,1), box-shadow .28s;
}
html[data-theme-layout="helm"] .box:hover,
html[data-theme-layout="helm"] .cmp-card:hover,
html[data-theme-layout="helm"] .kpi:hover,
html[data-theme-layout="helm"] .ob-metric:hover{
  transform:translateY(-4px); box-shadow:0 34px 80px -32px rgba(37,28,15,.55);
}
html[data-theme-layout="helm"] .box{ padding:22px 24px; }

/* card headers: serif, no glowing dot */
html[data-theme-layout="helm"] .bh{
  font-family:var(--serif-disp); font-size:19px; font-weight:600; letter-spacing:0;
  text-transform:none; color:var(--ink); padding-left:0; padding-bottom:12px; margin-bottom:14px;
  border-bottom:1px solid var(--line2);
}
html[data-theme-layout="helm"] .bh::before{ display:none; }

/* ── the now-card becomes the masthead: the verdict set as a display word ── */
html[data-theme-layout="helm"] .now-card{ padding:28px 26px; text-align:left; }
html[data-theme-layout="helm"] .now-call{
  font-family:var(--serif-disp); font-size:clamp(38px,4.6vw,62px); line-height:1;
  letter-spacing:-1.4px; font-weight:600; text-shadow:none;
}
html[data-theme-layout="helm"] .now-vessel{
  font-family:var(--sans-ui); font-size:15px; color:var(--dim); margin-top:10px; letter-spacing:0;
}
html[data-theme-layout="helm"] .now-limit{ font-size:13px; color:var(--faint); }
html[data-theme-layout="helm"] .gauge{ margin:16px auto 6px; }
html[data-theme-layout="helm"] .g-num{ font-family:var(--serif-disp); font-weight:600; }
html[data-theme-layout="helm"] .g-lab{ letter-spacing:2.4px; color:var(--faint); }

/* ── key/value rows: airier, mono only for the value ── */
html[data-theme-layout="helm"] .kv{
  padding:11px 0; border-bottom:1px solid var(--line2); border-bottom-style:solid;
}
html[data-theme-layout="helm"] .kv span{ font-family:var(--sans-ui); font-size:14px; color:var(--dim); letter-spacing:0; }
html[data-theme-layout="helm"] .kv b{ font-family:var(--mono); font-size:15px; font-weight:500; }
html[data-theme-layout="helm"] .op-row{ padding:10px 0; }
html[data-theme-layout="helm"] .op-row .opn{ font-family:var(--sans-ui); font-size:14px; }

/* ── buttons → editorial pills ── */
html[data-theme-layout="helm"] .btn{
  font-family:var(--sans-ui); font-size:13px; font-weight:600; letter-spacing:.2px;
  border-radius:12px; padding:10px 18px; text-transform:none;
}
html[data-theme-layout="helm"] .btn:not(.ghost):not(.ok):not(.no){
  background:linear-gradient(180deg, var(--sea2), var(--sea)); color:#fff;
  box-shadow:0 6px 16px -6px color-mix(in srgb, var(--sea) 65%, transparent);
}
html[data-theme-layout="helm"] .btn:not(.ghost):not(.ok):not(.no):hover{
  box-shadow:0 12px 26px -10px color-mix(in srgb, var(--sea) 75%, transparent);
}

/* ── tables: editorial list, generous rows ── */
html[data-theme-layout="helm"] .atable th{
  font-family:var(--sans-ui); font-size:11px; letter-spacing:1.5px; color:var(--faint); font-weight:700;
  padding:12px 12px;
}
html[data-theme-layout="helm"] .atable td{ padding:16px 12px; font-family:var(--sans-ui); font-size:14px; }
html[data-theme-layout="helm"] .atable tr:hover td{ background:color-mix(in srgb, #ffffff 55%, transparent); }

/* ── weather sub-nav → quiet segmented control ── */
html[data-theme-layout="helm"] .weather-subnav{
  background:transparent; border-bottom:1px solid var(--line2); padding:12px 26px;
}
html[data-theme-layout="helm"] .wsub{
  font-family:var(--sans-ui); font-size:13px; font-weight:600; letter-spacing:.2px;
  border-radius:11px; padding:9px 16px; text-transform:none;
}
html[data-theme-layout="helm"] .wsub.on{
  color:#fff; background:linear-gradient(180deg, var(--sea2), var(--sea)); box-shadow:none;
}

/* ── the safety line stays prominent, restyled editorial ── */
html[data-theme-layout="helm"] .disclaimer{
  background:color-mix(in srgb, var(--nogo) 8%, transparent);
  border-top:1px solid color-mix(in srgb, var(--nogo) 22%, transparent);
  letter-spacing:.6px;
}

/* ── theme picker inherits the editorial type ── */
html[data-theme-layout="helm"] .theme-menu .tm-name{ font-family:var(--sans-ui); }
html[data-theme-layout="helm"] .theme-menu .tm-h{ font-family:var(--sans-ui); }

/* ── narrow screens: the command bar wraps instead of scrolling off ── */
@media (max-width:820px){
  html[data-theme-layout="helm"] #rail{ margin:14px 12px 4px; padding:10px 12px; }
  html[data-theme-layout="helm"] .view-pad{ padding:18px 14px 32px; }
  html[data-theme-layout="helm"] .rail-sec + .rail-sec{ margin-left:0; padding-left:0; border-left:0; }
}
