/* Screen: port — the job board, the map and the capacity meter.
   Wide (≥ 901 px): map + news on the left, job board on the right.
   Narrow: job board, map, news. The dock bar (meter, estimate, "Load the ship →") sticks to the bottom. */

.screen--port {
  gap: var(--sp-4);
}

/* Re-renders (taking a job, waiting) should not replay the screen's entrance. */
.screen--port.is-rerender,
.screen--port .mate.is-still {
  animation: none;
}

/* ── Header ────────────────────────────────────────────── */
.port-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.port-head__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
}

.port-head__nation {
  font-size: var(--fs-sm);
}

.port-head__hint {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--ink-soft);
}

.port-head__spent {
  align-self: flex-start;
  margin-top: var(--sp-1);
  padding: 0.2em 0.8em;
  border-radius: var(--r-pill);
  background: var(--loss-bg);
  color: var(--ink-soft);
  font-size: var(--fs-sm);
  font-weight: 800;
}

/* ── Debt reminder (calm slate, never red) ─────────────── */
.port-debt {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--loss-bg);
  border: 2px solid var(--line);
}

.port-debt__icon {
  font-size: 1.6em;
  line-height: 1;
}

.port-debt__text {
  flex: 1 1 260px;
  font-weight: 700;
  color: var(--ink);
}

/* ── Layout ────────────────────────────────────────────── */
/* Jobs first, on every screen: they are the choice here (the owner's ask). Wide screens: the job board on the left,
   the port's notes and news under it, the map on the right, staying in view while the job list scrolls. */
.port-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    'board map'
    'news map';
  gap: var(--sp-4) var(--sp-5);
  align-items: start;
}

.port-map {
  grid-area: map;
  position: sticky;
  top: var(--sp-2);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.port-board {
  grid-area: board;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.port-news {
  grid-area: news;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  min-width: 0;
}

/* ── CAP: the port's notes (bills with C2's 🎯 season-goal note under them, C8's 📃 Promises card, C5's ⛽ fuel dock;
   src/ui/screens/port.js). A late home port shows them all. They come right after the job board on every screen
   (side by side where the column is wide enough: each at least 17rem; one note alone keeps the full width). */
.port-layout.has-notes {
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    'board map'
    'notes map'
    'news map';
}

.port-notes {
  grid-area: notes;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  align-items: start;
  gap: var(--sp-3) var(--sp-4);
  min-width: 0;
}

/* ── FINAL review: a busy 📃 Promises card (two items or more, or a 🙏 request with its button; port.js
   promisesCardBusy) is too tall for the notes: it has a place of its own (.port-cards) after them. */
.port-cards {
  grid-area: cards;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.port-layout.has-cards {
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    'board map'
    'cards map'
    'news map';
}

.port-layout.has-notes.has-cards {
  grid-template-rows: auto auto auto 1fr;
  grid-template-areas:
    'board map'
    'notes map'
    'cards map'
    'news map';
}

/* ── FINAL: C2's 🎯 season-goal note under the Bills card, in one column of the notes (both are about bill day). */
.port-notes__stack {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

/* Narrow screens (tablet portrait, phones): one column, the job board first, then the notes, the map and the news. */
@media (max-width: 56.25em) {
  .port-layout,
  .port-layout.has-notes,
  .port-layout.has-cards,
  .port-layout.has-notes.has-cards {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }

  .port-layout {
    grid-template-areas:
      'board'
      'map'
      'news';
  }

  .port-layout.has-notes {
    grid-template-areas:
      'board'
      'notes'
      'map'
      'news';
  }

  .port-layout.has-cards {
    grid-template-areas:
      'board'
      'cards'
      'map'
      'news';
  }

  .port-layout.has-notes.has-cards {
    grid-template-areas:
      'board'
      'notes'
      'cards'
      'map'
      'news';
  }

  /* Tablet portrait: the map and its info card side by side. */
  .port-map {
    position: static;
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    align-items: start;
  }
}

/* Phones: the map's info card goes under the map. */
@media (max-width: 35em) {
  .port-map {
    display: flex;
  }
}

/* ── Map extras: destination pills and the info card ──── */
.port-pill rect {
  fill: #ffffff;
  stroke: var(--accent-500);
  stroke-width: 3;
}

.port-pill text {
  font-size: 23px;
  font-weight: 900;
  fill: var(--accent-700);
}

.port-pill.is-taken rect {
  fill: var(--sea-600);
  stroke: #ffffff;
}

.port-pill.is-taken text {
  fill: #ffffff;
}

.screen--port .map-port.is-dest .map-port-ring {
  fill: var(--accent-100);
  stroke: var(--accent-500);
  stroke-width: 3;
}

.screen--port .map-port.is-selected .map-port-ring {
  fill: var(--accent-200);
  stroke: var(--accent-700);
  stroke-width: 4;
}

.port-info {
  min-height: 56px;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-1);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-1);
}

.port-info__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.port-info__name {
  font-size: var(--fs-md);
}

.port-info__text {
  margin: 0 !important;
  font-weight: 600;
}

.port-info .btn {
  margin-top: var(--sp-2);
}

.port-info__hint {
  margin: auto 0 !important;
  font-weight: 700;
}

/* ── Job board ─────────────────────────────────────────── */
.port-board__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-3);
}

.port-board__title {
  font-size: var(--fs-lg);
}

.port-board .mate {
  max-width: none;
}

/* Pip, slim: words and "Got it" on one line when there is room. */
.port-board .mate__bubble {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
}

.port-board .mate__name {
  grid-column: 1 / -1;
}

.port-board .mate__text {
  font-size: var(--fs-base);
}

/* Job cards, compact: pay and the button on the right, details under the title. */
.port-jobs .job-card {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    'icon title pay'
    'icon dest per'
    'minis minis take'
    'meta meta take'
    'chips chips chips'
    'late late late'
    'hint hint hint'
    'rival rival rival'
    'ride ride ride'
    'why why why';
  gap: 2px var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}

.port-jobs .job-card__main,
.port-jobs .job-card__side {
  display: contents;
}

.port-jobs .job-card__icon {
  width: 60px;
  height: 60px;
  font-size: 34px;
  align-self: center;
}

.port-jobs .job-card__title {
  grid-area: title;
  align-self: center;
}

.port-jobs .job-card__dest {
  grid-area: dest;
  align-self: center;
}

.port-jobs .job-card__minis {
  grid-area: minis;
  align-self: end;
  margin: var(--sp-1) 0 0;
}

.port-jobs .job-card__meta {
  grid-area: meta;
  align-self: start;
}

/* WS-D: the chips row (the time chip, 💵, 🧤), the ⚠️ late hint, the bank's hint, a rival's face. */
.port-jobs .job-card__chips {
  grid-area: chips;
  margin-top: var(--sp-1);
}

.port-jobs .job-card__late {
  grid-area: late;
}

.port-jobs .job-card__hint {
  grid-area: hint;
}

.port-jobs .job-card__rival {
  grid-area: rival;
  justify-self: start;
  margin-top: var(--sp-1);
}

.port-jobs .job-card__pay {
  grid-area: pay;
  justify-self: end;
  align-self: center;
}

.port-jobs .job-card__per-box {
  grid-area: per;
  justify-self: end;
  align-self: center;
  margin: 0;
}

.port-jobs .job-card__take {
  grid-area: take;
  justify-self: end;
  align-self: center;
}

.port-jobs .job-card__why {
  margin-top: var(--sp-1);
}

/* UI-P2: the 🛒 twin's line (at a Dock shop port). */
.port-jobs .job-card__ride {
  grid-area: ride;
}

@media (max-width: 35em) {
  .port-jobs .job-card {
    grid-template-areas:
      'icon title pay'
      'icon dest per'
      'minis minis minis'
      'meta meta meta'
      'chips chips chips'
      'late late late'
      'hint hint hint'
      'rival rival rival'
      'ride ride ride'
      'take take take'
      'why why why';
    padding: var(--sp-3);
  }

  .port-jobs .job-card__icon {
    width: 50px;
    height: 50px;
    font-size: 28px;
  }

  .port-jobs .job-card__title {
    font-size: var(--fs-base);
  }

  .port-jobs .job-card__dest {
    font-size: var(--fs-base);
  }

  .port-jobs .job-card__pay {
    font-size: var(--fs-lg);
  }

  .port-jobs .job-card__take {
    justify-self: stretch;
    margin-top: var(--sp-2);
  }
}

.port-jobs {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.port-jobs .job-card {
  position: relative;
  cursor: pointer;
}

.port-jobs .job-card.is-blocked {
  cursor: help;
}

.port-jobs .job-card:not(.is-blocked):not(.is-taken):hover {
  border-color: var(--accent-200);
}

.port-jobs .job-card__dest .stop-badge {
  vertical-align: middle;
}

.port-jobs .job-card.is-new {
  border-color: var(--accent-400);
}

.port-job__new {
  position: absolute;
  top: -10px;
  right: 14px;
  padding: 0.05em 0.6em;
  border-radius: var(--r-pill);
  background: var(--accent-500);
  color: var(--ink);
  font-size: var(--fs-xs);
  font-weight: 900;
  box-shadow: var(--shadow-1);
  pointer-events: none;
}

/* Sail empty */
.sail-empty {
  padding: var(--sp-3) var(--sp-4);
}

.sail-empty__summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 900;
  font-size: var(--fs-md);
  cursor: pointer;
  list-style: none;
  border-radius: var(--r-sm);
}

.sail-empty__summary::-webkit-details-marker {
  display: none;
}

.sail-empty__summary::after {
  content: '▾';
  margin-left: auto;
  padding-left: var(--sp-2);
  color: var(--sea-600);
  transition: transform var(--dur-2) var(--ease);
}

.sail-empty[open] .sail-empty__summary::after {
  transform: rotate(180deg);
}

.sail-empty__note {
  margin: var(--sp-1) 0 var(--sp-3) !important;
  font-size: var(--fs-sm);
  font-weight: 700;
}

.sail-empty__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
  gap: var(--sp-2);
}

.sail-empty__dest {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-height: 64px;
  padding: var(--sp-2) var(--sp-3);
  border: 2px solid var(--line);
  border-radius: var(--r-md);
  background: var(--sea-50);
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}

.sail-empty__dest:hover {
  border-color: var(--sea-400);
}

.sail-empty__dest.is-selected {
  border-color: var(--sea-600);
  background: var(--sea-100);
  box-shadow: inset 0 0 0 2px var(--sea-600);
}

.sail-empty__name {
  font-weight: 900;
  font-size: var(--fs-base);
}

.sail-empty__days {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--sea-700);
}

.sail-empty__hint {
  font-size: var(--fs-xs);
  color: var(--ink-soft);
  font-weight: 600;
}

/* ── News ──────────────────────────────────────────────── */
.port-newsbox {
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.port-newsbox__title {
  font-size: var(--fs-md);
}

.port-newsbox__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.port-newsbox__item {
  display: grid;
  grid-template-columns: 1.5em minmax(0, 1fr) auto;
  gap: var(--sp-2);
  align-items: baseline;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.port-newsbox__icon {
  text-align: center;
}

.port-newsbox__when {
  color: var(--ink-faint);
  font-size: var(--fs-xs);
  font-weight: 700;
  white-space: nowrap;
}

.port-newsbox .btn {
  align-self: flex-start;
}

/* ── Dock bar: meter · estimate · go ───────────────────── */
.port-dock {
  position: sticky;
  bottom: var(--sp-2);
  z-index: 20;
  display: grid;
  /* The estimate keeps a column it can be read in (14rem); the meter takes the rest, up to its own width,
     and its slot cells wrap (an 18- or 24-slot hull once took the whole row at 1024 px: one word a line). */
  grid-template-columns: auto minmax(14rem, 1fr) auto;
  grid-template-areas: 'meter est go';
  align-items: center;
  gap: var(--sp-3) var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  background: rgba(255, 255, 255, 0.97);
  border: 2px solid var(--sea-200);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}

.port-dock__meter {
  grid-area: meter;
  min-width: 0;
}

.port-dock__estimate {
  grid-area: est;
  min-width: 0;
}

.port-dock__go {
  grid-area: go;
}

.port-go {
  white-space: nowrap;
}

/* Meter */
.port-meter {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.port-meter__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-2);
}

.port-meter__row--small {
  gap: var(--sp-1) var(--sp-4);
}

/* A big hull's slot cells wrap beside their label and count: one block, not a line each. */
.port-meter__row--slots {
  flex-wrap: nowrap;
}

.port-meter__row--slots .port-meter__cells {
  min-width: 0;
}

.port-meter__part {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.port-meter__label {
  font-size: var(--fs-sm);
  font-weight: 800;
  color: var(--ink-soft);
  white-space: nowrap;
}

.port-meter__cells {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 3px;
}

.port-meter__slot {
  display: grid;
  place-items: center;
  width: 28px;
  height: 24px;
  border: 2px dashed var(--line-strong);
  border-radius: 5px;
  background: var(--sea-50);
  font-size: 15px;
  line-height: 1;
}

.port-meter__slot.is-full {
  border: 2px solid var(--sand-600);
  background: var(--sand-200);
}

.port-meter__slot.is-cold {
  border-color: var(--cold);
  background: var(--cold-bg);
}

.port-meter__plug {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 2px dashed var(--plug);
  border-radius: 50%;
  font-size: 13px;
  line-height: 1;
  background: #fffbea;
}

.port-meter__plug.is-used {
  border: 2px solid var(--cold);
  background: var(--cold-bg);
}

.port-meter__stop-empty {
  display: inline-block;
  width: 22px;
  height: 22px;
  border: 2px dashed var(--line-strong);
  border-radius: 50%;
}

.port-meter .stop-badge {
  width: 24px;
  height: 24px;
  min-width: 24px;
  font-size: 13px;
}

.port-meter__count {
  font-variant-numeric: tabular-nums;
  font-weight: 900;
  font-size: var(--fs-sm);
}

/* Estimate */
.port-est__main {
  font-weight: 900;
  font-size: var(--fs-md);
  line-height: 1.2;
}

.port-est__sub {
  margin: 0 !important;
  font-weight: 700;
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

.port-est.is-good .port-est__main {
  color: var(--gain);
}

.port-est.is-loss .port-est__main {
  color: var(--loss);
}

.port-est.is-empty .port-est__main {
  color: var(--ink-soft);
  font-size: var(--fs-base);
}

/* Tablet portrait and narrower: go button next to the meter, estimate under them. */
@media (max-width: 56.25em) {
  .port-dock {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'meter go'
      'est go';
    gap: var(--sp-2) var(--sp-4);
  }
}

/* Phones: one column, compact meter. */
@media (max-width: 35em) {
  .port-dock {
    bottom: var(--sp-1);
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      'meter'
      'est'
      'go';
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-md);
  }

  .port-go {
    width: 100%;
    min-height: 52px;
  }

  .port-meter__slot {
    width: 22px;
    height: 20px;
    font-size: 12px;
  }

  .port-meter__word {
    display: none;
  }

  /* Slots, plugs and stops on one line when they fit. */
  .port-meter {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-3);
  }

  .port-meter__row {
    gap: var(--sp-1) var(--sp-3);
  }

  .port-info__hint {
    font-size: var(--fs-sm);
  }

  .port-est__main {
    font-size: var(--fs-base);
  }

  .port-head__hint {
    font-size: var(--fs-base);
  }
}

/* The big button stays solid when it is not ready yet (nothing shows through it). */
.port-go[aria-disabled='true'] {
  --btn-bg: #e9eef2;
  --btn-fg: var(--ink-soft);
  --btn-border: var(--line-strong);
  --btn-shadow: var(--line-strong);
  opacity: 1;
  filter: none;
}

/* Toasts float above the dock bar so they never hide the big button. */
body:has(.screen--port) .toast-stack {
  bottom: 128px;
}

@media (max-width: 56.25em) {
  body:has(.screen--port) .toast-stack {
    bottom: 150px;
  }
}

@media (max-width: 35em) {
  body:has(.screen--port) .toast-stack {
    bottom: 176px;
  }
}

/* ── Welcome / new-feature card (a modal on top of the port) ── */
.unlock-card__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.unlock-card__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  background: var(--sea-50);
  border: 2px solid var(--sea-100);
}

.unlock-card__emoji {
  flex: none;
  width: 1.6em;
  font-size: 2rem;
  line-height: 1;
  text-align: center;
}

.unlock-card__text {
  font-weight: 700;
}

.unlock-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.unlock-card__subtitle {
  margin: var(--sp-2) 0 0;
  font-size: 1.05rem;
}

@media (max-width: 35em) {
  .port-meter__cells {
    gap: 2px;
  }

  .port-meter__slot {
    width: 17px;
    height: 19px;
    border-width: 1.5px;
    border-radius: 4px;
    font-size: 11px;
  }

  .port-meter__slot.is-full {
    border-width: 1.5px;
  }

  /* Pip already says what to do; keep the phone dock short. */
  .port-dock__estimate:has(.port-est.is-empty) {
    display: none;
  }
}

/* Keep focused things and the map's info card clear of the sticky dock bar. */
html:has(.screen--port) {
  scroll-padding-bottom: 130px;
}

.port-info {
  scroll-margin-bottom: 130px;
}

@media (max-width: 56.25em) {
  html:has(.screen--port) {
    scroll-padding-bottom: 170px;
  }

  .port-info {
    scroll-margin-bottom: 170px;
  }
}

@media (max-width: 35em) {
  html:has(.screen--port) {
    scroll-padding-bottom: 210px;
  }

  .port-info {
    scroll-margin-bottom: 210px;
  }
}

/* ── Bill day (WS-D): the 🧾 card that replaced the debt note ── */
.port-bills {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 2px solid var(--line);
  box-shadow: var(--shadow-1);
}

.port-bills.is-short {
  background: var(--loss-bg);
}

.port-bills__icon {
  font-size: 1.8em;
  line-height: 1;
}

.port-bills__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.port-bills__title {
  font-weight: 900;
  font-size: var(--fs-md);
}

.port-bills__parts,
.port-bills__short {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--ink-soft);
}

.port-bills__short {
  color: var(--loss);
}

.port-bills__pips {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 2px;
}

.port-bills__pip {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--sea-200);
}

.port-bills__pip.is-bill {
  background: var(--sea-600);
  box-shadow: 0 0 0 2px var(--sea-100);
}

@media (max-width: 35em) {
  .port-bills {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .port-bills > .btn {
    grid-column: 1 / -1;
    justify-self: start;
  }
}

/* ── Rival Captains in port, and who just left with a job ── */
.port-rivals {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.port-rivals__here {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.port-rivals__chip {
  padding: 0.15em 0.7em;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 2px solid var(--sea-200);
  color: var(--sea-800);
  font-size: var(--fs-sm);
  font-weight: 800;
}

.port-rivals__left {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--ink-soft);
}

/* ── The other ports: days, 🧤, shelf, arrow, a face ── */
.port-dests {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-4);
}

.port-dests__title {
  font-size: var(--fs-md);
}

.port-dests__list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.port-dest {
  display: grid;
  /* The name keeps room for itself; the chips (shelf, 🧤, a face with words) wrap beside it. */
  grid-template-columns: minmax(7em, 1fr) minmax(0, auto);
  grid-template-areas:
    'name chips'
    'days chips'
    'arrow arrow';
  align-items: center;
  gap: 2px var(--sp-2);
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--line);
}

.port-dest:first-child {
  border-top: 0;
}

.port-dest__name {
  grid-area: name;
  font-weight: 900;
}

.port-dest__days {
  grid-area: days;
  font-size: var(--fs-sm);
  color: var(--ink-soft);
  font-weight: 700;
}

.port-dest__chips {
  grid-area: chips;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--sp-1);
}

.port-dest__arrow {
  grid-area: arrow;
}

.port-dest__small {
  background: var(--sand-100);
  color: #6d5530;
}

.port-dest.is-selected {
  margin: 0 calc(-1 * var(--sp-2));
  padding-inline: var(--sp-2);
  border-radius: var(--r-md);
  background: var(--sea-50);
  box-shadow: inset 0 0 0 2px var(--sea-200);
}

/* A rival's face: the emoji in a ring (solid: in port; dashed: on the way) and her name with a word. */
.port-face {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  max-width: 100%;
  min-width: 0;
  padding: 1px 0.6em 1px 1px;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 1px solid var(--line);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--ink-soft);
}

.port-face__emoji {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--sea-300);
  font-size: 16px;
  line-height: 1;
}

.port-face.is-coming .port-face__emoji {
  border-style: dashed;
}

.port-face__word {
  min-width: 0;
  overflow-wrap: anywhere;
}

.port-info__market {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.port-info__small {
  color: #6d5530;
  font-weight: 700;
}

.port-est__bill {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--ink-soft);
}

.sail-empty__shelf {
  justify-self: start;
}

/* ════ UI-P2 (WS-D lane P, part 2): far ports, the board's tabs, her own boxes on the board ════ */

/* The far region's one idea, beside the nation ("🏔️ Big ports: big loads."). */
.port-head__region {
  font-size: var(--fs-sm);
  background: var(--sand-100);
  color: #6d5530;
}

/* The board's tabs (🏝️ / 🌴 / 🏔️ / 🛒) and the panel under them. */
.port-tabs-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.port-tabs__panel {
  min-width: 0;
}

/* Phones: three tabs share one row. The emoji sits over a smaller label that wraps in balanced lines
   ("The Five / Isles" at most), not one word a line. */
@media (max-width: 35em) {
  .port-tabs {
    gap: var(--sp-1);
  }

  .port-tabs .tabs__tab {
    position: relative;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding: var(--sp-1) var(--sp-2);
    border-radius: var(--r-md);
    font-size: var(--fs-sm);
    line-height: 1.15;
    text-align: center;
  }

  .port-tabs .tabs__label {
    text-wrap: balance;
  }

  .port-tabs .tabs__badge {
    position: absolute;
    top: -6px;
    right: -4px;
  }
}

.port-jobs-panel {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.port-crossing-note {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: var(--sea-100);
  color: var(--sea-800);
  font-weight: 800;
}

.port-jobs__none {
  padding: var(--sp-2) var(--sp-3);
}

/* Her own boxes on the board: "🛒 2 🍫 · yours ➜ Coral Bay". */
.port-lots {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: var(--accent-100);
  border: 2px dashed var(--accent-400);
}

.port-lots__title {
  font-size: var(--fs-base);
}

.port-lots__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  flex: 1 1 200px;
  min-width: 0;
}

.port-lot {
  font-weight: 800;
  overflow-wrap: anywhere;
}

.port-lot__to {
  color: var(--ink-soft);
}

/* The meter: her own boxes wear a 🛒 corner. */
.port-meter__slot.is-own {
  position: relative;
  border-style: dashed;
  border-color: var(--accent-600);
}

.port-meter__slot.is-own::after {
  content: '🛒';
  position: absolute;
  right: -5px;
  bottom: -6px;
  font-size: 10px;
  line-height: 1;
}

/* The estimate with her own boxes: "You keep about $X" over "🔒 $Y for sure · 2 days". */
.port-est.is-own .port-est__sub {
  font-weight: 800;
}

/* 🧊 an iced port: greyed, its words say why (Other ports, the sail-empty picker, the map's card). */
.port-dest.is-iced .port-dest__name,
.port-dest.is-iced .port-dest__days {
  color: var(--loss);
}

.port-dest__iced {
  background: var(--cold-bg);
  color: var(--sea-800);
  font-size: var(--fs-sm);
}

.sail-empty__dest.is-iced {
  background: var(--loss-bg);
  border-style: dashed;
  color: var(--loss);
  cursor: help;
}

.port-info__iced {
  font-weight: 800;
  color: var(--sea-800);
}

/* A job card's 🛒 twin and a job too big for her ship (greyed, never hidden; its words name the fix). */
.job-card__ride {
  display: block;
  margin-top: var(--sp-1);
  padding: 0.15em 0.7em;
  border-radius: var(--r-md);
  background: var(--accent-100);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: 800;
  justify-self: start;
  overflow-wrap: anywhere;
}

/* The twin's cause: the shop's cause chip, words without a number ("🚢 A ship is coming"). */
.job-card__ride-cause {
  display: inline-flex;
  margin-left: 0.35em;
  vertical-align: middle;
  max-width: 100%;
}

.job-card.is-too-big {
  background: var(--loss-bg);
  border-style: dashed;
  border-color: var(--line-strong);
}

.job-card.is-too-big .job-card__why {
  color: var(--ink-soft);
  font-weight: 800;
}
/* ════ end UI-P2 ════ */

/* ── C3: the 🔨 Icebreaker Bow (docs/roadmap/C3-shipyard-depth.md §4.1, §9): an iced port her bow opens reads
   open (no 🧊 grey) with its own chip; the port panel's bow line (what opens it, or "Your bow breaks the ice."). */
.port-dest__bow {
  background: var(--cold-bg);
  color: var(--sea-800);
  font-size: var(--fs-sm);
  font-weight: 800;
}

.port-info__bow {
  font-weight: 800;
  color: var(--sea-800);
}
/* ── end C3 ── */
