/* ============================================================
   NORTHWATER — core visual system
   Palette: wet asphalt, sodium lamp, oxblood, bone.
   ============================================================ */

:root{
  /* every form control in the game sits on near-black: tell the browser so,
     and checkboxes, ranges and selects come back dark instead of stock white */
  color-scheme: dark;
  --ink-900:#07090c;
  --ink-800:#0b0e13;
  --ink-700:#11151c;
  --ink-600:#181d26;
  --ink-500:#222935;
  --ink-400:#2f3846;
  --line:#39424f;

  --bone:#e8e3d8;
  --bone-dim:#b6b0a4;
  /* 4.48:1 on the darkest ground was a hair under the 4.5 that small text
     needs; one step lighter clears it without changing the look. */
  --bone-faint:#847f74;

  /* the tagline and the eyebrow labels are small text in this red: it has
     to clear 4.5:1 on ink-900 as well */
  --blood:#c96055;
  --blood-hot:#e05b4c;
  --blood-dim:#7e2f28;

  --sodium:#e6b24b;
  --sodium-dim:#8a6a2b;
  --cyan:#5fa8b8;
  --green:#6f9d6a;

  /* the HUD is one row on a desk and two on a phone; every layout that
     sits under it reads this instead of hard-coding 56px */
  --hud-h:56px;
  --safe-t:env(safe-area-inset-top, 0px);
  --safe-b:env(safe-area-inset-bottom, 0px);
  --safe-l:env(safe-area-inset-left, 0px);
  --safe-r:env(safe-area-inset-right, 0px);

  --radius:3px;
  --shadow-hard: 0 18px 40px -12px rgba(0,0,0,.85);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: "Avenir Next", "Helvetica Neue", Inter, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;
}

*,*::before,*::after{ box-sizing:border-box; }

html,body{ height:100%; }
body{
  margin:0;
  background:
    radial-gradient(1200px 700px at 70% -10%, #1a222e 0%, transparent 60%),
    linear-gradient(180deg,#0a0d12 0%, #07090c 100%);
  color:var(--bone);
  font-family:var(--serif);
  font-size:16px;
  line-height:1.55;
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
}

/* ---------- atmosphere layers ---------- */
/* The overscan only has to cover what the shift moves: the keyframes
   travel 2%, so 4% of bleed on every side is already a margin. It used to
   be 50%, which is a fixed, always-animating layer four times the area of
   the screen — paid for on every frame, on a phone, for nothing. */
#grain{
  position:fixed; inset:-4%; z-index:9000; pointer-events:none; opacity:.035;
  will-change:transform;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  animation:grainshift 1400ms steps(3,end) infinite;
}
@keyframes grainshift{
  0%{transform:translate(0,0)} 33%{transform:translate(-2%,1%)} 66%{transform:translate(1%,-2%)} 100%{transform:translate(0,0)}
}
#vignette{
  position:fixed; inset:0; z-index:8998; pointer-events:none;
  background:radial-gradient(120% 100% at 50% 40%, transparent 45%, rgba(0,0,0,.72) 100%);
}
/* Rain, at the weight of weather rather than of a screen door. It used to be
   two hard 1px rules drifting a full pass every 1.1s across everything the
   player was trying to read; the streaks caught the eye instead of the text.
   Now: fewer lines, softer than the paper they fall on, and slow enough that
   the eye settles. */
#rain{
  position:fixed; inset:0; z-index:8997; pointer-events:none; opacity:0; transition:opacity 1.4s ease;
  background-image:
    repeating-linear-gradient(101deg, rgba(184,206,226,.07) 0 1px, transparent 1px 19px),
    repeating-linear-gradient(97deg, rgba(184,206,226,.045) 0 1px, transparent 1px 34px);
  background-size:300px 300px, 460px 460px;
  animation:raindrift 3.4s linear infinite;
  mix-blend-mode:soft-light;
}
body.raining #rain{ opacity:.5; }
/* over a sheet of paper it is damp air, not weather */
body.raining:has(.cover-stage) #rain{ opacity:.22; }
@keyframes raindrift{ to{ background-position:-120px 300px, -180px 460px; } }

@media (prefers-reduced-motion: reduce){
  #grain{animation:none} #rain{animation:none}
  *{ animation-duration:.001ms !important; transition-duration:.08s !important; }
}

/* ---------- HUD ---------- */
#hud{
  position:fixed; top:0; left:0; right:0; height:var(--hud-h); z-index:600;
  display:flex; align-items:center; gap:18px; padding:0 16px;
  background:linear-gradient(180deg, rgba(7,9,12,.97), rgba(7,9,12,.78));
  border-bottom:1px solid var(--line);
  backdrop-filter:blur(6px);
}
#hud[hidden]{ display:none; }
.hud-left{ display:flex; align-items:center; gap:12px; min-width:230px; }
.hud-btn{
  background:transparent; border:1px solid var(--line); color:var(--bone-dim);
  width:32px; height:32px; border-radius:var(--radius); cursor:pointer; font-size:15px; line-height:1;
}
.hud-btn:hover{ border-color:var(--blood); color:var(--blood-hot); }
.hud-case{ display:flex; flex-direction:column; line-height:1.1; }
.hud-case span{ font:600 9px/1 var(--sans); letter-spacing:.22em; color:var(--blood); }
.hud-case strong{ font:400 14px/1.3 var(--serif); color:var(--bone-dim); white-space:nowrap;
  max-width:210px; overflow:hidden; text-overflow:ellipsis; }

#hud-tabs{ display:flex; gap:2px; flex:1; justify-content:center; }
.tab{
  background:transparent; border:0; border-bottom:2px solid transparent;
  color:var(--bone-faint); font:600 11px/1 var(--sans); letter-spacing:.16em; text-transform:uppercase;
  padding:10px 14px; cursor:pointer; transition:color .16s, border-color .16s; position:relative;
}
.tab:hover{ color:var(--bone); }
.tab.active{ color:var(--bone); border-bottom-color:var(--blood); }
.tab.accent{ color:var(--blood); }
.tab.accent:hover{ color:var(--blood-hot); }
.tab[disabled]{ opacity:.28; cursor:not-allowed; }
.tab .dot{
  position:absolute; top:5px; right:5px; width:6px; height:6px; border-radius:50%;
  background:var(--sodium); box-shadow:0 0 8px var(--sodium);
}

.hud-right{ display:flex; gap:16px; min-width:230px; justify-content:flex-end; }
.meter{ display:flex; align-items:center; gap:7px; }
.meter-label{ font:600 9px/1 var(--sans); letter-spacing:.18em; color:var(--bone-faint); }
.meter-bar{ width:74px; height:5px; background:var(--ink-600); border:1px solid var(--ink-400); overflow:hidden; }
.meter-bar i{ display:block; height:100%; width:100%; transition:width .45s cubic-bezier(.2,.8,.3,1); }
#meter-time .meter-bar i{ background:linear-gradient(90deg,var(--sodium-dim),var(--sodium)); }
#meter-cred .meter-bar i{ background:linear-gradient(90deg,var(--blood-dim),var(--blood)); }
.meter-val{ font:600 11px/1 var(--mono); color:var(--bone-dim); min-width:34px; }
.meter.warn .meter-bar i{ background:var(--blood-hot) !important; animation:pulse 1s infinite; }
@keyframes pulse{ 50%{ opacity:.35 } }

/* ---------- stage ---------- */
#stage{
  position:absolute; inset:0; padding-top:0; overflow:hidden;
}
body.in-game #stage{ top:var(--hud-h); }
/* decoration — the lamp glow, the pass of light — is wider than the screen on
   purpose; it must never become something the player can swipe sideways */
.screen{ position:absolute; inset:0; overflow-x:hidden; overflow-y:auto; animation:fadein .38s ease both; }
@keyframes fadein{ from{opacity:0; transform:translateY(8px)} to{opacity:1; transform:none} }

::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-track{ background:var(--ink-800); }
::-webkit-scrollbar-thumb{ background:var(--ink-400); border:2px solid var(--ink-800); }
::-webkit-scrollbar-thumb:hover{ background:var(--blood-dim); }

/* ---------- typography helpers ---------- */
h1,h2,h3{ font-weight:400; margin:0; }
.eyebrow{ font:600 10px/1 var(--sans); letter-spacing:.28em; text-transform:uppercase; color:var(--blood); }
.dim{ color:var(--bone-dim); }
.faint{ color:var(--bone-faint); }
.mono{ font-family:var(--mono); font-size:12px; letter-spacing:.02em; }
.prose{ font-family:var(--serif); font-size:16.5px; line-height:1.68; color:#d6d1c6; max-width:66ch; }
.prose em{ color:var(--bone); font-style:italic; }
.beat{ display:block; height:.75em; }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; gap:8px; justify-content:center;
  background:var(--ink-600); color:var(--bone); border:1px solid var(--line);
  padding:10px 18px; border-radius:var(--radius); cursor:pointer;
  font:600 11px/1 var(--sans); letter-spacing:.16em; text-transform:uppercase;
  transition:background .16s, border-color .16s, color .16s, transform .12s;
}
.btn:hover{ background:var(--ink-500); border-color:var(--bone-faint); }
.btn:active{ transform:translateY(1px); }
.btn.primary{ background:var(--blood-dim); border-color:var(--blood); color:#fff; }
.btn.primary:hover{ background:var(--blood); }
.btn.ghost{ background:transparent; }
.btn[disabled]{ opacity:.35; pointer-events:none; }
.btn.wide{ width:100%; }

/* ---------- cards / panels ---------- */
.panel{
  background:linear-gradient(180deg, rgba(24,29,38,.92), rgba(17,21,28,.92));
  border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-hard);
}
.panel-hd{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:11px 14px; border-bottom:1px solid var(--line);
  font:600 10px/1 var(--sans); letter-spacing:.22em; text-transform:uppercase; color:var(--bone-faint);
}
.panel-bd{ padding:14px; }

/* ---------- toasts ---------- */
#toaster{ position:fixed; right:18px; bottom:18px; z-index:9500; display:flex; flex-direction:column; gap:8px; align-items:flex-end; }
.toast{
  background:var(--ink-700); border-left:3px solid var(--sodium); color:var(--bone);
  padding:10px 14px; max-width:380px; box-shadow:var(--shadow-hard);
  font:400 14px/1.45 var(--serif); animation:toastin .3s ease both;
}
.toast.bad{ border-left-color:var(--blood); }
/* a test account: both meters are off, and the HUD says so plainly */
body.unmetered #meter-time i, body.unmetered #meter-cred i{
  background:repeating-linear-gradient(115deg, var(--sodium-dim) 0 6px, transparent 6px 12px);
  width:100% !important; opacity:.55; }
body.unmetered .meter-val{ color:var(--sodium); letter-spacing:.06em; }
body.unmetered #hud-case-no::after{
  content:'TEST'; margin-left:9px; padding:2px 6px; border:1px solid var(--sodium);
  color:var(--sodium); font:600 8px/1.4 var(--sans); letter-spacing:.18em; vertical-align:2px; }

.toast.good{ border-left-color:var(--green); }
.toast strong{ display:block; font:600 9px/1.6 var(--sans); letter-spacing:.2em; text-transform:uppercase; color:var(--bone-faint); }
.toast.out{ animation:toastout .35s ease both; }
@keyframes toastin{ from{opacity:0; transform:translateX(26px)} }
@keyframes toastout{ to{opacity:0; transform:translateX(26px)} }

/* ---------- modal ---------- */
#modal-root:empty{ display:none; }
.modal-scrim{
  position:fixed; inset:0; z-index:9200; background:rgba(4,5,7,.82);
  display:flex; align-items:center; justify-content:center; padding:24px;
  animation:fadein .2s ease both; backdrop-filter:blur(3px);
}
.modal{ width:min(640px,100%); max-height:86vh; overflow:auto; }
.modal .panel-bd{ padding:20px; }
.modal-actions{ display:flex; gap:10px; justify-content:flex-end; padding:0 20px 18px; }

/* film-strip divider */
.rule{ height:1px; background:linear-gradient(90deg, transparent, var(--line) 12%, var(--line) 88%, transparent); margin:18px 0; border:0; }

svg.portrait{ max-width:100%; height:auto; display:block; }

.kbd{ font:600 10px/1 var(--mono); border:1px solid var(--line); border-bottom-width:2px; padding:3px 5px; border-radius:3px; color:var(--bone-dim); }

/* the browser's own controls, dressed for the room */
input[type=checkbox]{ accent-color:var(--blood); }
/* no accent-color on the range: it makes the browser paint its own rail and
   thumb, which overrides the dark ones below */
input[type=range]{ -webkit-appearance:none; appearance:none; }
input[type=checkbox]{ width:19px; height:19px; cursor:pointer; }
input[type=range]{ width:min(180px,42vw); cursor:pointer; background:transparent; }
/* accent-color paints the filled part but leaves the stock white rail, which is
   the brightest thing on any screen in the game. Draw the rail ourselves. */
input[type=range]::-webkit-slider-runnable-track{ height:4px; border-radius:2px; background:var(--ink-500); }
input[type=range]::-moz-range-track{ height:4px; border-radius:2px; background:var(--ink-500); }
input[type=range]::-webkit-slider-thumb{ -webkit-appearance:none; appearance:none; margin-top:-6px;
  width:16px; height:16px; border-radius:50%; background:var(--blood); border:1px solid #1a0f0e; }
input[type=range]::-moz-range-thumb{ width:15px; height:15px; border-radius:50%;
  background:var(--blood); border:1px solid #1a0f0e; }
input:focus-visible, button:focus-visible, select:focus-visible{ outline:2px solid var(--sodium); outline-offset:2px; }
/* A screen takes focus when it mounts so the keyboard starts inside it.
   That is a place to stand, not a control, and drawing a ring around a
   heading every time the player clicks a tab reads as an error. */
.screen:focus, [tabindex="-1"]:focus{ outline:none; }

/* Only inside a file. The HUD is the thing worth skipping — six tabs and
   a menu between the top of the page and what the player is reading — and
   everywhere else there is nothing above the content to skip past. */
#skip{ display:none; }
body.in-game #skip{
  display:block;
  position:fixed; top:8px; left:8px; z-index:10000;
  transform:translateY(-200%);
  padding:10px 16px; border-radius:3px;
  background:var(--sodium); color:#12100c;
  font:600 14px/1 system-ui, sans-serif; letter-spacing:.04em;
  text-decoration:none;
}
body.in-game #skip:focus{ transform:none; }
