/* ============================================================
   Average Shore Power Demand Database - stylesheet
   ------------------------------------------------------------
   The Decarbonizer design language, measured from the sandbox
   rather than approximated: a white header closed by a hairline
   rule inset to the gutter, a band of eight summary blocks closed
   by a seam, then de-boxed panels with the row rules carrying the
   structure.

   This tool does NOT take the Decarbonizer's accordions. Those
   exist there because that page has fourteen subsections to fold
   through; this one has seven views and a filter column, so the
   view select stays the navigation and the panels stay open. What
   is taken is everything else: the header rule, the seam, the
   block band, the de-boxing, the table treatment, the square
   corners and the italic justified copy.

   Three things this file does not do, deliberately, because the
   reference does not: draw a frame around a panel, draw a rule
   between two rows of the same list, or draw a vertical rule in a
   table. Spacing separates; the row rules carry the structure.
   ============================================================ */

/* ===== tokens ===== */
:root {
  --navy: #0A1543;
  --green: #2f9e6f;
  --grey: #aab2c2;
  --line: #e6e9f0;
  --soft: #f6f7fa;
  --ets: #c00000;
  --sel-row: #f0f1f3;
  --bg: #fff;
  --paper-warm: #f4f5f8;

  --ink: #15151a;
  --ink-soft: #3d3d47;
  --ink-muted: #6b6b75;

  /* Three weights of line, and they are not interchangeable.
     --rule2 draws table headers and block borders; --rule2-soft
     draws the rows underneath them and should be almost invisible;
     --rule-band draws the two structural seams, which have to be
     seen. One value each to dial. */
  --rule2: rgba(10, 21, 67, .12);
  --rule2-soft: rgba(10, 21, 67, .06);
  --rule-band: rgba(10, 21, 67, .38);

  /* The content column. The header and the wrapper both read this,
     so the header rule cannot drift away from the blocks under it.
     1300px rather than the Decarbonizer's 1180: the vessel table
     has eight columns, one of them a 61-character engine string. */
  --col: 1300px;
  --gutter: 26px;

  /* The single gap governing the summary band: above and below the
     seam, so the band reads with one rhythm. */
  --band-gap: 31px
}

* {
  box-sizing: border-box
}

body {
  font-family: 'Poppins', sans-serif;
  color: var(--ink);
  background: var(--bg);
  margin: 0;
  font-size: 14px;
  line-height: 1.55
}

h3 {
  font-weight: 600;
  margin: 0
}

.wrap {
  max-width: var(--col);
  margin: 0 auto;
  padding: 0 var(--gutter)
}

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

a:hover {
  text-decoration: underline
}

.hidden {
  display: none !important
}

/* ===== shapes ===== */
/* Square corners are the house rule. Stated once as a blanket, with
   the exceptions listed immediately after, so there is one place to
   look rather than a border-radius:0 on every rule in the file. */
#siteHeader *,
#tool * {
  border-radius: 0
}

/* Exception 1: the methodology marker. Squared off, it reads as a
   tiny button rather than as the "there is more here" dot it is.
   Scoped with the id: the blanket above is "#siteHeader *", which
   is (1,0,0), and a bare ".dz-info" at (0,1,0) loses to it. */
#siteHeader .dz-info {
  border-radius: 50%
}

/* Exception 2: the pie charts draw their own arcs, and Chart.js is
   not governed by any of this. Nothing else in the tool is round. */

/* ===== header ===== */
/* Centred in the same column as the content, with the same gutter.
   No border-bottom: a border spans the whole 1300px border box, so
   it would sit 26px proud of the content column at each end. The
   rule is drawn by ::after instead, inset to the gutter, so it
   starts at the left edge of the first block and ends at the right
   edge of Download database at every width. */
.dz-header {
  max-width: var(--col);
  margin: 0 auto;
  background: #fff;
  color: var(--ink);
  padding: 19px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  border-bottom: 0;
  box-shadow: none
}

.dz-header::after {
  content: '';
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: 0;
  border-bottom: 1px solid var(--rule-band)
}

.dz-left {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  min-width: 0
}

.dz-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap
}

.dz-mark {
  font-weight: 600;
  font-size: 1.25rem;
  letter-spacing: -.01em;
  color: var(--navy)
}

.dz-product {
  font-size: .9rem;
  color: var(--ink-soft)
}

.dz-product strong {
  color: var(--navy);
  font-weight: 600
}

.dz-right {
  display: flex;
  align-items: center;
  gap: 10px
}

/* Methodology is a signpost to a reference panel, not an action on
   the selection, so it reads as a marker beside the product name
   rather than competing with Download database for the same weight
   in the same corner. */
.dz-info {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--navy);
  background: #fff;
  color: var(--navy);
  font-family: inherit;
  font-size: 11px;
  font-style: italic;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none
}

.dz-info:hover,
.dz-info.active {
  background: var(--navy);
  color: #fff
}

.dz-save {
  background: var(--navy);
  color: #fff;
  border: 0;
  padding: 9px 16px;
  font-family: inherit;
  font-size: .85rem;
  font-weight: 500;
  cursor: pointer
}

.dz-save:hover {
  background: #16224f
}

#tool {
  /* The page used to stop dead at the footer. A tail gives it
     somewhere to end. */
  padding-bottom: 40px
}

/* ===== summary blocks ===== */
/* No rule of its own and no spine down the middle. The seam
   directly below closes the band, so the page carries two
   horizontal lines in total: the header rule and the summary seam.
   The dotted spine read as clutter inside the block area rather
   than as structure, which is the call the Decarbonizer made when
   it dropped its own. No group headings above the band either:
   that decision stands from the previous pass, and the block
   labels already say what each figure is. */
.blk8 {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: 14px;
  row-gap: 14px;
  margin: 14px 0 0;
  padding: 0;
  border-bottom: 0
}

.blk {
  border: 1px solid var(--rule2);
  background: #fff;
  padding: 12px 13px 11px;
  min-height: 118px;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: border-color .14s
}

.blk:hover {
  border-color: var(--navy)
}

.blk-lab {
  font-size: 10.5px;
  color: var(--ink-muted);
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px
}

.blk-lab-t {
  display: block;
  white-space: nowrap
}

.blk-val {
  font-size: 23px;
  font-weight: 600;
  line-height: 1.15;
  margin-top: auto;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.015em
}

.blk-val.sm {
  font-size: 17px
}

.blk-unit {
  font-size: 12px;
  font-weight: 400;
  color: var(--ink-muted)
}

.blk-sub {
  font-size: 10.5px;
  color: var(--ink-muted);
  margin-top: 3px;
  font-variant-numeric: tabular-nums
}

.blk-sub b {
  font-weight: 500;
  color: var(--ink-soft)
}

/* ===== the summary seam ===== */
/* One hairline in the seam tone, with equal air above and below
   from a single token, so the band reads as one group rather than
   trailing into the panels. This is what the 3px navy border used
   to do, at the weight the reference actually draws it. It also
   carries the air the panels used to add themselves, so there is
   one owner of the gap rather than two. */
.bandseam {
  height: 0;
  border-top: 1px solid var(--rule-band);
  margin: var(--band-gap) 0
}

/* ===== panels ===== */
.split {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare 1fr is minmax(auto, 1fr) and
     grows to its content's min-content width, which the vessel
     table and the three-canvas row both exceed. That widened the
     whole page on those two views. */
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 26px;
  align-items: start
}

/* De-boxed: a panel is its heading and its content, with no frame
   and no rule under the heading. Spacing does the separating. Both
   columns open with one of these, so they sit level without either
   having to be offset by the other's height. */
.acc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0 12px
}

.acc-head h3 {
  font-weight: 500;
  font-size: 1.05rem;
  color: var(--navy)
}

.acc-body {
  border: 0;
  padding: 0
}

.view {
  display: none
}

.view.active {
  display: block;
  min-width: 0
}

/* A caption naming the plot or the table under it. Smaller than a
   heading and centred over what it names. */
.band {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: none;
  color: var(--ink-muted);
  margin: 0 0 10px
}

.band.chart-cap {
  font-size: 10px;
  line-height: 1.35;
  letter-spacing: 0;
  text-align: center
}

/* ===== charts ===== */
.chartbox {
  position: relative;
  /* a Chart.js canvas will not shrink below its own width without
     this, which re-broke the grid track it sits in */
  min-width: 0;
  height: 260px;
  cursor: default;
  contain: layout
}

/* The Decarbonizer packs several charts into one panel; this tool
   shows one at a time, so the single-chart panels add .tall. Drop
   the class to sit exactly on 260. */
.chartbox.tall {
  height: 400px
}

.chartbox.sm {
  height: 210px
}

.grid3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px
}

/* ===== copy ===== */
/* All explanatory copy: italic and justified, so its right edge
   lines up with the charts and tables above it. */
p,
.note {
  font-style: italic;
  text-align: justify;
  hyphens: auto
}

.note {
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--ink-muted);
  margin-top: 18px;
  border-top: 0;
  padding-top: 0;
  white-space: pre-line
}

/* Two notes in a row are one block of small print, not two
   separated paragraphs. */
.note + .note {
  margin-top: 10px
}

/* ===== controls column ===== */
/* De-boxed, like the panel beside it. The heading above it and the
   row rhythm carry the structure. */
.controls {
  border: 0;
  padding: 0
}

/* A filter row. No rule between rows: the uniform height and the
   shared label column carry the alignment, and lines only add
   noise. */
.field {
  min-height: 34px;
  padding: 6px 0;
  margin-bottom: 0
}

label {
  display: block;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  margin-bottom: 5px
}

/* The view select is navigation rather than a filter, so it is
   marked out from the fields below it with a navy edge and closed
   off by a hairline. The hairline separates two GROUPS, which is
   the one place in this file a rule between rows is right. */
.viewfield select {
  border-color: var(--navy);
  font-weight: 500
}

.viewfield {
  padding-bottom: 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--rule2)
}

input[type=text],
input[type=number],
input[type=search],
select {
  width: 100%;
  font-family: inherit;
  font-size: 13px;
  padding: 6px 8px;
  height: 30px;
  border: 1px solid var(--rule2);
  background: #fff;
  color: var(--ink)
}

input[type=number] {
  -moz-appearance: textfield;
  appearance: textfield
}

input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0
}

input:focus,
select:focus,
button:focus-visible {
  outline: 1px solid var(--navy);
  border-color: var(--navy)
}

input:disabled {
  background: var(--soft);
  color: var(--grey);
  cursor: not-allowed
}

.row2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px
}

/* ===== tables ===== */
/* No frame; the row rules carry the structure. No vertical rules,
   ever. A table ends open: the last row draws none. */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  border: 0
}

th,
td {
  text-align: right;
  padding: 6px 9px
}

th:first-child,
td:first-child {
  text-align: left
}

thead th {
  background: transparent;
  color: var(--ink-muted);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule2)
}

td {
  border-bottom: 1px solid var(--rule2-soft)
}

tbody tr:last-child > td {
  border-bottom: 0
}

/* ----- the vessel table ----- */
/* Left-aligned text columns; the four numeric ones stay right. */
.shiptable td:nth-child(2),
.shiptable th:nth-child(2),
.shiptable td:nth-child(3),
.shiptable th:nth-child(3),
.shiptable td:nth-child(4),
.shiptable th:nth-child(4),
.shiptable td:nth-child(6),
.shiptable th:nth-child(6) {
  text-align: left
}

/* 11.5px and wrapping rather than one nowrap line per cell: at
   802px the eight columns cannot hold a 29-character ship type and
   a 61-character engine description on one line each, and clipping
   them to an ellipsis loses the identifying part of the string.
   Names, types and sizes wrap in full; the engine description is
   the only cell still cut, and to two lines rather than a
   fragment. */
.shiptable td,
.shiptable th {
  padding: 7px 9px;
  font-size: 11.5px;
  vertical-align: top;
  white-space: normal;
  word-break: break-word
}

/* Opaque, not transparent: the header is frozen and the rows
   scroll under it. Transparent would let them show through and the
   text would collide. */
.shiptable thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #fff;
  font-size: 10.5px;
  line-height: 1.3;
  vertical-align: bottom
}

/* numeric columns read better on one line */
.shiptable td:nth-child(1),
.shiptable td:nth-child(5),
.shiptable td:nth-child(7),
.shiptable td:nth-child(8) {
  white-space: nowrap
}

/* two lines of engine description, with the full string on hover */
.shiptable .eng {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.35
}

.shiptable tbody tr:hover {
  background: var(--paper-warm)
}

/* The rows scroll inside the box so the page does not grow with the
   selection. The header stays put through it. */
.tablescroll {
  position: relative;
  max-height: 520px;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule2) transparent
}

.tablescroll::-webkit-scrollbar {
  width: 8px;
  height: 8px
}

.tablescroll::-webkit-scrollbar-track {
  background: transparent
}

/* Quieter by colour, not by shape. */
.tablescroll::-webkit-scrollbar-thumb {
  background: var(--rule2)
}

/* Fixed layout so the aux engine description truncates to its
   column instead of setting the table's minimum width. */
.shiptable {
  table-layout: fixed;
  min-width: 760px
}

/* The four numeric columns get enough width for their two-line
   headers, so nothing in the header row clips. */
.shiptable col.c-imo { width: 9% }
.shiptable col.c-name { width: 15% }
.shiptable col.c-type { width: 15% }
.shiptable col.c-size { width: 9% }
.shiptable col.c-gt { width: 7% }
.shiptable col.c-aux { width: 22% }
.shiptable col.c-tot { width: 11% }
.shiptable col.c-avg { width: 12% }

/* ===== methodology panel ===== */
/* No frame: the headings are the structure. The page spans the same
   column as the rest of the tool, so its right edge lines up with
   everything else. */
.mp {
  border: 0;
  padding: 0;
  max-width: none
}

.mp h2 {
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--navy);
  margin: 26px 0 6px
}

.mp h2:first-of-type {
  margin-top: 0
}

.mp h3 {
  font-size: 13px;
  font-weight: 500;
  color: var(--navy);
  margin: 18px 0 4px;
  text-transform: none;
  letter-spacing: 0
}

.mp p {
  margin: 0 0 8px;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.75;
  max-width: none
}

.foot {
  color: var(--ink-muted);
  font-size: 11.5px;
  text-align: center;
  padding: 26px 0 0
}

/* ===== responsive ===== */
@media (max-width: 1100px) {
  .blk8 {
    grid-template-columns: repeat(2, minmax(0, 1fr))
  }
}

@media (max-width: 860px) {
  .split {
    grid-template-columns: minmax(0, 1fr)
  }

  .grid3 {
    grid-template-columns: minmax(0, 1fr)
  }

  .dz-header {
    flex-wrap: wrap;
    gap: 12px
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important
  }
}

/* ============================================================
   Freemium layer
   ------------------------------------------------------------
   Inert on the premium deployment: nothing carries these classes
   unless /init reports the free tier, so both Workers serve the
   same stylesheet and the only difference between them is the
   TIER variable in wrangler.toml.

   The vocabulary is the Decarbonizer Freemium's, so a gate reads
   as the same software across the range rather than as a bolt-on
   per tool: .fm-lock, .fm-cell, .fm-ghost, .fm-snapshot and
   .fm-upgrade. Gated rows stay in the layout, marked, never
   removed.
   ============================================================ */

/* The single lock glyph, drawn rather than typed, so it carries no
   font dependency and no emoji. Coloured by whatever it sits in. */
:root {
  --fm-lock-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 10V7a6 6 0 0 1 12 0v3h1a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h1zm2 0h8V7a4 4 0 0 0-8 0v3z'/%3E%3C/svg%3E")
}

.fm-lock {
  display: inline-block;
  width: 11px;
  height: 11px;
  vertical-align: -1px;
  margin-right: 5px;
  flex: none;
  background: currentColor;
  -webkit-mask: var(--fm-lock-svg) center / contain no-repeat;
  mask: var(--fm-lock-svg) center / contain no-repeat
}

/* A withheld vessel. It keeps its row, at the same height as a real
   one, so a hundred records followed by two hundred of these show
   the depth of the list rather than describing it.

   One cell across the row, not eight. GT is a 7% column and the
   phrase does not fit it; more to the point, a row is what is
   withheld here, so the row says so once. */
.fm-ghost td {
  color: var(--ink-muted);
  background: transparent
}

.fm-ghost:hover td {
  background: var(--soft)
}

.fm-cell {
  display: inline-block;
  color: var(--ink-muted);
  font-style: italic;
  font-size: 11.5px;
  opacity: .75;
  white-space: nowrap;
  overflow-wrap: normal;
  word-break: keep-all
}

/* The data-currency line, sitting above the summary band because it
   qualifies every figure in it. */
.fm-snapshot {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-style: italic;
  color: var(--ink-muted);
  padding-top: 14px
}

/* The single upgrade route. One consistent link, navy, no shouting,
   and it appears once rather than on every withheld row. */
.fm-upgrade {
  color: var(--navy);
  font-weight: 600;
  font-style: normal;
  text-decoration: none;
  border-bottom: 1px solid rgba(10, 21, 67, .35);
  white-space: nowrap
}

.fm-upgrade:hover {
  border-bottom-color: var(--navy);
  text-decoration: none
}

/* A control the free tier pins. Visible at the value it is held to,
   greyed and inert, so the reader can see the range rather than an
   empty box. The field carries the state, not the input alone, so
   the label dims with it. */
.fm-locked {
  opacity: .5;
  cursor: not-allowed
}

.fm-locked input {
  pointer-events: none
}

.fm-locked label {
  cursor: not-allowed
}
