/* ============================================================
   GREENSHIPS PUBLIC SITE — DIRECTION C "SEYIR" (passage chart)
   Loaded AFTER bootstrap.min.css (5.3.0-alpha3).
   Rules:
     - never redefine a Bootstrap class; ride its CSS variables
     - every own component is prefixed  gs-
     - NO url() anywhere in this file (ManifestStaticFilesStorage
       resolves url() targets at collectstatic and fails hard on a
       miss). Images belong in templates via {% static %}.
   ============================================================ */

/* ---------- 1. TOKENS ---------- */
:root {
  /* brand ground, measured off the logo */
  --gs-navy:       #01152E;
  --gs-navy-deep:  #010E1F;
  --gs-grid:       #16375B;
  --gs-contour:    #0A2544;
  --gs-glass:      #7FB6A6;
  --gs-text:       #CBDCE9;
  --gs-head:       #FFFFFF;
  --gs-red:        #C9483A;
  --gs-red-deep:   #A93123;

  /* surfaces + hairlines: chart weight, but each clears 2:1 on navy */
  --gs-surface:    rgba(22, 55, 91, .16);
  --gs-surface-2:  rgba(22, 55, 91, .28);
  --gs-hair:       #235080;
  --gs-hair-soft:  rgba(35, 80, 128, .60);
  /* --gs-hair is chart-weight (2.2:1) and fine for decorative rules, but
     WCAG 1.4.11 wants 3:1 on any border that IDENTIFIES a control. Use
     --gs-hair-strong (3.48:1 on navy) for inputs and buttons only. */
  --gs-hair-strong: #3170A5;
  --gs-fill:       rgba(35, 80, 128, .10);
  --gs-glass-dim:  rgba(127, 182, 166, .55);

  /* type */
  --gs-sans: "Barlow", "Helvetica Neue", Arial, sans-serif;
  --gs-cond: "Barlow Condensed", "Barlow", "Arial Narrow", sans-serif;
  --gs-mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;

  /* metrics */
  --gs-nav-h: 102px;
}
@media (min-width: 992px) { :root { --gs-nav-h: 124px; } }

/* ---------- 2. BOOTSTRAP VARIABLE OVERRIDES ----------
   Specificity 0-2-0 so it beats Bootstrap's own [data-bs-theme=dark]
   block regardless of source order.                                   */
:root,
:root[data-bs-theme="dark"] {
  --bs-primary:              #C9483A;
  --bs-primary-rgb:          201, 72, 58;
  --bs-primary-text-emphasis:#E08D82;
  --bs-primary-bg-subtle:    rgba(201, 72, 58, .14);
  --bs-primary-border-subtle:rgba(201, 72, 58, .45);

  --bs-body-bg:              #01152E;
  --bs-body-bg-rgb:          1, 21, 46;
  --bs-body-color:           #CBDCE9;
  --bs-body-color-rgb:       203, 220, 233;
  --bs-emphasis-color:       #FFFFFF;
  --bs-secondary-color:      rgba(203, 220, 233, .72);
  --bs-tertiary-color:       rgba(203, 220, 233, .52);
  --bs-tertiary-bg:          rgba(22, 55, 91, .28);

  --bs-heading-color:        #FFFFFF;
  --bs-link-color:           #FFFFFF;
  --bs-link-color-rgb:       255, 255, 255;
  --bs-link-hover-color:     #7FB6A6;
  --bs-link-hover-color-rgb: 127, 182, 166;

  --bs-border-color:         #235080;
  --bs-border-color-translucent: rgba(35, 80, 128, .60);

  --bs-focus-ring-color:     rgba(127, 182, 166, .55);
  --bs-focus-ring-width:     2px;

  --bs-body-font-family:     var(--gs-sans);
  --bs-body-font-size:       1rem;
  --bs-body-line-height:     1.65;
  --bs-font-monospace:       var(--gs-mono);
}

/* ---------- 2b. SCROLL REVEAL ----------
   Armed only by the inline script in base.html, which adds .gs-js to <html>
   and takes it back off if site.js never reports in. Without that class these
   rules do nothing and every block is visible — a broken script can hide
   content on a page like this only if you let the stylesheet hide it alone.

   Motion is deliberately small: a 14px lift over .55s. The audience is a
   technical manager scanning for a deadline, not an audience for a showreel. */
.gs-js .gs-reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity   .55s cubic-bezier(.22, .61, .36, 1) var(--gs-reveal-d, 0ms),
    transform .55s cubic-bezier(.22, .61, .36, 1) var(--gs-reveal-d, 0ms);
}
.gs-js .gs-reveal.is-in {
  opacity: 1;
  transform: none;
}
/* Belt and braces: the inline script already refuses to arm under reduced
   motion, but a visitor who flips the OS setting mid-session gets the same
   answer without a reload. */
@media (prefers-reduced-motion: reduce) {
  .gs-js .gs-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- 3. BASE ---------- */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--gs-navy);
  color: var(--gs-text);
  font-family: var(--gs-sans);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, canvas, video { max-width: 100%; }
img { border: 0; height: auto; }

/* in-page anchors must clear the sticky bar */
[id] { scroll-margin-top: calc(var(--gs-nav-h) + 1rem); }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--gs-cond);
  color: var(--gs-head);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: .025em;
  text-transform: uppercase;
}

/* Keyboard focus must stay visible on every interactive element,
   including the ones Bootstrap resets. */
:focus-visible {
  outline: 2px solid var(--gs-glass);
  outline-offset: 3px;
  border-radius: 1px;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--gs-glass);
  outline-offset: 3px;
  box-shadow: none;
}

::selection { background: var(--gs-red); color: #fff; }

/* skip link — visible only on keyboard focus */
.gs-skip {
  position: absolute; left: -9999px; top: 0; z-index: 2000;
  background: var(--gs-red); color: #fff;
  padding: .75rem 1.25rem;
  font-family: var(--gs-mono); font-size: .875rem;
  letter-spacing: .12em; text-transform: uppercase;
  text-decoration: none;
}
.gs-skip:focus { left: 0; }

/* ---------- 4. TYPE HELPERS ---------- */
/* ---- Result sections ----------------------------------------------------
   The results used to be one flat run of eyebrows: "Rating 2025", "Workings",
   "The CO2, fuel by fuel", "IMO Net-Zero Framework" all at the same weight,
   so nothing said where CII ended and the draft framework began. This is the
   level above them — the eyebrows keep their job of labelling what follows,
   and this one names the regulation the whole block is about. */
.gs-cii-sec {
  font-family: var(--gs-cond);
  font-weight: 700;
  font-size: 2.35rem;
  line-height: 1.05;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--gs-head);
  margin: 3.25rem 0 1.5rem;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--gs-hair);
}
.gs-cii-sec:first-child { margin-top: 0; }
/* The name spelled out. Set quietly and in sentence case so it reads as a
   gloss on the acronym rather than a second thing being shouted — the page
   says GFI and CII everywhere else, and the heading should not make the
   reader work out that these are the same thing. */
.gs-cii-sec__long {
  display: inline-block;
  font-family: var(--gs-sans);
  font-weight: 400;
  font-size: .44em;
  letter-spacing: .01em;
  text-transform: none;
  color: var(--gs-glass);
}
@media (max-width: 575.98px) {
  .gs-cii-sec { font-size: 1.85rem; }
  .gs-cii-sec__long { display: block; margin-top: .2rem; }
}

.gs-eyebrow {
  font-family: var(--gs-mono);
  font-size: .8125rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin: 0 0 1rem;
  font-variant-numeric: tabular-nums;
}
.gs-mono,
.gs-num {
  font-family: var(--gs-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
}
.gs-h1 {
  font-size: clamp(2.6rem, 6.6vw, 4.6rem);
  line-height: .94;
  letter-spacing: .015em;
  margin: 0 0 1.25rem;
}
.gs-h1 span { display: block; }
.gs-h1__b { color: var(--gs-text); }

.gs-h2 { font-size: clamp(2.1rem, 5vw, 3.5rem); line-height: 1; margin: 0; }
.gs-h3 { font-size: clamp(1.35rem, 2.2vw, 1.6rem); letter-spacing: .03em; margin: 0; }
.gs-h4 { font-size: 1.125rem; letter-spacing: .04em; margin: 0; }

.gs-lead {
  font-size: clamp(1.0625rem, 1.6vw, 1.3125rem);
  line-height: 1.5;
  color: var(--gs-head);
  font-weight: 500;
}
.gs-body { color: var(--gs-text); }
.gs-muted { color: rgba(203, 220, 233, .72); }
.gs-rule { height: 1px; background: var(--gs-hair); border: 0; margin: 0; opacity: 1; }

/* long-form copy blocks (services / about bodies) */
/* Long-form body copy. Wide, because a measure that stops two thirds
   across a desktop screen reads as an accident, but not unbounded —
   the full 1320px container is about 110 characters a line. */
.gs-prose { max-width: 92ch; }
/* Full container instead of the 92ch measure, for a block that sits directly
   under a lead paragraph spanning the whole width: the measure is what makes
   the copy stop two thirds across while the line above it does not. */
.gs-prose--wide { max-width: none; }
.gs-prose p { margin: 0 0 1.15rem; }
.gs-prose p:last-child { margin-bottom: 0; }
.gs-prose ul, .gs-prose ol { margin: 0 0 1.15rem; padding-left: 1.1rem; }
.gs-prose li { margin-bottom: .5rem; }
.gs-prose li::marker { color: var(--gs-glass); }
.gs-prose h3, .gs-prose h4 { margin: 2rem 0 .85rem; }
.gs-prose h3:first-child, .gs-prose h4:first-child { margin-top: 0; }
.gs-prose a { color: var(--gs-head); text-decoration: underline; text-decoration-color: var(--gs-glass-dim); text-underline-offset: 3px; }
.gs-prose a:hover { text-decoration-color: var(--gs-glass); }

/* ---------- 5. NAVBAR ---------- */
.gs-nav {
  position: sticky; top: 0; z-index: 1030;
  background: rgba(1, 21, 46, .94);
  border-bottom: 1px solid var(--gs-hair-soft);
  padding: 0;
  transition: background-color .22s ease, border-color .22s ease;
}
@supports (backdrop-filter: blur(10px)) {
  .gs-nav { background: rgba(1, 21, 46, .82); backdrop-filter: blur(12px); }
}
/* The bar shares the page container, so the logo starts on the same left edge
   as every heading below it and the sign-in button ends on the same right
   edge. Running the bar to the viewport edges instead was tried and put the
   logo 77px left of the content at 1440 and 317px at 1920 — a gap that moved
   with the window, which reads as a mistake rather than a decision. */
.gs-nav > .container { min-height: var(--gs-nav-h); }

.gs-nav--scrolled {
  background: rgba(1, 21, 46, .97);
  border-bottom-color: var(--gs-hair);
}

/* Pages that open on a full-bleed hero add gs-page--immersive to <body>.
   The hero then slides up under the transparent bar; the bar solidifies
   on scroll or whenever the mobile menu is open. */
.gs-page--immersive .gs-hero {
  margin-top: calc(-1 * var(--gs-nav-h));
  padding-top: calc(var(--gs-nav-h) + 3.5rem);
}
.gs-page--immersive .gs-nav {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.gs-page--immersive .gs-nav.gs-nav--scrolled,
.gs-page--immersive .gs-nav.gs-nav--open {
  background: rgba(1, 21, 46, .97);
  border-bottom-color: var(--gs-hair);
}
@supports (backdrop-filter: blur(10px)) {
  .gs-page--immersive .gs-nav.gs-nav--scrolled { background: rgba(1, 21, 46, .90); backdrop-filter: blur(12px); }
}

.gs-nav__brand { display: inline-flex; align-items: center; padding: .5rem 0; }
.gs-nav__logo { width: 237px; height: auto; display: block; }
@media (min-width: 992px) { .gs-nav__logo { width: 285px; } }

.gs-nav__toggler {
  border: 1px solid var(--gs-hair-strong);
  border-radius: 0;
  padding: .45rem .6rem;
  background: transparent;
  line-height: 1;
}
.gs-nav__toggler:focus { box-shadow: none; }
.gs-nav__bars { display: block; width: 22px; height: 14px; position: relative; }
.gs-nav__bars i {
  position: absolute; left: 0; right: 0; height: 1.5px;
  background: var(--gs-text);
  transition: transform .2s ease, opacity .2s ease;
}
.gs-nav__bars i:nth-child(1) { top: 0; }
.gs-nav__bars i:nth-child(2) { top: 6.25px; }
.gs-nav__bars i:nth-child(3) { bottom: 0; }
.gs-nav__toggler[aria-expanded="true"] .gs-nav__bars i:nth-child(1) { transform: translateY(6.25px) rotate(45deg); }
.gs-nav__toggler[aria-expanded="true"] .gs-nav__bars i:nth-child(2) { opacity: 0; }
.gs-nav__toggler[aria-expanded="true"] .gs-nav__bars i:nth-child(3) { transform: translateY(-6.25px) rotate(-45deg); }

.gs-nav__collapse { flex-basis: 100%; }
@media (max-width: 991.98px) {
  .gs-nav__collapse {
    border-top: 1px solid var(--gs-hair-soft);
    margin-top: .25rem;
    padding: .5rem 0 1.25rem;
  }
}

.gs-nav__list { gap: 0; }
@media (min-width: 992px) { .gs-nav__list { gap: 1.75rem; } }

.gs-nav__link {
  display: inline-block;
  font-family: var(--gs-mono);
  font-size: .875rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--gs-text);
  text-decoration: none;
  padding: .7rem 0;
  border-bottom: 1px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
@media (min-width: 992px) { .gs-nav__link { font-size: .8125rem; letter-spacing: .16em; padding: .4rem 0; } }
.gs-nav__link:hover { color: var(--gs-head); border-bottom-color: var(--gs-glass); }
.gs-nav__link.is-active { color: var(--gs-head); border-bottom-color: var(--gs-red); }

/* ---------- NAV DROPDOWN ----------
   The trigger is a button so the browser gives it the right role, which means
   resetting what a button brings with it before .gs-nav__link can take over.
   Everything rides on Bootstrap's dropdown behaviour; only the look is ours. */
.gs-nav__link--drop {
  background: none;
  border: 0;
  border-bottom: 1px solid transparent;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: .45rem;
}
.gs-nav__link--drop svg { flex: 0 0 auto; transition: transform .18s ease; }
.gs-nav__drop.show .gs-nav__link--drop { color: var(--gs-head); }
.gs-nav__drop.show .gs-nav__link--drop svg { transform: rotate(180deg); }

.gs-nav__menu {
  background: rgba(1, 21, 46, .97);
  border: 1px solid var(--gs-hair);
  border-radius: 0;
  padding: .35rem 0;
  margin-top: .5rem;
  min-width: 15rem;
}
@supports (backdrop-filter: blur(10px)) {
  .gs-nav__menu { background: rgba(1, 21, 46, .90); backdrop-filter: blur(12px); }
}
.gs-nav__menuitem {
  display: block;
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--gs-text);
  text-decoration: none;
  padding: .6rem 1rem;
  border-left: 2px solid transparent;
  transition: color .18s ease, background-color .18s ease, border-color .18s ease;
}
.gs-nav__menuitem:hover,
.gs-nav__menuitem:focus-visible {
  color: var(--gs-head);
  background: var(--gs-surface-2);
  border-left-color: var(--gs-glass);
}

/* Inside the collapsed menu the panel floats over nothing, so it drops the
   frame and indents instead, the way a sub-list should read. */
@media (max-width: 991.98px) {
  .gs-nav__menu {
    background: none; backdrop-filter: none;
    border: 0; border-left: 1px solid var(--gs-hair-soft);
    margin: 0 0 .35rem .25rem; padding: 0 0 0 .25rem;
    min-width: 0;
  }
  .gs-nav__menuitem { padding: .55rem .75rem; }
}

.gs-nav__cta {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--gs-cond); font-weight: 700;
  font-size: 1.15rem; letter-spacing: .1em; text-transform: uppercase;
  color: #FFFFFF; background: var(--gs-red);
  border: 1px solid var(--gs-red);
  text-decoration: none;
  padding: .6rem 1.4rem;
  transition: background-color .18s ease, border-color .18s ease;
}
.gs-nav__cta:hover { background: var(--gs-red-deep); border-color: var(--gs-red-deep); color: #fff; }
@media (max-width: 991.98px) { .gs-nav__cta { margin-top: .85rem; } }

/* ---------- 6. HERO ---------- */
.gs-hero {
  position: relative;
  /* The hero owns the first screen exactly: it ends where the fold is, so
     whatever follows starts below it. At 88vh it stopped short, and on the
     home page — the only immersive one, where the hero also slides up under
     the navbar and gives that height back — the regulation band was left
     sitting in the gap. Immersive heroes start at the top of the viewport and
     take all of it; the rest start under the bar and take what is left. */
  min-height: max(560px, calc(100vh - var(--gs-nav-h)));
  display: flex;
  align-items: center;
  padding: 4.5rem 0 3rem;
  overflow: hidden;
  border-bottom: 1px solid var(--gs-hair);
}
.gs-page--immersive .gs-hero { min-height: max(560px, 100vh); }
/* Mobile browsers report 100vh as the chrome-less height, which leaves the
   hero taller than the screen until the bar retracts. dvh is the real one. */
@supports (height: 100dvh) {
  .gs-hero { min-height: max(560px, calc(100dvh - var(--gs-nav-h))); }
  .gs-page--immersive .gs-hero { min-height: max(560px, 100dvh); }
}
.gs-hero--compact { min-height: 0; padding: 4rem 0 3.5rem; }
@media (min-width: 992px) { .gs-hero--compact { padding: 6rem 0 5rem; } }

.gs-hero__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* The title block carries its own .84 navy plate, so the scrim only has to
   settle the ground around it — a heavier wash flattens the red passage
   line, the one element the whole direction rests on. */
.gs-hero__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(1,21,46,.85) 0%, rgba(1,21,46,0) 22%),
    linear-gradient(90deg, rgba(1,21,46,.80) 0%, rgba(1,21,46,.30) 38%, rgba(1,21,46,0) 60%),
    linear-gradient(0deg, rgba(1,21,46,.55) 0%, rgba(1,21,46,0) 20%);
}
.gs-hero__inner { position: relative; z-index: 10; width: 100%; }

.gs-titleblock {
  border: 1px solid var(--gs-hair);
  background: rgba(1, 21, 46, .84);
  padding: 1.75rem 1.5rem;
  position: relative;
}
.gs-titleblock::before,
.gs-titleblock::after { content: ""; position: absolute; width: 12px; height: 12px; pointer-events: none; }
.gs-titleblock::before {
  top: -1px; left: -1px;
  border-top: 2px solid var(--gs-glass); border-left: 2px solid var(--gs-glass);
}
.gs-titleblock::after {
  bottom: -1px; right: -1px;
  border-bottom: 2px solid var(--gs-glass); border-right: 2px solid var(--gs-glass);
}
@media (min-width: 768px) { .gs-titleblock { padding: 2.5rem 2.25rem; } }

.gs-hero__meta {
  border-top: 1px solid var(--gs-hair);
  margin: 1.75rem 0 0;
  padding-top: 1.1rem;
  font-family: var(--gs-mono);
  font-size: .8125rem;
  letter-spacing: .12em;
  color: var(--gs-glass);
  font-variant-numeric: tabular-nums;
}

/* ---------- 7. BUTTONS / LINKS ---------- */
.gs-btn {
  display: inline-flex; align-items: center; gap: .625rem;
  font-family: var(--gs-cond); font-weight: 700;
  font-size: 1.0625rem; letter-spacing: .09em; text-transform: uppercase;
  text-decoration: none;
  padding: .85rem 1.5rem;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.gs-btn svg { flex: 0 0 auto; }
.gs-btn--primary { background: var(--gs-red); color: #FFFFFF; border-color: var(--gs-red); }
.gs-btn--primary:hover { background: var(--gs-red-deep); border-color: var(--gs-red-deep); color: #fff; }
.gs-btn--ghost { border-color: var(--gs-hair-strong); color: var(--gs-head); }
.gs-btn--ghost:hover { border-color: var(--gs-glass); color: var(--gs-head); background: var(--gs-surface); }

.gs-link {
  color: var(--gs-head);
  text-decoration: none;
  border-bottom: 1px solid var(--gs-glass-dim);
  padding-bottom: 2px;
  transition: border-color .18s ease;
}
.gs-link:hover { border-bottom-color: var(--gs-glass); color: var(--gs-head); }
.gs-link--mono {
  /* An address is one unbreakable word. In a narrow column this one ran
     past the viewport and gave the whole page a horizontal scrollbar on a
     phone, which is a long way to travel for a mailto. */
  overflow-wrap: anywhere;
  font-family: var(--gs-mono); font-size: .9375rem; letter-spacing: .06em; }

/* ---------- 8. NOTICE STRIP ---------- */
.gs-notice { border-bottom: 1px solid var(--gs-hair); background: var(--gs-surface); }
.gs-notice__scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--gs-hair) transparent;
  /* cancel the .container padding so the band spans the page, not the padded
     box inside it */
  margin-left: -.75rem; margin-right: -.75rem;
}
/* Six regimes, one row, each cell stacking the name over its citation. On one
   line each they needed 1493px inside a 1320px container and broke into a
   ragged three-and-three; stacked, the widest cell is under 220px. Columns
   take their content rather than an equal share, and the row is centred as a
   group: split six ways the short citations floated in the middle of a cell
   far wider than they needed, and the band read as unevenly spaced. */
.gs-notice__list {
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: center;
  padding: 0; margin: 0; list-style: none;
}
@media (min-width: 576px) { .gs-notice__list { grid-template-columns: repeat(3, auto); } }
/* Six across only from 1200px. At 992 the cells fall to 160px and four of
   the six citations wrap, which reads worse than three wide columns. */
@media (min-width: 1200px) { .gs-notice__list { grid-template-columns: repeat(6, auto); } }
.gs-notice__list li {
  position: relative;
  display: flex; flex-direction: column; justify-content: center; gap: .3rem;
  padding: 1.05rem .8rem;
  text-align: center;
  font-family: var(--gs-mono);
  font-variant-numeric: tabular-nums;
}
/* The name is what gets scanned, so it carries the accent and the weight; the
   citation sits under it, quieter and tighter. */
.gs-notice__list b {
  color: var(--gs-glass); font-weight: 500;
  font-size: .9375rem; letter-spacing: .18em; text-transform: uppercase;
  line-height: 1.1;
}
.gs-notice__list span {
  color: var(--gs-text);
  font-size: .8125rem; letter-spacing: .06em; text-transform: uppercase;
  line-height: 1.35;
}
/* Inset to the cell padding, so it reads as a rule between two labels rather
   than a table gridline. Dropped from whichever cell ends the row at each
   column count, which a grid can name and a wrapped flex row cannot. */
.gs-notice__list li::after {
  content: "";
  position: absolute; right: 0; top: 1.05rem; bottom: 1.05rem;
  width: 1px; background: var(--gs-hair-soft);
}
.gs-notice__list li:nth-child(2n)::after { content: none; }
@media (min-width: 576px) {
  .gs-notice__list li:nth-child(2n)::after { content: ""; }
  .gs-notice__list li:nth-child(3n)::after { content: none; }
}
@media (min-width: 1200px) {
  .gs-notice__list li:nth-child(3n)::after { content: ""; }
  .gs-notice__list li:nth-child(6n)::after { content: none; }
}

/* ---------- 9. SECTIONS ---------- */
.gs-section { padding: 4.5rem 0; position: relative; }
@media (min-width: 992px) { .gs-section { padding: 7rem 0; } }
.gs-section--tint {
  background: var(--gs-surface);
  border-top: 1px solid var(--gs-hair);
  border-bottom: 1px solid var(--gs-hair);
}
.gs-section--tight { padding: 3rem 0; }
.gs-sechead__no {
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .2em;
  color: var(--gs-head);
  font-variant-numeric: tabular-nums;
}

/* ---------- 10. LEGEND CARD (regulation module) ---------- */
.gs-legend {
  position: relative;
  border: 1px solid var(--gs-hair);
  background: var(--gs-fill);
  padding: 1.5rem 1.35rem 1.6rem;
  height: 100%;
  transition: border-color .2s ease, background-color .2s ease;
}
.gs-legend:hover { border-color: var(--gs-glass-dim); background: var(--gs-surface-2); }
.gs-legend:focus-within { border-color: var(--gs-glass); }
.gs-legend__mark { position: absolute; top: 10px; right: 10px; opacity: .85; }
.gs-legend__no {
  font-family: var(--gs-mono);
  font-size: .875rem; letter-spacing: .18em;
  color: var(--gs-glass);
  font-variant-numeric: tabular-nums;
  display: block; margin-bottom: .9rem;
}
.gs-legend__title {
  font-size: 1.5rem; letter-spacing: .035em;
  margin: 0 0 .75rem; padding-right: 1.75rem; line-height: 1.05;
}
.gs-legend__body { font-size: 1rem; line-height: 1.65; margin: 0 0 1.25rem; }
.gs-legend__tag {
  display: inline-block;
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gs-glass);
  border: 1px solid var(--gs-hair);
  padding: .3rem .55rem;
  font-variant-numeric: tabular-nums;
  /* A card can carry three of these. Inline-block with no margin left them
     touching edge to edge once they wrapped onto their own lines, which read
     as one box divided rather than three separate ones. The .5rem matches the
     gap between the chips on the rail, which are the same pattern. */
  margin: 0 .5rem .5rem 0;
}

/* ---------- 11. SPEC TABLE ---------- */
.gs-spec { border-top: 1px solid var(--gs-hair); margin: 0; }
.gs-spec__row {
  display: flex; flex-wrap: wrap;
  border-bottom: 1px solid var(--gs-hair);
  padding: .85rem 0;
  gap: .25rem 1.5rem;
}
.gs-spec__k {
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gs-glass);
  flex: 0 0 auto; width: 100%;
  padding-top: .15rem;
}
@media (min-width: 576px) { .gs-spec__k { width: 148px; } }
.gs-spec__v { flex: 1 1 220px; font-size: .9375rem; color: var(--gs-text); }

/* ---------- 12. THEME RAIL ---------- */
/* Chips rather than words divided by rules. A centred row cannot use the
   divider trick the left-aligned one did — that relies on every row starting
   at x=0 so the leading rule falls under an overflow clip — and a rule that
   dangles at the end of a wrapped row was the original complaint. A closed
   border belongs to its own item, so it centres and wraps at any width with
   nothing left hanging. The type is the rail's own condensed caps, so this
   reads as the same element it was, not as the small mono tags on the cards. */
.gs-rail {
  display: flex; flex-wrap: wrap; gap: .5rem;
  justify-content: center;
  border-top: 1px solid var(--gs-hair);
  padding-top: 1.5rem; margin-top: 2rem;
}
.gs-rail span {
  font-family: var(--gs-cond);
  font-size: 1.0625rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gs-glass);
  border: 1px solid var(--gs-hair);
  padding: .3rem .9rem;
}
/* The roles sit under a spec table that already draws a rule. */
.gs-rail--plain { margin-top: 1.5rem; padding-top: 0; border-top: 0; }
/* "Used by" labels the row, so it is not boxed like the things it labels. */
.gs-rail__lead {
  border-color: transparent; color: var(--gs-text); opacity: .68;
  padding-left: 0; padding-right: .35rem;
}

/* ---------- 13. WAYPOINT ROUTE STRIP + PROJECT CARD ---------- */
/* Route draw-on. Armed by .gs-js exactly like the block reveal, so a visitor
   who asked for reduced motion — or whose site.js never loaded — gets the
   finished line rather than an empty strip. --gs-route-len is written by
   site.js from the measured length; the fallback keeps the line hidden rather
   than half-drawn if that ever fails to run after the class is on.
   Waypoint delays are set to roughly when the line reaches each one. */
.gs-js .gs-legs__route {
  stroke-dasharray: var(--gs-route-len, 2000);
  stroke-dashoffset: var(--gs-route-len, 2000);
  transition: stroke-dashoffset 1.4s cubic-bezier(.33, .02, .28, 1);
}
.gs-js .gs-legs.is-in .gs-legs__route { stroke-dashoffset: 0; }

.gs-js .gs-legs__wp { opacity: 0; transition: opacity .45s ease var(--gs-wp-d, 0ms); }
.gs-js .gs-legs.is-in .gs-legs__wp { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .gs-js .gs-legs__route { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
  .gs-js .gs-legs__wp { opacity: 1; transition: none; }
}

/* ---------- HERO ARTWORK DRAW-ON ----------
   Same contract as the route strip. The accent path is hidden by a dash as
   long as itself and draws once; the marks fade in behind it, each on its own
   delay so they land as the line reaches them. Armed by .gs-js, which the head
   script only sets when the visitor has not asked for reduced motion, so with
   JavaScript absent or motion reduced the drawing is simply there from the
   first paint rather than never arriving. */
/* Everything hangs off .is-armed, which the script adds only once it has
   measured the path. Hiding the line first and revealing it later would mean
   a visitor holding a stale copy of site.js — one that predates this and never
   adds the class — sees the accent hidden for good. Nothing hides until the
   code that un-hides it has proven it is present. */
/* The transition lives on the revealed state, not the hidden one. With it on
   both, arming and revealing land a frame apart and the browser transitions
   into the hidden state and straight back out of it, so the line never goes
   away and there is nothing to watch. Hidden must arrive instantly; only the
   reveal is animated. */
.gs-js .gs-hero__canvas.is-armed .gs-hero__draw {
  stroke-dasharray: var(--gs-draw-len, 2400);
  stroke-dashoffset: var(--gs-draw-len, 2400);
}
.gs-js .gs-hero__canvas.is-armed.is-drawn .gs-hero__draw {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.8s cubic-bezier(.33, .02, .28, 1);
}

.gs-js .gs-hero__canvas.is-armed .gs-hero__wp { opacity: 0; }
.gs-js .gs-hero__canvas.is-armed.is-drawn .gs-hero__wp {
  opacity: 1; transition: opacity .5s ease var(--gs-wp-d, 800ms);
}

@media (prefers-reduced-motion: reduce) {
  .gs-js .gs-hero__canvas.is-armed .gs-hero__draw {
    stroke-dasharray: none; stroke-dashoffset: 0;
  }
  .gs-js .gs-hero__canvas.is-armed.is-drawn .gs-hero__draw { transition: none; }
  .gs-js .gs-hero__canvas.is-armed .gs-hero__wp { opacity: 1; }
  .gs-js .gs-hero__canvas.is-armed.is-drawn .gs-hero__wp { transition: none; }
}

/* ---------- READ MORE ----------
   Native <details>, deliberately. The body stays in the DOM whether it is open
   or not, so a crawler indexes it, Find-in-page reaches it, and the control
   works with the keyboard and without a single line of JavaScript. A scripted
   accordion on a 5,000-word page would put all of that at risk for nothing. */
.gs-more { margin-top: 1.3rem; }
.gs-more > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gs-glass);
  padding: .35rem 0;
  border-bottom: 1px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.gs-more > summary::-webkit-details-marker { display: none; }
.gs-more > summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 1.4px solid currentColor;
  border-bottom: 1.4px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform .2s ease;
}
.gs-more[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
.gs-more > summary:hover { color: var(--gs-head); border-bottom-color: var(--gs-glass); }
.gs-more > summary:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 3px; }
.gs-more[open] > summary { margin-bottom: 1.3rem; }

/* One control, two labels. */
.gs-more .gs-more__close { display: none; }
.gs-more[open] .gs-more__open { display: none; }
.gs-more[open] .gs-more__close { display: inline; }

@media (prefers-reduced-motion: reduce) {
  .gs-more > summary::after { transition: none; }
}

/* Vessel profile drawing (home, contact section). Sits in a drawing frame the
   way a general arrangement sits in its border, with the caption reading as a
   title block rather than a photo credit. */
.gs-ship svg { display: block; width: 100%; height: auto; }

.gs-legs { position: relative; height: 132px; margin-bottom: .5rem; }
.gs-legs__svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.gs-legs__wp { position: absolute; width: 22px; height: 22px; transform: translate(-50%, -50%); }
.gs-legs__wp svg { display: block; }
.gs-legs__wp .gs-legs__lbl {
  position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
}
.gs-legs__lbl {
  font-family: var(--gs-mono);
  font-size: .75rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gs-glass);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gs-proj { border-top: 1px solid var(--gs-hair); padding-top: 1.35rem; height: 100%; }
.gs-proj__no {
  font-family: var(--gs-mono);
  font-size: 3.25rem; line-height: 1;
  color: var(--gs-head);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  display: block; margin-bottom: .35rem;
}
.gs-proj__unit {
  font-family: var(--gs-mono);
  font-size: .75rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gs-glass);
  display: block; margin-bottom: 1.1rem;
}
.gs-proj__title { font-size: 1.375rem; margin: 0 0 .6rem; letter-spacing: .035em; }
.gs-proj__body { font-size: .9375rem; margin: 0; }
.gs-proj__wpm { align-items: center; gap: .55rem; margin-bottom: .9rem; }

/* The projects page gives each waypoint its own section and carries the same
   figure there at section scale, so the number reads as the headline it is. */
.gs-proj__no--lg { font-size: clamp(3.25rem, 7.5vw, 4.75rem); line-height: .95; }

/* On the index grid the card title doubles as the jump link to that section.
   Colour is inherited so the link is not a second accent competing with the
   red waypoint marks; the underline only lights up on hover. */
.gs-proj__title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--gs-hair);
  padding-bottom: 2px;
  transition: border-color .18s ease;
}
.gs-proj__title a:hover { border-bottom-color: var(--gs-red); }

/* ---------- 14. QUOTE BAND ---------- */
.gs-quote {
  border-top: 1px solid var(--gs-hair);
  border-bottom: 1px solid var(--gs-hair);
  padding: 2.5rem 0 2.5rem 1.35rem;
  margin: 0;
  position: relative;
}
.gs-quote::before {
  content: ""; position: absolute; left: 0; top: 2.5rem; bottom: 2.5rem;
  width: 2px; background: var(--gs-red);
}
@media (min-width: 992px) { .gs-quote { padding: 3.25rem 0 3.25rem 2rem; } }
.gs-quote__text {
  font-family: var(--gs-cond); font-weight: 600;
  font-size: clamp(1.45rem, 3.2vw, 2.35rem);
  line-height: 1.15; letter-spacing: .02em;
  color: var(--gs-head);
  margin: 0 0 1.25rem;
  text-transform: none;
  max-width: 30ch;
}
.gs-quote__by {
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gs-glass);
  font-style: normal;
  display: block;
}

/* ---------- 15. MEDIA FRAME ---------- */
.gs-media {
  border: 1px solid var(--gs-hair);
  background: var(--gs-fill);
  padding: .5rem;
  position: relative;
}
.gs-media img { display: block; width: 100%; }

/* ---------- 16. FORM ---------- */
.gs-form { max-width: 44rem; }
.gs-form__group { margin-bottom: 1.35rem; }
.gs-form__label {
  display: block;
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gs-glass);
  margin-bottom: .5rem;
}
.gs-form__label .gs-req { color: var(--gs-red); }
.gs-form__control,
.gs-form .form-control,
.gs-form .form-select {
  width: 100%;
  background: rgba(1, 21, 46, .55);
  border: 1px solid var(--gs-hair-strong);
  border-radius: 0;
  color: var(--gs-head);
  font-family: var(--gs-sans);
  font-size: 1rem;
  line-height: 1.5;
  padding: .7rem .9rem;
  transition: border-color .18s ease, background-color .18s ease;
}
.gs-form__control::placeholder,
.gs-form .form-control::placeholder { color: rgba(203, 220, 233, .42); }
.gs-form__control:hover,
.gs-form .form-control:hover,
.gs-form .form-select:hover { border-color: var(--gs-glass-dim); }
.gs-form__control:focus,
.gs-form .form-control:focus,
.gs-form .form-select:focus {
  background: rgba(1, 21, 46, .75);
  border-color: var(--gs-glass);
  color: var(--gs-head);
  box-shadow: none;
  outline: 2px solid var(--gs-glass);
  outline-offset: 1px;
}
textarea.gs-form__control,
.gs-form textarea.form-control { min-height: 9rem; resize: vertical; }
.gs-form__help { font-size: .9375rem; color: rgba(203, 220, 233, .68); margin: .4rem 0 0; }
.gs-form__error {
  font-family: var(--gs-mono);
  font-size: .875rem; letter-spacing: .06em;
  color: #E9897E;
  margin: .4rem 0 0;
}

.gs-alert {
  border: 1px solid var(--gs-hair);
  border-left: 2px solid var(--gs-glass);
  background: var(--gs-surface);
  padding: .9rem 1.1rem;
  font-size: .9375rem;
  margin-bottom: 1.5rem;
}
.gs-alert--error { border-left-color: var(--gs-red); }

/* ---------- 17. CONTACT BLOCKS ---------- */
.gs-mail {
  font-family: var(--gs-cond); font-weight: 700;
  /* Capped at 36px, not 52px. The address needs 593px at 52 and the column it
     sits in on Contact is 440, so it broke in two there. At 36 it measures
     411 and sets on one line in both places it appears. */
  font-size: clamp(1.75rem, 5.2vw, 2.25rem);
  line-height: 1.05; letter-spacing: .02em;
  color: var(--gs-head);
  text-decoration: none;
  display: inline-block;
  border-bottom: 2px solid var(--gs-glass-dim);
  padding-bottom: .2rem;
  /* break-word split it mid-word: MANAGEMENT@GREE / NSHIPS.NET. The markup
     carries a <wbr> after the @, which is the one place an address should
     break; overflow-wrap is the safety net if a half still will not fit. */
  word-break: normal;
  overflow-wrap: break-word;
}
.gs-mail:hover { border-bottom-color: var(--gs-glass); color: var(--gs-head); }

.gs-addr {
  font-family: var(--gs-mono);
  font-size: .9375rem; line-height: 1.9;
  font-style: normal;
  color: var(--gs-text);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* ---------- 18. FOOTER ---------- */
.gs-footer {
  border-top: 1px solid var(--gs-hair);
  padding: 3.5rem 0 2.5rem;
  background: var(--gs-navy);
}
.gs-footer__about { font-size: .9375rem; max-width: 46ch; margin: 1.25rem 0 0; }
/* Same size as the navbar mark, and it follows it at the same breakpoint —
   two different sizes of the same logo on one page reads as a mistake. */
.gs-footer__logo { width: 237px; height: auto; display: block; }
@media (min-width: 992px) { .gs-footer__logo { width: 285px; } }
.gs-footer__h {
  font-family: var(--gs-mono);
  font-size: .75rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gs-glass);
  margin: 0 0 1rem;
}
.gs-footer__list { padding-left: 0; list-style: none; margin: 0; }
.gs-footer__list li { margin-bottom: .55rem; font-size: .9375rem; }
.gs-footer__list a {
  color: var(--gs-text);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.gs-footer__list a:hover { border-bottom-color: var(--gs-glass); color: var(--gs-head); }
.gs-footer__social { display: inline-flex; align-items: center; gap: .6rem; margin-top: 1rem; }
.gs-footer__social img { width: 22px; height: 22px; opacity: .82; transition: opacity .18s ease; }
.gs-footer__social a:hover img { opacity: 1; }
.gs-footer__bottom {
  border-top: 1px solid var(--gs-hair);
  margin-top: 2.75rem;
  padding-top: 1.5rem;
  font-family: var(--gs-mono);
  font-size: .8125rem; letter-spacing: .1em;
  color: var(--gs-glass);
  font-variant-numeric: tabular-nums;
}
.gs-footer__bottom a { color: var(--gs-glass); text-decoration: none; border-bottom: 1px solid transparent; }
.gs-footer__bottom a:hover { border-bottom-color: var(--gs-glass); }

/* ---------- 21. SERVICES: CONTENTS INDEX + SERVICE BLOCK ----------
   The services page is one 5,000-word document, not a card grid. It needs
   three things the rest of the site does not: a jumpable index, a text
   column that alternates side without reordering on a phone, and a real
   ordered list for the twenty-item benefits run.                        */

/* index of the thirteen services */
.gs-toc {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  border-top: 1px solid var(--gs-hair);
}
@media (min-width: 768px)  { .gs-toc { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 2.5rem; } }
@media (min-width: 1200px) { .gs-toc { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.gs-toc li { border-bottom: 1px solid var(--gs-hair-soft); min-width: 0; }
.gs-toc a {
  display: flex;
  align-items: baseline;
  gap: .85rem;
  padding: .8rem .5rem .8rem 0;
  color: var(--gs-text);
  text-decoration: none;
  transition: color .18s ease, background-color .18s ease;
}
.gs-toc a:hover { color: var(--gs-head); background: var(--gs-surface); }
.gs-toc a:hover .gs-toc__no { color: var(--gs-red); }
.gs-toc__no {
  font-family: var(--gs-mono);
  font-size: .8125rem;
  letter-spacing: .16em;
  color: var(--gs-glass);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
  transition: color .18s ease;
}
.gs-toc__t {
  font-family: var(--gs-cond);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.2;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* one service: heading block, prose column, framed figure */
.gs-svc__hd {
  border-bottom: 1px solid var(--gs-hair);
  padding-bottom: 1.5rem;
  margin-bottom: 1.85rem;
}
.gs-svc__deck {
  font-family: var(--gs-cond);
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.25;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin: .9rem 0 0;
}
.gs-svc__deck + .gs-svc__deck { margin-top: .3rem; color: rgba(203, 220, 233, .72); }

/* The figure rides along the long copy instead of stranding at the top.
   It only sticks from lg up, where the two columns actually sit side by
   side; the column must keep its default stretch height for this. */
.gs-svc__fig { margin: 0; }
@media (min-width: 992px) {
  .gs-svc__fig { position: sticky; top: calc(var(--gs-nav-h) + 2rem); }
}

/* Back-to-contents. The padding is the point: the bare text line is 24px
   tall, which only scrapes WCAG 2.5.8. The rule stays tight to the word by
   sitting on the inner span instead of the padded anchor. */
.gs-svc__back { margin: 2.25rem 0 0; }
.gs-svc__backlink {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .7rem 0;
  font-family: var(--gs-mono);
  font-size: .9375rem;
  letter-spacing: .06em;
  color: var(--gs-head);
  text-decoration: none;
}
.gs-svc__backlink span {
  border-bottom: 1px solid var(--gs-glass-dim);
  padding-bottom: 2px;
  transition: border-color .18s ease;
}
.gs-svc__backlink:hover { color: var(--gs-head); }
.gs-svc__backlink:hover span { border-bottom-color: var(--gs-glass); }

/* twenty numbered benefits — a real <ol>, native markers kept so the
   list keeps its list semantics in Safari with VoiceOver. */
.gs-numlist {
  list-style: decimal-leading-zero outside;
  max-width: 92ch;
  margin: 0;
  padding-left: 2.6rem;
}
@media (min-width: 576px) { .gs-numlist { padding-left: 3rem; } }
.gs-numlist > li {
  margin: 0 0 1.65rem;
  padding-left: 1rem;
  border-left: 1px solid var(--gs-hair-soft);
}
.gs-numlist > li:last-child { margin-bottom: 0; }
.gs-numlist > li::marker {
  font-family: var(--gs-mono);
  font-size: .9375rem;
  color: var(--gs-glass);
}
.gs-numlist__t {
  font-size: 1.0625rem;
  letter-spacing: .05em;
  line-height: 1.15;
  margin: 0 0 .5rem;
}
.gs-numlist > li > p { margin: 0; }

/* ---------- 22. CII CALCULATOR ---------- */
/* The verdict, the A-E ladder and the empty state on tools/cii-and-gfi.
   The ladder runs top to bottom the way figure 2 of MEPC.354(78) draws it:
   A at the top, E unbounded at the bottom, each rung labelled with the boundary
   it ends at. Segments are equal height on purpose — the value ranges are not
   equal and E has no upper edge, so a proportional scale would have to invent
   one. Colour reinforces the letter, it never carries meaning on its own. */

.gs-cii-verdict {
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
  border: 1px solid var(--gs-hair);
  background: var(--gs-surface);
  padding: 1.25rem 1.4rem;
}
.gs-cii-verdict__letter {
  font-family: var(--gs-cond);
  font-weight: 700;
  font-size: 4.25rem;
  line-height: .85;
  letter-spacing: .02em;
  color: var(--gs-head);
  align-self: center;
  flex: 0 0 auto;
  min-width: 2.2rem;
  text-align: center;
}
.gs-cii-verdict__body { align-self: center; }
.gs-cii-verdict__line {
  margin: 0;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--gs-text);
  font-variant-numeric: tabular-nums;
}

.gs-cii-scale {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  border-top: 1px solid var(--gs-hair);
}
.gs-cii-scale__band {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: .6rem .75rem;
  border-bottom: 1px solid var(--gs-hair);
  border-left: 2px solid transparent;
  color: rgba(203, 220, 233, .68);
}
.gs-cii-scale__band.is-active {
  background: var(--gs-surface-2);
  color: var(--gs-head);
}

/* A to E in the colours the industry draws them, green through yellow to red.
   Applied to the verdict letter and to the left edge of the band the ship
   landed in. Colour is reinforcement, never the message: the letter is right
   there beside it, and the four boundaries are printed next to the bands, so
   nothing here is carried by hue alone. All five clear 4.4:1 on the navy. */
.gs-cii-verdict[data-letter="A"] .gs-cii-verdict__letter,
.gs-cii-scale__band[data-letter="A"].is-active .gs-cii-scale__letter,
.gs-cii-outlook strong[data-letter="A"] { color: #92D050; }
.gs-cii-verdict[data-letter="B"] .gs-cii-verdict__letter,
.gs-cii-scale__band[data-letter="B"].is-active .gs-cii-scale__letter,
.gs-cii-outlook strong[data-letter="B"] { color: #00B050; }
.gs-cii-verdict[data-letter="C"] .gs-cii-verdict__letter,
.gs-cii-scale__band[data-letter="C"].is-active .gs-cii-scale__letter,
.gs-cii-outlook strong[data-letter="C"] { color: #FFD966; }
.gs-cii-verdict[data-letter="D"] .gs-cii-verdict__letter,
.gs-cii-scale__band[data-letter="D"].is-active .gs-cii-scale__letter,
.gs-cii-outlook strong[data-letter="D"] { color: #F4B183; }
.gs-cii-verdict[data-letter="E"] .gs-cii-verdict__letter,
.gs-cii-scale__band[data-letter="E"].is-active .gs-cii-scale__letter,
.gs-cii-outlook strong[data-letter="E"] { color: #FF0000; }


.gs-cii-scale__band[data-letter="A"].is-active { border-left-color: #92D050; }
.gs-cii-scale__band[data-letter="B"].is-active { border-left-color: #00B050; }
.gs-cii-scale__band[data-letter="C"].is-active { border-left-color: #FFD966; }
.gs-cii-scale__band[data-letter="D"].is-active { border-left-color: #F4B183; }
.gs-cii-scale__band[data-letter="E"].is-active { border-left-color: #FF0000; }
.gs-cii-scale__letter {
  font-family: var(--gs-cond);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: .12em;
}
/* Body font, not mono. The rest of the site sets its figures in Barlow and
   the mono face reads badly at this size; tabular-nums keeps the column
   aligned without changing family. */
.gs-cii-scale__edge { font-size: .9375rem; font-variant-numeric: tabular-nums; }

/* The form element wraps both columns so the report button can reach a second
   endpoint through formaction without the calculation being copied into hidden
   fields. .gs-form's 44rem cap is meant for a single-column form and would
   squeeze the whole row, so it is lifted here; the grid sets the width. */
#calculator .gs-form { max-width: none; }

/* Ask for the report. Sits under the result, so it only exists once there is
   something worth sending. */
.gs-cii-request {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--gs-hair);
}
/* The details dialog. Bootstrap's own dark theme gets the mechanics right and
   the colours wrong for this page — its surface is a neutral grey against a
   navy ground. Only the surfaces and the rules are restated; the behaviour,
   the backdrop and the focus trap stay Bootstrap's. */
.gs-modal .modal-content {
  background: var(--gs-navy);
  border: 1px solid var(--gs-hair-strong);
  border-radius: 0;
  box-shadow: 0 24px 60px rgba(1, 14, 31, .55);
}
.gs-modal .modal-header,
.gs-modal .modal-footer { border-color: var(--gs-hair); padding: 1.1rem 1.5rem; }
.gs-modal .modal-body { padding: 1.5rem; }
.gs-modal__title {
  font-family: var(--gs-cond); font-weight: 700; font-size: 1.6rem;
  text-transform: uppercase; letter-spacing: .01em; color: var(--gs-head); margin: 0;
}
.gs-modal .btn-close { filter: invert(1) grayscale(1) brightness(1.6); opacity: .5; }
.gs-modal .btn-close:hover { opacity: 1; }
/* The action fills the footer. A dialog has one thing to do and hiding it in a
   corner makes the reader look for it. */
.gs-modal .modal-footer .gs-btn { flex: 1 1 auto; justify-content: center; }
/* Inside the dialog the fields have a shorter measure than the page, so three
   rows of two would be cramped. Two rows of two and then the pairs stack. */
@media (max-width: 767.98px) {
  .gs-modal .gs-cii-request__fields { grid-template-columns: 1fr; }
}

/* Six fields across the whole measure, in three rows of two.

   The pairs are the point: a vessel and its IMO number identify one thing, a
   first and last name are one name, and an address and the company behind it
   are read together. Six single rows made the reader scroll a list; four
   columns fitted but split those pairs across the row.

   One column below sm, so a phone reads down the page. */
.gs-cii-request__fields {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: 1.5rem;
}
@media (min-width: 576px) { .gs-cii-request__fields { grid-template-columns: 1fr 1fr; } }

/* Marks a field the Pro report prints. Not an asterisk: on this form a star
   already means required, and one glyph cannot carry two rules. */
.gs-cii-pro-tag {
  font-family: var(--gs-mono);
  font-size: .625rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gs-glass);
  border: 1px solid var(--gs-hair);
  padding: .05rem .3rem;
  margin-left: .35rem;
  vertical-align: .06rem;
}

/* Its own row. A tick and a sentence do not belong in a field-sized cell. */
.gs-cii-consent { grid-column: 1 / -1; margin-top: .5rem; }
.gs-cii-consent label {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  cursor: pointer;
  font-size: .9375rem;
  line-height: 1.45;
  color: var(--gs-text);
}
.gs-cii-consent input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: .18rem;
  accent-color: var(--gs-red);
}
.gs-cii-consent input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--gs-glass);
  outline-offset: 2px;
}

/* The trajectory chart. Fixed height rather than an aspect ratio: the bands are
   close together and a short chart flattens the very crossing it exists to
   show. */
.gs-cii-chart { margin: 1.75rem 0 0; }
.gs-cii-chart figcaption { margin-bottom: .75rem; }
.gs-cii-chart__canvas { position: relative; height: 260px; }
@media (min-width: 992px) { .gs-cii-chart__canvas { height: 300px; } }

/* Beside the rating bands, the chart takes whatever height they turn out to
   be rather than a number picked to look right against one ship's wording. The
   sentence under the bands is longer when the letter drops than when it holds,
   so any fixed height is wrong for one of the two — and the gap it leaves sits
   under the chart, where a reader reads it as the chart having ended early.

   The row already stretches its columns to the tallest, so the column has a
   definite height to give away; the figure spends it on the canvas, which is
   the only part of this that can use it. The min-height is for the degenerate
   case where the bands are somehow shorter than a chart is worth drawing at.
   Below lg the columns stack and the fixed height above applies again. */
@media (min-width: 992px) {
  .gs-cii-chartcol { display: flex; }
  .gs-cii-chartcol .gs-cii-chart {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    margin-top: 0;
    min-width: 0;
  }
  .gs-cii-chartcol .gs-cii-chart__canvas {
    flex: 1 1 auto;
    height: auto;
    min-height: 300px;
  }
}

/* The one figure the free tool gives away: the year the letter drops. Set as a
   sentence rather than a panel — it is a fact about the ship, not a feature. */
.gs-cii-outlook {
  margin: 1.5rem 0 0;
  padding: .9rem 1.1rem;
  border-left: 2px solid var(--gs-hair-strong);
  background: var(--gs-fill);
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--gs-text);
}
.gs-cii-outlook strong { font-weight: 700; }

/* Free against Pro, side by side, because the difference is only read as a
   comparison while the two are in the same glance. Stacked, the reader meets
   the free card, decides, and never weighs it against the other.

   They have the full width of the block, under the form rather than beside
   it, so the pair fits from the first breakpoint where a card can hold a list
   item on two lines. Below that they stack, which is the right answer on a
   phone anyway. */
.gs-cii-tiers {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  margin-top: 2.5rem;
}
@media (min-width: 768px) {
  .gs-cii-tiers { grid-template-columns: 1fr 1fr; gap: 1.5rem; }
}
.gs-cii-tier {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--gs-hair);
  background: var(--gs-fill);
  padding: 1.5rem;
}
/* The Pro card is the one being sold, and two panels of identical weight are
   read as equals rather than as an upgrade. A hairline of brand red along the
   top is the least that settles it — inset, so the card does not grow a pixel
   and the two stay aligned. No badge, no shadow, no scaling. */
.gs-cii-tier--pro {
  border-color: var(--gs-hair-strong);
  background: var(--gs-surface);
  box-shadow: inset 0 3px 0 0 var(--gs-red);
}
.gs-cii-tier__name {
  font-family: var(--gs-mono);
  font-size: .8125rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin: 0;
}
.gs-cii-tier__price {
  font-family: var(--gs-cond);
  font-weight: 700;
  font-size: 2.375rem;
  line-height: 1;
  letter-spacing: -.005em;
  color: var(--gs-head);
  margin: .4rem 0 1rem;
}
/* The zero is there so the two prices line up and the comparison is one
   glance. It is not the figure being sold, so it does not take the white. */
.gs-cii-tier:not(.gs-cii-tier--pro) .gs-cii-tier__price { color: var(--gs-glass); }
/* What the figure buys, under the figure. A naked price on a card invites the
   question this answers, and at three figures the reader asks it. */
.gs-cii-tier__unit {
  display: block;
  font-family: var(--gs-mono);
  font-weight: 400;
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin-top: .45rem;
}
.gs-cii-tier__list {
  list-style: none;
  margin: 0 0 1.35rem;
  padding: 1rem 0 0;
  border-top: 1px solid var(--gs-hair-soft);
  font-size: .9375rem;
  line-height: 1.5;
  color: var(--gs-text);
  flex: 1 1 auto;
}
.gs-cii-tier__list li { padding: .3rem 0 .3rem 1.1rem; position: relative; }
.gs-cii-tier__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .95em;
  width: .45rem;
  height: 1px;
  background: var(--gs-glass-dim);
}
.gs-cii-tier--pro .gs-cii-tier__list li::before { background: var(--gs-glass); }
/* Full width inside the card. A button hugging the left edge of a panel it
   does not fill reads as an afterthought, and this one is the whole point of
   the panel. */
.gs-cii-tier .gs-btn { align-self: stretch; justify-content: center; }
.gs-cii-tier .gs-form__help { margin: 0 0 .85rem; }

/* Before there is a result the page is a form and a promise. The promise used
   to be held at 46rem, on the argument that prose wants a measure — which was
   true while the form beside it was narrower too. Everything above it runs to
   the edge now, and a panel stopping two thirds across reads as unfinished
   rather than as considered. */
.gs-cii-empty {
  border: 1px solid var(--gs-hair);
  border-left: 2px solid var(--gs-hair-strong);
  background: var(--gs-fill);
  padding: 1.5rem 1.6rem;
  font-size: .9375rem;
  color: rgba(203, 220, 233, .82);
}
.gs-cii-empty p + p { margin-top: .9rem; }

/* The ship and the year, across the measure rather than down a column. Three
   up on a wide screen: five fields in a row of five would each be too narrow
   for the ship-type names, and two rows of three reads as one block. The help
   text under each is what sets the row height, so `align-items: start` keeps a
   short field from stretching to match a long explanation beside it. */
.gs-cii-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 2rem;
  align-items: start;
}
@media (min-width: 576px) { .gs-cii-fields { grid-template-columns: 1fr 1fr; } }
@media (min-width: 992px) { .gs-cii-fields { grid-template-columns: repeat(3, 1fr); } }

/* Fuel entry: one row per grade burned. The page ships with a single row and
   grows by cloning Django's empty_form, so the markup here has to work for a row
   that does not exist yet as well as for one that does.

   Full width, like the ship fields above it. It was capped at 58rem for a
   while, on the grounds that a select run to 1,250px is a bar with a word at
   one end. The rows are wider now and the numeric columns took the slack, so
   the select is a share of the line rather than all of it.

   The prose runs the full width with them, by owner's decision. It was capped
   at 74ch for a few minutes on the usual argument — the line runs to about a
   hundred and sixty characters here, and that is one the eye loses the start
   of on the way back. The
   paragraphs here are three and four sentences, not a page of body copy, and
   the block reads as one thing when nothing inside it stops short of the edge.
   Both of those are true; which one wins is a judgement, and it was made. */
.gs-cii-rows { display: flex; flex-direction: column; gap: .6rem; }
/* The column names, once at the top instead of a unit hung off every box. Same
   track sizes as the row below it, so the two line up. */
.gs-cii-rows__head {
  display: none;
  gap: .5rem;
  font-family: var(--gs-mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin-bottom: .4rem;
}
.gs-cii-row__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 7.5rem 2.25rem;
  gap: .5rem;
  align-items: stretch;
}
@media (min-width: 576px) {
  .gs-cii-rows__head { display: grid; grid-template-columns: minmax(0, 1fr) 7.5rem 2.25rem; }
  /* The head carries its own modifier rather than reaching for the rows
     below it: a sibling selector would have to look forwards, and :has() is
     not something a column alignment should depend on. */
  .gs-cii-rows__head--priced {
    grid-template-columns: minmax(0, 1fr) 7.5rem 9rem 2.25rem;
  }
  .gs-cii-rows--priced .gs-cii-row__grid {
    grid-template-columns: minmax(0, 1fr) 7.5rem 9rem 2.25rem;
  }
}
@media (min-width: 1200px) {
  .gs-cii-rows__head { grid-template-columns: minmax(0, 1fr) 10rem 3rem; }
  .gs-cii-row__grid { grid-template-columns: minmax(0, 1fr) 10rem 3rem; }
  .gs-cii-rows__head--priced,
  .gs-cii-rows--priced .gs-cii-row__grid {
    grid-template-columns: minmax(0, 1fr) 10rem 12rem 3rem;
  }
}
.gs-cii-row .gs-form__control { padding: .5rem .7rem; }
.gs-cii-row__drop {
  border: 1px solid var(--gs-hair-strong);
  background: transparent;
  color: var(--gs-text);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color .18s ease, color .18s ease;
}
.gs-cii-row__drop:hover { border-color: var(--gs-red); color: var(--gs-head); }
.gs-cii-row__drop:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 1px; }
.gs-cii-addrow[disabled] { opacity: .45; cursor: not-allowed; }

/* The blend fields, folded away behind a <details>. Native rather than
   scripted: the "Add fuel" button clones a <template>, and a cloned element
   carries no event listeners — a disclosure that needed JS would work on the
   first row and silently not on any of the others. */
.gs-cii-row__more { margin-top: .45rem; }
/* The fold belongs to a biofuel row. A fossil grade has a published factor and
   nothing left to ask, so its row is the two boxes and no more.

   Written as "hide unless the selection is a biofuel" rather than "show when it
   is": a browser without :has() drops the rule and the fold stays visible on
   every row, which is noisier but leaves every control reachable. That is the
   safe direction for a progressive enhancement. The empty spare row is covered
   by the same rule, since its selection is not a biofuel either. */
.gs-cii-row:has(.gs-cii-row__fuel option:checked:not([value="fame"]):not([value="hvo"]))
  .gs-cii-row__more {
  display: none;
}
.gs-cii-row__more > summary {
  cursor: pointer;
  font-family: var(--gs-mono);
  font-size: .7rem;
  opacity: .72;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gs-glass);
  padding: .15rem 0;
}
.gs-cii-row__more > summary:hover { color: var(--gs-text); opacity: 1; }
.gs-cii-row__more[open] > summary { color: var(--gs-text); opacity: 1; }
/* A stack, not a grid. The calculator column is about 450px wide, so a
   two-column layout here was one browser-zoom step away from collapsing — and
   worse, it made one label serve two boxes, which is how "24.00" ended up in a
   field with nothing saying what 24 was. Every control gets its own label and
   every number its own unit. */
.gs-cii-row__blend {
  margin: .5rem 0 0;
  padding: .7rem .75rem .8rem;
  border: 1px solid var(--gs-hair);
}
.gs-cii-row__lbl {
  font-size: .8125rem;
  line-height: 1.35;
  color: var(--gs-glass);
  margin: .8rem 0 .3rem;
}
.gs-cii-row__blend > .gs-cii-row__lbl:first-child { margin-top: 0; }
/* The box and its unit read as one thing, so the unit cannot be mistaken for
   the next field's label. */
.gs-cii-row__unit { display: flex; align-items: center; gap: .5rem; }
.gs-cii-row__unit .gs-form__control { flex: 0 0 8rem; }
.gs-cii-row__unit span {
  font-family: var(--gs-mono);
  font-size: .78rem;
  color: var(--gs-glass);
  white-space: nowrap;
}
.gs-form fieldset { border: 0; padding: 0; margin: 0 0 1.35rem; min-width: 0; }
.gs-form legend { float: none; width: auto; padding: 0; }

/* The per-fuel working under the result: tonnes x Cf = tonnes CO2, with the
   column totalled underneath so the footer can be checked against the rows.
   The wrapper scrolls rather than letting four columns push the page sideways
   on a narrow screen. */
#calculator .gs-spec__v { font-variant-numeric: tabular-nums; }
.gs-cii-burn { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.gs-cii-burn__table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gs-cii-burn__table th,
.gs-cii-burn__table td { padding: .4rem .75rem .4rem 0; text-align: right; }
.gs-cii-burn__table th:first-child,
.gs-cii-burn__table td:first-child { text-align: left; white-space: normal; min-width: 11rem; }
.gs-cii-burn__table thead th,
.gs-cii-burn__table tfoot th {
  font-family: var(--gs-mono);
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gs-glass);
}
.gs-cii-burn__table thead th { border-bottom: 1px solid var(--gs-hair); padding-bottom: .5rem; }
.gs-cii-burn__table tbody td { border-bottom: 1px solid var(--gs-hair-soft); }
.gs-cii-burn__table tfoot th,
.gs-cii-burn__table tfoot td {
  border-top: 1px solid var(--gs-hair);
  padding-top: .6rem;
}
.gs-cii-burn__table tfoot td { color: var(--gs-head); }
.gs-cii-burn__src {
  display: block;
  margin-top: .5rem;
  font-family: var(--gs-mono);
  font-size: .8125rem;
  letter-spacing: .06em;
  color: var(--gs-glass);
}

/* ---------- 20. MOTION ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---- GFI, the draft framework -------------------------------------------
   Set apart from the CII result rather than styled to match it: the two
   answer different questions, and one of them is not law yet. A rule ran down
   the left to say so, which worked while the results had no headings — but it
   grew with the section, and beside a draft banner that carries its own left
   flag it read as two markers competing. The .gs-cii-sec heading does that job
   now; the flag stays, because "not adopted" is a warning and not a section. */
.gs-cii-gfi { margin-top: 0; }
.gs-cii-gfi__flag {
  font-size: .9375rem;
  color: rgba(203, 220, 233, .82);
  border-left: 3px solid #E2725B;
  padding: .1rem 0 .1rem .75rem;
  margin: 0 0 .9rem;
}
.gs-cii-gfi__pending { font-size: .9375rem; color: rgba(203, 220, 233, .82); margin: 0; }
.gs-cii-gfi__headline { font-size: .9375rem; color: rgba(203, 220, 233, .88); margin: .5rem 0 0; }
.gs-cii-gfi__prices > summary { cursor: pointer; font-size: .9375rem; color: rgba(203, 220, 233, .82); }
.gs-cii-gfi__price-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
/* The three boxes sit on one line, so the three labels above them have to be
   the same height. Reserving two lines was not enough on its own: whether a
   label took one line or two still depended on where the text happened to
   break, so the row held at one width and not at another. The unit is now a
   block of its own, which makes every label two lines by construction rather
   than by luck, and the reserved height is the floor under that. The third
   name lost "trading price" to keep its first line from wrapping too. */
.gs-cii-gfi__price-grid .gs-form__label {
  min-height: 2.6em;
  line-height: 1.3;
}
.gs-form__unit { display: block; }

/* The four figures a reader who reads nothing else should leave with. A rule
   down the left of each rather than a box: the section is already set apart by
   a rule of its own, and four bordered panels inside it would read as four
   verdicts on a page that has one. */
.gs-gfi-cards {
  display: grid;
  gap: 1.1rem 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
.gs-gfi-card { border-left: 1px solid rgba(203, 220, 233, .22); padding-left: .9rem; }
.gs-gfi-card__k {
  font-family: var(--gs-mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin: 0 0 .35rem;
}
.gs-gfi-card__v {
  font-size: 1.375rem;
  line-height: 1.1;
  color: var(--gs-head);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.gs-gfi-card__n {
  font-size: .78rem;
  line-height: 1.35;
  color: rgba(203, 220, 233, .62);
  margin: .35rem 0 0;
}

/* The unit switch on the cost chart, in the caption line where it belongs —
   it changes what the chart is measured in, not what is being asked. */
.gs-gfi-toggle { float: right; display: inline-flex; gap: 1px; }
.gs-gfi-toggle__btn {
  border: 1px solid rgba(203, 220, 233, .22);
  background: transparent;
  color: rgba(203, 220, 233, .62);
  font-family: var(--gs-mono);
  font-size: .66rem;
  letter-spacing: .1em;
  padding: .18rem .5rem;
  cursor: pointer;
  transition: color .18s ease, border-color .18s ease;
}
.gs-gfi-toggle__btn:hover { color: var(--gs-text); }
.gs-gfi-toggle__btn.is-on { color: var(--gs-head); border-color: var(--gs-glass); }
.gs-gfi-toggle__btn:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 1px; }

/* A definition list in two columns. Only for lists of short rows: the fuel
   table used to sit inside this one as a row of its own, which is why the
   workings could not run two-up until it was lifted out. Left to right rather
   than down one column and up the next — these are labelled facts, not a
   sequence, and reading order is the order they are written in. */
@media (min-width: 992px) {
  .gs-spec--two {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 2.5rem;
  }
}



/* ==========================================================================
   UK ETS TOOL
   Reuses the CII tool's field grid (.gs-cii-fields), stat card (.gs-gfi-card)
   and result table (.gs-cii-burn__table).

   The itinerary is ONE grid, not a card per stop. The card version carried four
   stacked bands per leg — ports, radios, two fuel groups, a fold — and three
   legs came to roughly twenty rows of chrome. A line is now the sentence a
   voyage is: from here, to there, this much at sea, this much alongside.
   ========================================================================== */

/* .gs-form caps at 44rem, right for a contact form and wrong for a seven-column
   itinerary. */
.gs-form--wide { max-width: none; }

/* The worked-example rail. Its heading sits above the cards rather than beside
   them: inline, it pushed the first card out of line with the rest and the row
   wrapped a card short, leaving one orphan under four.

   auto-fit rather than a fixed column count, so the cards share the width evenly
   however many there are. Five rules today, and adding a sixth should not mean
   choosing a new grid. */
.gs-uk-examples { margin: 1.75rem 0 0; }
.gs-uk-examples__hd { margin: 0 0 .6rem; }
.gs-uk-examples__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: .6rem;
}
.gs-uk-examples__link {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  padding: .7rem .85rem;
  border: 1px solid var(--gs-hair-strong);
  border-radius: .5rem;
  /* No underline. Two underlined lines in a card read as two links, and the
     border already says the whole card is one. */
  text-decoration: none;
  transition: border-color .18s ease, background-color .18s ease;
}
.gs-uk-examples__link strong {
  color: var(--gs-head);
  font-weight: 500;
  font-size: .9375rem;
  line-height: 1.25;
}
.gs-uk-examples__link span {
  font-size: .8125rem;
  color: var(--gs-glass);
  line-height: 1.35;
}
.gs-uk-examples__link:hover {
  border-color: var(--gs-glass);
  background: var(--gs-surface);
}
.gs-uk-examples__link:hover strong { color: var(--gs-head); }
.gs-uk-examples__link:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 2px; }
/* The one on screen. A left edge rather than a full red border: the card is
   showing, not warning. */
.gs-uk-examples__link.is-active {
  border-color: var(--gs-glass-dim);
  box-shadow: inset 3px 0 0 var(--gs-red);
}

.gs-uk-banner { margin: 1.5rem 0 0; }
.gs-uk-banner a { color: var(--gs-head); text-decoration: underline; }
.gs-uk-fold { margin-top: .5rem; }
.gs-uk-fold > summary,
.gs-uk-more > summary {
  font-size: .875rem; color: var(--gs-text); opacity: .6;
  cursor: pointer; list-style: revert;
}
.gs-uk-fold > summary:hover, .gs-uk-fold[open] > summary,
.gs-uk-more > summary:hover, .gs-uk-more[open] > summary { opacity: 1; }
.gs-uk-fold .gs-form__group { max-width: 32rem; }

/* --- the itinerary ------------------------------------------------------ */

/* A leg is the two ports on one line, then two stacks of fuel rows side by
   side — one for the voyage, one for the arrival port. A stack grows and
   shrinks in the browser, the way the CII tool's fuel rows do. */
.gs-uk-grid { --gs-uk-cols: minmax(0, 1fr) minmax(0, 1.3fr); }

.gs-uk-leg { padding: .85rem 0; }
.gs-uk-leg + .gs-uk-leg { border-top: 1px solid var(--gs-hair-strong); }

.gs-uk-ports { display: grid; grid-template-columns: 1fr; gap: .5rem; align-items: end; }

.gs-uk-cell { min-width: 0; }
.gs-uk-cell__lbl {
  display: block;
  font-family: var(--gs-mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin-bottom: .2rem;
}
.gs-uk-cell .gs-form__control,
.gs-uk-row .gs-form__control { padding: .45rem .6rem; font-size: .9rem; }
/* A later leg inherits its departure end, so those two controls are disabled:
   they read as text rather than as boxes nobody may use. */
.gs-uk-cell .gs-form__control:disabled {
  border-color: transparent;
  background: transparent;
  color: var(--gs-glass);
  opacity: 1;
  padding-left: 0;
}
.gs-uk-cell--arrow { display: none; }

/* The two halves. */
.gs-uk-halves { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: .9rem; }
.gs-uk-half { min-width: 0; }
.gs-uk-half__hd {
  font-family: var(--gs-mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gs-glass);
  margin: 0 0 .35rem;
}

/* Rows stack against each other — an added grade is another line of the box
   above it, and a gap between them reads as two separate questions. */
.gs-uk-rows { display: flex; flex-direction: column; gap: .35rem; }
/* The same two tracks as the ports line above, so the grade sits under the port
   box and the tonnage under the region select. It used to have three tracks of
   its own — grade, tonnage, cross — which lined up with nothing. */
.gs-uk-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: .35rem;
  align-items: center;
}
/* Every input in a leg ends on the same edge as the one above it. That means
   the tonnage box has to FILL its cell, not sit at a fixed width inside it —
   and the cross therefore cannot take space beside it, or the box would stop
   short by exactly the width of a cross. So the cross sits inside the box's
   right end, over the padding kept for it. */
.gs-uk-row__qty { position: relative; }
.gs-uk-row__qty .gs-form__control { width: 100%; padding-right: 1.75rem; }
.gs-uk-row__qty .gs-uk-row__drop {
  position: absolute;
  right: .55rem;
  top: 50%;
  transform: translateY(-50%);
}
.gs-uk-row .gs-form__error { grid-column: 1 / -1; margin: 0; }

.gs-uk-add { margin: .45rem 0 0; }
.gs-uk-addbtn,
.gs-uk-drop {
  border: 0;
  background: transparent;
  padding: 0;
  font-family: var(--gs-mono);
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gs-glass);
  cursor: pointer;
  line-height: 1;
}
.gs-uk-addbtn:hover { color: var(--gs-head); }
.gs-uk-drop:hover { color: var(--gs-red); }
.gs-uk-addbtn:focus-visible,
.gs-uk-drop:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 2px; }
/* The row cross needs no words: it sits beside the box it removes. */
.gs-uk-row__drop { font-size: 1.1rem; }

.gs-uk-legdrop { margin: .6rem 0 0; }

/* What happened at the arrival port: one form-wide button, because it is the
   same answer on nearly every leg. A leg that IS a bunkers-only stop shows it
   whether the box is ticked or not. */
.gs-uk-toggle { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.gs-uk-x { display: none; margin-top: .75rem; }
.gs-uk-leg.is-open-stop > .gs-uk-x--stop,
.gs-uk-toggle--stop:checked ~ .gs-uk-grid .gs-uk-x--stop { display: block; }
.gs-uk-x .gs-form__control { max-width: 16rem; }
.gs-uk-note { display: block; font-size: .78rem; color: var(--gs-glass); margin-top: .3rem; }

.gs-uk-actions { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.gs-uk-actions label.gs-btn { cursor: pointer; margin: 0; }
.gs-uk-toggle--stop:checked ~ .gs-uk-grid ~ .gs-uk-actions label[for="gs-uk-more-stop"] {
  border-color: var(--gs-glass);
  color: var(--gs-head);
  background: var(--gs-surface);
}
.gs-uk-toggle:focus-visible ~ .gs-uk-grid ~ .gs-uk-actions label {
  outline: 2px solid var(--gs-glass);
  outline-offset: 2px;
}

@media (min-width: 768px) {
  .gs-uk-ports {
    grid-template-columns: var(--gs-uk-cols) 1.25rem var(--gs-uk-cols);
    gap: .5rem .6rem;
  }
  .gs-uk-cell--arrow {
    display: block;
    text-align: center;
    color: var(--gs-glass);
    padding-bottom: .5rem;
  }
  /* The two halves take the same widths as the two ports above them, so a
     voyage's fuel sits under where it sailed from and the arrival port's fuel
     under where it arrived. */
  .gs-uk-halves {
    grid-template-columns: minmax(0, 1fr) 1.25rem minmax(0, 1fr);
    gap: 0 .6rem;
  }
  .gs-uk-half:first-child { grid-column: 1; }
  .gs-uk-half:last-child { grid-column: 3; }
  /* A half is exactly as wide as the two port controls above it, so the row
     inside it can take their proportions and land on their edges. */
  .gs-uk-row { grid-template-columns: var(--gs-uk-cols); gap: .35rem .6rem; }
}

/* --- the result --------------------------------------------------------- */

.gs-uk-route {
  display: flex; flex-wrap: wrap; align-items: stretch;
  gap: .5rem; margin: 0 0 1.5rem; padding: 0;
}
.gs-uk-route__stop {
  display: flex; flex-direction: column; gap: .15rem;
  padding: .55rem .8rem;
  border: 1px solid var(--gs-hair-strong);
  border-radius: .5rem;
  position: relative;
}
.gs-uk-route__stop + .gs-uk-route__stop { margin-left: 1.1rem; }
.gs-uk-route__stop + .gs-uk-route__stop::before {
  content: "\2192";
  position: absolute; left: -1.05rem; top: 50%;
  transform: translateY(-50%);
  color: var(--gs-glass);
}
.gs-uk-route__stop.is-foreign { opacity: .62; border-style: dashed; }
.gs-uk-route__stop.is-transit { border-style: dotted; }
.gs-uk-route__port { color: var(--gs-head); font-weight: 500; }
.gs-uk-route__where { font-size: .78rem; color: var(--gs-glass); }

.gs-uk-cards { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-bottom: 1.5rem; }
@media (min-width: 768px) { .gs-uk-cards { grid-template-columns: repeat(3, 1fr); } }

/* An out-of-scope row is dimmed, not hidden: the zero answers a question the
   visitor asked, and a row that vanished would read as one never entered. */
.gs-cii-burn__table tr.is-out > * { opacity: .62; }
/* The Why column carries a sentence, so it gets a floor rather than a cap. The
   table scrolls inside .gs-cii-burn, which already sets overflow-x. */
.gs-cii-burn__table { min-width: 46rem; }
.gs-uk-why { font-size: .85rem; color: rgba(203, 220, 233, .78); min-width: 20ch; }
.gs-uk-note {
  display: block; font-size: .8125rem; font-weight: 400;
  color: var(--gs-glass); margin-top: .25rem; max-width: 46ch;
}

.gs-uk-workings > summary {
  font-family: var(--gs-mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gs-glass); cursor: pointer;
}
.gs-uk-workings > summary:hover { color: var(--gs-text); }
.gs-uk-workings__body { margin-top: 1rem; }

.gs-uk-notes ul { margin: 0; padding: 0; }
.gs-uk-notes li {
  padding: .6rem 0;
  border-top: 1px solid var(--gs-hair-strong);
  font-size: .9375rem;
  color: rgba(203, 220, 233, .82);
}

/* Remove: a real submit, because clearing a field and renumbering a formset are
   not things CSS can do. Same weight as the "add" it undoes — a control that
   destroys should not be louder than the one that creates, nor quieter. */
.gs-uk-drop {
  border: 0;
  background: transparent;
  padding: 0;
  font-family: var(--gs-mono);
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gs-glass);
  cursor: pointer;
  line-height: 1;
}
/* The row remove is a cross and nothing else: it sits in a track a word does
   not fit, and beside its own tonnage box, where what it removes is obvious.
   "Remove leg" keeps its words — it is a different size of action. */
.gs-uk-cell--drop .gs-uk-drop { font-size: 1.1rem; }
.gs-uk-drop:hover { color: var(--gs-red); }
.gs-uk-drop:focus-visible { outline: 2px solid var(--gs-glass); outline-offset: 2px; }
.gs-uk-cell--drop { display: flex; align-items: end; justify-content: center; padding-bottom: .45rem; }
/* "Remove leg" sits at the far end of the line it removes, away from the add
   beside it, so the two are not pressed for each other. */
.gs-uk-add .gs-uk-drop { margin-left: auto; }

/* Two installation questions side by side. They are folded together because a
   ship burning neither is asked nothing, and both change a Table C2 cell. */
.gs-uk-fold__grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 768px) { .gs-uk-fold__grid { grid-template-columns: 1fr 1fr; } }
.gs-uk-fold__grid .gs-form__group { margin-bottom: 0; }

/* The workings panel prints one table per leg or berth. Left to size
   themselves, each puts its columns where its own longest cell happens to fall,
   so "Tonnes" lands in a different place on every block and a reader comparing
   two rows has to find the column again each time. Fixed widths, shared by all
   of them. */
.gs-uk-workings__table { table-layout: fixed; width: 100%; }
.gs-uk-workings__table th:nth-child(1),
.gs-uk-workings__table td:nth-child(1) { width: auto; }
.gs-uk-workings__table th:nth-child(2),
.gs-uk-workings__table td:nth-child(2) { width: 6rem; text-align: right; }
.gs-uk-workings__table th:nth-child(3),
.gs-uk-workings__table td:nth-child(3) { width: 7rem; text-align: right; }
.gs-uk-workings__table th:nth-child(4),
.gs-uk-workings__table td:nth-child(4) { width: 9rem; text-align: right; }
.gs-uk-workings__table th:nth-child(5),
.gs-uk-workings__table td:nth-child(5) { width: 21rem; text-align: right; }
/* A fuel name is long and the column is what is left over, so it wraps rather
   than pushing the numeric columns out of line. */
.gs-uk-workings__table td:nth-child(1),
.gs-uk-workings__table th:nth-child(1) { white-space: normal; word-break: normal; }
