/* ---------------------------------------------------------------------------
   Nassau Free Port — UI skin.
   A harbourmaster's ledger: ink, brass rule, parchment numerals. Dark at the
   top so it reads as one piece with the iOS status bar.
--------------------------------------------------------------------------- */

/* The whole UI scales off the root font size. 3vh tracks the short edge in
   landscape, which is what actually governs how big a control should feel;
   the clamp stops it collapsing on a tiny window or ballooning on a big one. */
html { font-size: clamp(10px, 3.0vh, 17px); }

:root {
  --safe-top:   env(safe-area-inset-top, 0px);
  --safe-left:  env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);

  --ink:        #0b0f14;
  --panel:      rgba(10, 15, 21, 0.82);
  --panel-hi:   rgba(26, 36, 48, 0.94);
  --rule:       rgba(200, 168, 96, 0.34);
  --rule-soft:  rgba(200, 168, 96, 0.16);
  --brass:      #c8a860;
  --parch:      #e8dcc0;
  --parch-dim:  #9aa2a8;
  --sea:        #58c0b8;
  --red:        #c86050;

  --ui: 600 0.78rem/1.25 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

html, body {
  position: fixed; inset: 0; margin: 0; padding: 0;
  overflow: hidden; overscroll-behavior: none;
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  background: var(--ink); color: var(--parch);
  font: var(--ui);
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

#stack { position: absolute; inset: 0; }

/* --- the scene ---------------------------------------------------------- */

#view {
  display: block; position: absolute; inset: 0;
  width: 100%; height: 100%;
  background: var(--ink);
}

/* Transparent input catcher. The engine binds its own orbit/pan/zoom handlers
   straight onto the canvas with no public way to turn them off, so every
   pointer event the game wants has to be caught on a layer above it. */
#input {
  position: absolute; inset: 0;
  touch-action: none;
  z-index: 2;
}

/* --- UI overlay --------------------------------------------------------- */

#ui {
  position: absolute; inset: 0;
  z-index: 3;
  pointer-events: none;
  display: flex; flex-direction: column;
  padding: var(--safe-top) var(--safe-right) 0 var(--safe-left);
}

#topbar {
  flex: none;
  display: flex; align-items: stretch;
  padding: 0.36rem max(0.85rem, var(--safe-left)) 0.42rem max(0.85rem, var(--safe-right));
  background: linear-gradient(180deg, rgba(8,12,17,.88) 0%, rgba(8,12,17,.50) 58%, rgba(8,12,17,0) 100%);
}

.stat {
  display: flex; flex-direction: column; justify-content: center;
  padding: 0.12rem 0.85rem 0.12rem 0; margin-right: 0.85rem;
  border-right: 1px solid var(--rule-soft);
  min-width: 0;
}
.stat:last-child { border-right: 0; margin-right: 0; padding-right: 0; }

.stat b {
  font: 700 0.92rem/1.1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--parch);
  letter-spacing: .01em;
  white-space: nowrap;
}
.stat span {
  font-size: 0.56rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--parch-dim); margin-top: 0.18rem; white-space: nowrap;
}
.stat.warn b { color: var(--red); }
#st-coin b { color: var(--brass); }

/* --- selection caption -------------------------------------------------- */

/* It used to be nowrap, one line, and pinned above the dock, which is fine for
   CARGO ROTTING ON THE QUAY and useless for anything a diplomatic reply has to
   say. It wraps now, and it sits under the top bar rather than over the dock:
   the sheet rises from the bottom and would bury it, and the sky is empty. */
#selection {
  position: absolute; z-index: 6;
  left: 50%; transform: translateX(-50%);
  top: calc(var(--safe-top) + 3.1rem);
  pointer-events: none;
  padding: 0.34rem 0.8rem;
  max-width: min(30rem, 82vw);
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: 3px;
  font-size: 0.68rem; letter-spacing: .1em; text-transform: uppercase;
  line-height: 1.45; text-align: center;
  color: var(--parch);
}

/* --- bottom dock -------------------------------------------------------- */

#dock {
  margin-top: auto; flex: none;
  display: flex; gap: 0.5rem;
  padding: 0 max(24px, var(--safe-left)) 0.85rem max(24px, var(--safe-right));
  pointer-events: none;
}

button.act {
  pointer-events: auto;
  flex: 1 1 0; min-width: 0;
  min-height: max(44px, 2.8rem);
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--panel);
  color: var(--parch);
  font: 700 0.68rem/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: .14em; text-transform: uppercase;
  padding: 0 0.4rem;
  transition: background .08s linear, color .08s linear;
}
button.act:active,
button.act.on { background: var(--brass); color: var(--ink); border-color: var(--brass); }
button.act:disabled { opacity: .38; }

/* --- build / ledger sheet ----------------------------------------------- */

#sheet {
  position: absolute; z-index: 4;
  left: 0; right: 0; bottom: 0;
  max-height: 78%;
  padding: 0 max(24px, var(--safe-left)) 0 max(24px, var(--safe-right));
  pointer-events: none;
}
#sheet-inner {
  pointer-events: auto;
  background: var(--panel-hi);
  border: 1px solid var(--rule);
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
  padding: 0.72rem 0.85rem 1rem;
  max-height: 76vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  box-shadow: 0 -14px 40px rgba(0,0,0,.55);
}

.sheet-head {
  display: flex; align-items: baseline; gap: 10px;
  padding-bottom: 0.5rem; margin-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
}
.sheet-head h2 {
  margin: 0; font: 700 0.8rem/1 ui-monospace, monospace;
  letter-spacing: .16em; text-transform: uppercase; color: var(--brass);
}
.sheet-head .sub { font-size: 0.62rem; color: var(--parch-dim); letter-spacing: .06em; }
.sheet-head .x {
  margin-left: auto; pointer-events: auto;
  width: max(34px, 2rem); height: max(34px, 2rem); flex: none;
  border: 1px solid var(--rule-soft); border-radius: 3px;
  background: transparent; color: var(--parch-dim);
  font: 700 0.8rem/1 monospace;
}
.sheet-head .x:active { background: var(--brass); color: var(--ink); }

.opt {
  pointer-events: auto;
  display: flex; align-items: center; gap: 0.6rem;
  width: 100%; text-align: left;
  min-height: max(48px, 3.1rem); padding: 0.5rem 0.6rem;
  margin-bottom: 0.36rem;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--rule-soft); border-radius: 3px;
  color: var(--parch); font: var(--ui);
}
.opt:last-child { margin-bottom: 0; }
.opt:active:not(:disabled) { background: rgba(200,168,96,.18); border-color: var(--rule); }
.opt:disabled { opacity: .4; }
/* A fitting already installed is not a dead option, it is an achievement, so it
   keeps its colour where a disabled row loses it. */
.opt.fitted { opacity: 1; border-color: var(--rule); background: rgba(200,168,96,.10); }
.opt.fitted .cost b { color: var(--sea); }
.opt .glyph {
  flex: none; width: 1.85rem; height: 1.85rem; border-radius: 2px;
  display: grid; place-items: center;
  background: rgba(200,168,96,.12); border: 1px solid var(--rule-soft);
  font-size: 0.92rem; line-height: 1;
}
.opt .body { flex: 1 1 auto; min-width: 0; }
.opt .body { display: block; }
.opt .name { display: block; font-weight: 700; letter-spacing: .06em; }
.opt .desc { display: block; font-size: 0.62rem; color: var(--parch-dim); margin-top: 3px; line-height: 1.35; }
.opt .cost { flex: none; text-align: right; }
.opt .cost b { color: var(--brass); font-size: 0.8rem; }
.opt .cost.cant b { color: var(--red); }
.opt .cost span { display: block; font-size: 0.56rem; color: var(--parch-dim); letter-spacing: .12em; margin-top: 2px; }

.ledger-row {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 0.3rem 0; border-bottom: 1px solid var(--rule-soft);
  font-size: 0.68rem;
}
.ledger-row:last-child { border-bottom: 0; }
.ledger-row span { color: var(--parch-dim); letter-spacing: .06em; }
.ledger-row b { color: var(--parch); font-weight: 700; }
.ledger-note { font-size: 0.62rem; color: var(--parch-dim); line-height: 1.5; margin-top: 10px; }

/* --- effect lines under a build option ---------------------------------- */

.opt .fx { display: block; margin-top: 5px; }
.opt .fx i {
  display: inline-block; font-style: normal;
  font-size: 10px; line-height: 1.1;
  color: var(--sea); letter-spacing: .04em;
  border: 1px solid rgba(88,192,184,.28); border-radius: 2px;
  padding: 2px 5px; margin: 0 4px 3px 0;
}

/* --- what already stands on the plot ------------------------------------ */

.stats {
  border: 1px solid var(--rule-soft); border-radius: 3px;
  background: rgba(200,168,96,.06);
  padding: 8px 10px; margin-bottom: 10px;
}
.stats-h {
  font-weight: 700; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--brass);
  padding-bottom: 5px; margin-bottom: 5px;
  border-bottom: 1px solid var(--rule-soft);
}
.stats-r { font-size: 11px; color: var(--parch); padding: 2px 0 2px 10px; position: relative; }
.stats-r::before { content: '•'; position: absolute; left: 0; color: var(--sea); }
.stats-n { font-size: 10px; color: var(--parch-dim); line-height: 1.45; margin-top: 6px; }

/* --- tab strip ----------------------------------------------------------
   Sticky, so it stays reachable in a long panel, and horizontally scrollable,
   because six policy groups do not fit across a phone in landscape. */

.tabs {
  position: sticky; top: -0.72rem; z-index: 1;
  display: flex; gap: 0.3rem;
  margin: -0.1rem -0.85rem 0.6rem;
  padding: 0.35rem 0.85rem 0.45rem;
  background: var(--panel-hi);
  border-bottom: 1px solid var(--rule-soft);
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  flex: none;
  min-height: max(32px, 1.9rem); padding: 0 0.7rem;
  border: 1px solid var(--rule-soft); border-radius: 3px;
  background: transparent; color: var(--parch-dim);
  font: 700 0.6rem/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: .12em; text-transform: uppercase;
  white-space: nowrap;
}
.tab.on { background: var(--brass); color: var(--ink); border-color: var(--brass); }
.tab:active:not(.on) { border-color: var(--rule); color: var(--parch); }

/* --- slider -------------------------------------------------------------- */

.slider {
  padding: 0.5rem 0.6rem 0.6rem;
  margin-bottom: 0.36rem;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--rule-soft); border-radius: 3px;
}
.slider-h {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 0.68rem; letter-spacing: .06em;
}
.slider-h span { color: var(--parch); font-weight: 700; }
.slider-h b { color: var(--brass); font-size: 0.8rem; white-space: nowrap; }
.slider-n { font-size: 0.62rem; color: var(--parch-dim); line-height: 1.4; margin-top: 5px; }

/* touch-action MUST be none. The page is `manipulation` and #sheet-inner is
   `pan-y`, so without this the first few pixels of a horizontal drag are eaten
   as a scroll gesture and the thumb jumps to wherever the finger ends up. */
.slider input[type=range] {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: max(30px, 1.8rem);
  margin-top: 0.35rem; background: transparent;
  touch-action: none;
}
.slider input[type=range]::-webkit-slider-runnable-track {
  height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, var(--rule) 0%, var(--rule-soft) 100%);
}
.slider input[type=range]::-moz-range-track {
  height: 3px; border-radius: 2px; background: var(--rule-soft);
}
.slider input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 1.15rem; height: 1.15rem; margin-top: calc(-0.575rem + 1.5px);
  border-radius: 2px; border: 1px solid var(--ink);
  background: var(--brass);
}
.slider input[type=range]::-moz-range-thumb {
  width: 1.15rem; height: 1.15rem;
  border-radius: 2px; border: 1px solid var(--ink);
  background: var(--brass);
}
.slider input[type=range]:disabled { opacity: .4; }

/* --- policy -------------------------------------------------------------- */

.pol {
  padding: 0.55rem 0.6rem 0.6rem;
  margin-bottom: 0.4rem;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--rule-soft); border-radius: 3px;
}
.pol-h {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 0.7rem; letter-spacing: .06em;
}
.pol-h span { color: var(--parch); font-weight: 700; }
.pol-h b { color: var(--parch-dim); font-size: 0.62rem; white-space: nowrap; }
.pol-h b.good { color: var(--sea); }
.pol-h b.bad { color: var(--red); }

.pol-now {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  margin-top: 0.3rem;
}
.pol-now b { color: var(--brass); font-size: 0.72rem; font-weight: 700; }
.pol-now i {
  font-style: normal; font-size: 0.56rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--parch-dim); white-space: nowrap;
}
.pol-desc { font-size: 0.62rem; color: var(--parch); line-height: 1.45; margin-top: 4px; }
.pol-note { font-size: 0.6rem; color: var(--parch-dim); line-height: 1.45; margin-top: 6px; }
.pol .fx { display: block; margin-top: 6px; }

/* A fork is centred, and the two names either side of the track are the whole
   point of the control: the status quo in the middle is a real answer, and each
   way out of it is a different policy rather than more of the same one. */
.fork-ends {
  display: flex; justify-content: space-between;
  font-size: 0.56rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--parch-dim);
  margin-top: 0.4rem;
}
.slider.fork input[type=range]::-webkit-slider-runnable-track {
  background: linear-gradient(90deg,
    rgba(200,80,64,.45) 0%, var(--rule-soft) 50%, rgba(88,192,184,.45) 100%);
}
.slider.fork input[type=range]::-moz-range-track {
  background: linear-gradient(90deg,
    rgba(200,80,64,.45) 0%, var(--rule-soft) 50%, rgba(88,192,184,.45) 100%);
}
.pol .slider {
  padding: 0; margin: 0; background: none; border: 0;
}

/* A relation, drawn from the centre so the sign is visible at a glance. */
.bar {
  position: relative; height: 4px; margin-top: 0.4rem;
  background: rgba(255,255,255,.06); border-radius: 2px; overflow: hidden;
}
.bar::before {
  content: ''; position: absolute; left: 50%; top: 0; bottom: 0;
  width: 1px; background: var(--rule-soft);
}
.bar i { position: absolute; top: 0; bottom: 0; border-radius: 2px; }
.bar i.pos { background: var(--sea); }
.bar i.neg { background: var(--red); }

/* --- modal --------------------------------------------------------------
   Between the sheet (4) and the boot screen (20). The scrim covers the whole
   stack and takes pointer events, which is what actually stops the camera
   panning under an open despatch. */

#modal {
  position: absolute; inset: 0; z-index: 5;
  display: flex; align-items: center; justify-content: center;
  padding: max(1rem, var(--safe-top)) max(24px, var(--safe-right))
           1rem max(24px, var(--safe-left));
  background: rgba(4, 7, 11, .72);
  touch-action: none;
}
#modal[hidden] { display: none; }

#modal-card {
  width: min(34rem, 100%);
  max-height: 88%;
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  touch-action: pan-y;
  padding: 0.85rem 0.9rem 1rem;
  background: var(--panel-hi);
  border: 1px solid var(--rule); border-radius: 4px;
  box-shadow: 0 18px 60px rgba(0,0,0,.6);
}
.modal-head { padding-bottom: 0.5rem; margin-bottom: 0.7rem; border-bottom: 1px solid var(--rule); }
.modal-head h2 {
  margin: 0; font: 700 0.86rem/1.2 ui-monospace, monospace;
  letter-spacing: .16em; text-transform: uppercase; color: var(--brass);
}
.modal-head .sub { font-size: 0.62rem; color: var(--parch-dim); letter-spacing: .06em; margin-top: 5px; }
.modal-body {
  font-size: 0.7rem; line-height: 1.6; color: var(--parch);
  margin-bottom: 0.8rem;
}
.modal-body p { margin: 0 0 0.6rem; }
.modal-body p:last-child { margin-bottom: 0; }

/* --- the chart -----------------------------------------------------------
   A period chart, on the same parchment the rest of the UI pretends to be.
   Crude coastlines on purpose: so were theirs. */

.chart-wrap {
  margin: 0 0 0.6rem;
  border: 1px solid var(--rule-soft); border-radius: 3px;
  background: #12161d;
  overflow: hidden;
}
svg.chart { display: block; width: 100%; height: auto; }

svg.chart .sea { fill: #10161f; }
svg.chart .land {
  fill: #26221a; stroke: rgba(200,168,96,.42); stroke-width: 1.4;
  stroke-linejoin: round;
}
svg.chart .isle { fill: #2c2820; stroke: rgba(200,168,96,.42); stroke-width: 1.1; }
svg.chart .bank { fill: none; stroke: rgba(88,192,184,.32); stroke-width: 1; }

/* Rhumb lines from a rose off the Main. Every chart of the period is ruled
   this way, and it is the single cheapest thing that makes an SVG read as one. */
svg.chart .rhumb { stroke: rgba(200,168,96,.10); stroke-width: 0.8; }
svg.chart .rose  { fill: none; stroke: rgba(200,168,96,.18); stroke-width: 0.9; }

svg.chart .port circle { fill: var(--brass); stroke: none; }
svg.chart .port text {
  fill: var(--parch-dim); font: 15px ui-monospace, monospace; letter-spacing: .06em;
}
svg.chart .port.shut circle { fill: none; stroke: var(--red); stroke-width: 2; }
svg.chart .port.shut text { fill: rgba(200,96,80,.85); }
svg.chart .port.known circle { fill: var(--sea); }

svg.chart .home circle { fill: none; stroke: var(--brass); stroke-width: 2.4; }
svg.chart .home circle:first-child { fill: var(--brass); }
svg.chart .home text {
  fill: var(--brass); font: 700 17px ui-monospace, monospace; letter-spacing: .18em;
}

svg.chart .track {
  stroke: rgba(88,192,184,.55); stroke-width: 1.6; stroke-dasharray: 7 6;
}
svg.chart .hull path { fill: var(--sea); stroke: none; }
svg.chart .hull .mast { stroke: var(--sea); stroke-width: 1.4; fill: none; }
svg.chart .hull-name {
  fill: var(--sea); font: 14px ui-monospace, monospace; letter-spacing: .06em;
}

svg.chart .cartouche text {
  fill: rgba(200,168,96,.55); font: 700 19px ui-monospace, monospace;
  letter-spacing: .22em;
}
svg.chart .cartouche text.small {
  font: 14px ui-monospace, monospace; letter-spacing: .14em;
  fill: rgba(200,168,96,.34);
}

/* --- boot / loading ----------------------------------------------------- */

#boot {
  position: absolute; inset: 0; z-index: 20;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  background: var(--ink);
  transition: opacity .7s ease-out;
}
#boot.done { opacity: 0; pointer-events: none; }
#boot-title {
  font: 700 2.1rem/1 ui-monospace, monospace;
  letter-spacing: .34em; text-indent: .34em;
  color: var(--brass);
}
#boot-sub {
  font-size: 0.62rem; letter-spacing: .38em; text-indent: .38em;
  color: var(--parch-dim); margin-bottom: 1.2rem;
}
#boot-bar {
  width: min(240px, 52vw); height: 2px;
  background: rgba(200,168,96,.18);
  overflow: hidden;
}
#boot-bar i { display: block; height: 100%; width: 0%; background: var(--brass); transition: width .3s ease-out; }
#boot-msg {
  margin-top: 0.6rem; font-size: 0.62rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--parch-dim);
  height: 0.8rem;
}

/* --- fatal error -------------------------------------------------------- */

#fatal {
  position: absolute; inset: 0; z-index: 40;
  padding: 40px 24px; overflow: auto;
  background: var(--ink); color: var(--red);
  font: 12px/1.5 ui-monospace, monospace; white-space: pre-wrap;
}

/* --- debug readout ------------------------------------------------------ */

#debug {
  position: absolute; z-index: 30;
  top: calc(var(--safe-top) + 58px); left: max(14px, var(--safe-left));
  padding: 5px 8px; border-radius: 2px;
  background: rgba(0,0,0,.7); border: 1px solid var(--rule-soft);
  font: 0.62rem/1.45 ui-monospace, monospace; color: var(--sea);
  white-space: pre; pointer-events: none;
}

/* --- Library home button ------------------------------------------------ */

#home {
  position: fixed; z-index: 50;
  top: calc(var(--safe-top) + 8px); right: 24px;
  min-height: max(32px, 1.9rem); padding: 0.36rem 0.66rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: rgba(0,0,0,.6); color: var(--parch);
  font: 700 0.68rem/1 ui-monospace, monospace; letter-spacing: .1em;
}
#home:active { background: var(--brass); color: var(--ink); }

#ui, #sheet, #boot { touch-action: none; }
#sheet-inner { touch-action: pan-y; }
