/* ==========================================================================
   nsg.github.io — hand-written stylesheet, no build step.

   Art direction: a tmux session.
     dark   = Gruvbox dark  (the primary look: soft black, warm off-white ink)
     light  = Gruvbox light (warm paper, dark ink, the same accent semantics)
   Motifs: tiled panes sharing single 1px borders with titles on the border,
   a bash prompt with host / path / branch segments, an htop pane drawn with
   real characters, a ruler for the operating range, a status line at the
   bottom that doubles as navigation. One font, one size for running text;
   every vertical distance is a multiple of one line (--lh), every horizontal
   one is measured in ch.

   Colour semantics (same in both themes):
     green  = user@host, running things, active pane
     blue   = paths and links
     aqua   = command words, labels
     yellow = git branch, the current window, search hits
     red    = the hot end of a meter
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   The dark palette appears twice on purpose: once for the explicit toggle
   ([data-theme="dark"]) and once as a no-JS fallback for the OS preference.
   Keep the two blocks identical.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  --mono: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Cascadia Mono",
          "Roboto Mono", "DejaVu Sans Mono", "Liberation Mono", monospace;
  --fs: 15px;
  --lh: 24px;

  --bg: #f9f5d7;          /* paper */
  --bar: #ebdbb2;         /* status line */
  --border: #bdae93;
  --fg: #3c3836;          /* ink */
  --fg-bright: #282828;
  --dim: #665c54;         /* comments, muted text, AA on --bg */
  --dim-bar: #665c54;     /* muted text on the status line */
  --green: #6c680b;
  --aqua: #3a6e4f;
  --blue: #076678;
  --yellow: #8f5a0a;      /* yellow as text */
  --red: #9d0006;
  --sel: #d79921;         /* yellow as a background (current window, hits) */
  --sel-fg: #282828;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #1d2021;
  --bar: #3c3836;
  --border: #504945;
  --fg: #ebdbb2;
  --fg-bright: #fbf1c7;
  --dim: #a89984;
  --dim-bar: #bdae93;
  --green: #b8bb26;
  --aqua: #8ec07c;
  --blue: #83a598;
  --yellow: #fabd2f;
  --red: #fb4934;
  --sel: #fabd2f;
  --sel-fg: #1d2021;
}

/* No-JS fallback: identical to the block above. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #1d2021;
    --bar: #3c3836;
    --border: #504945;
    --fg: #ebdbb2;
    --fg-bright: #fbf1c7;
    --dim: #a89984;
    --dim-bar: #bdae93;
    --green: #b8bb26;
    --aqua: #8ec07c;
    --blue: #83a598;
    --yellow: #fabd2f;
    --red: #fb4934;
    --sel: #fabd2f;
    --sel-fg: #1d2021;
  }
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

html { scroll-padding-top: var(--lh); }

body {
  margin: 0;
  padding: var(--lh) 0 calc(var(--lh) * 2);   /* room for the title on the top border and the status line */
  background: var(--bg);
  color: var(--fg);
  font: 400 var(--fs) / var(--lh) var(--mono);
  -webkit-text-size-adjust: 100%;
}

h1, h2, p, ul, ol, dl, dd, pre, figure { margin: 0; padding: 0; font-size: inherit; line-height: inherit; }
ul, ol { list-style: none; }
b, strong { font-weight: 700; }
small { font-size: inherit; }

a { color: var(--blue); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--yellow); }
a:focus-visible, button:focus-visible { outline: 1px solid var(--yellow); outline-offset: 2px; }

::selection { background: var(--sel); color: var(--sel-fg); }

.dim { color: var(--dim); }
.prose { max-width: 78ch; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Skip link, rendered like a tmux message line */
.skip {
  position: absolute; left: -999ch; top: 0; z-index: 3;
  padding: 0 1ch;
  background: var(--sel); color: var(--sel-fg);
  text-decoration: none;
}
.skip:focus { left: 2ch; }

/* --------------------------------------------------------------------------
   3. Panes — tiled, sharing single 1px borders like a real multiplexer
   -------------------------------------------------------------------------- */
.term { max-width: 180ch; margin: 0 auto; }

.win { display: grid; grid-template-columns: minmax(0, 1fr); }
.win + .win { margin-top: -1px; }                 /* stacked windows share the horizontal rule */
.win.hero { grid-template-columns: minmax(0, 1fr) 52ch; }
.win.split { grid-template-columns: 1fr 1fr; }

.pane {
  position: relative;
  min-width: 0;
  padding: var(--lh) 2ch;
  border: 1px solid var(--border);
}
.win > .pane + .pane { border-left: 0; }          /* vertical split: one shared line */

/* pane-border-status top: the title sits on the border line */
.pane .title {
  position: absolute; top: -1px; left: 1ch;
  transform: translateY(-50%);
  margin: 0; padding: 0 1ch;
  max-width: calc(100% - 4ch);
  background: var(--bg); color: var(--dim);
  font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.title .idx { color: var(--dim); }

/* The active pane gets the green border and a reversed index, as tmux does */
.pane.active { border-color: var(--green); }
.pane.active .title { color: var(--fg); }
.pane.active .title .idx { background: var(--green); color: var(--bg); padding: 0 1ch; margin-right: 1ch; }
.win.hero > .pane + .pane { border-left: 1px solid var(--green); }
.win.hero > .pane.active { height: calc(var(--lh) * 25 + 2px); padding: 0; }
.win.hero > .pane.active::after {
  content: "";
  position: absolute; z-index: 1; top: 0; left: 0; right: 1ch;
  height: var(--lh);
  background: var(--bg);
  pointer-events: none;
}
.win.hero > .pane.active .title { z-index: 2; }
.win.hero > .pane.active .pane-scroll {
  height: 100%;
  padding: var(--lh) 2ch;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--dim) var(--bar);
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}
.win.hero > .pane.active .pane-scroll::-webkit-scrollbar { width: 1ch; }
.win.hero > .pane.active .pane-scroll::-webkit-scrollbar-track { background: var(--bar); }
.win.hero > .pane.active .pane-scroll::-webkit-scrollbar-thumb { background: var(--dim); }

/* --------------------------------------------------------------------------
   4. Prompt and command lines
   -------------------------------------------------------------------------- */
.cmd { overflow-wrap: anywhere; }
.ps1 .uh  { color: var(--green); font-weight: 700; }   /* user@host */
.ps1 .cwd { color: var(--blue); }                      /* working directory */
.ps1 .git { color: var(--yellow); }                    /* branch */
.cmd .c { color: var(--aqua); }                        /* command word */
.cmd .p { color: var(--blue); }                        /* path argument */
.cmd .k { color: var(--dim); font-style: italic; }     /* # comment */

/* The last prompt is a small, safe command interpreter (terminal.js).
   It is never focused automatically: mobile keyboards therefore open only
   after a deliberate tap on this prompt. */
.terminal { margin-top: var(--lh); }
.terminal-output > * { margin-bottom: var(--lh); }
.terminal-output > :last-child { margin-bottom: 0; }
.terminal-output .terminal-command { margin-bottom: 0; }
.terminal-output pre {
  margin-bottom: var(--lh);
  overflow-x: auto;
  color: var(--fg);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.terminal-welcome .c { color: var(--aqua); }
.terminal-form { display: flex; align-items: baseline; min-width: 0; }
.terminal-form > .ps1 { flex: 0 0 auto; cursor: text; }
.terminal-entry { position: relative; flex: 1 1 auto; min-width: 2ch; }
.terminal-input {
  display: block; width: 100%; min-width: 0; margin: 0; padding: 0 0 0 1ch;
  border: 0; border-radius: 0; outline: 0; background: transparent;
  color: var(--fg-bright); caret-color: var(--fg); font: inherit;
  appearance: none;
}
.terminal-input:focus { outline: 1px solid transparent; }
.terminal-entry .cursor { position: absolute; left: 1ch; top: 2px; pointer-events: none; }
.terminal-input:focus + .cursor,
.terminal-input:not(:placeholder-shown) + .cursor { display: none; }
.terminal-link { color: var(--blue); }
.terminal-error { color: var(--red); }

.cursor {
  display: inline-block; width: 1ch; height: calc(var(--lh) - 4px);
  vertical-align: -3px;
  background: var(--fg);
}

/* one blank line around command output */
.out { margin-top: var(--lh); margin-bottom: var(--lh); }
.out:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   5. Sections
   -------------------------------------------------------------------------- */

/* 5a. about.md, shown as cat would print it, markdown syntax dimmed */
.md > * + * { margin-top: var(--lh); }
.md .eyebrow { color: var(--aqua); }
.md h1 {
  font-size: calc(var(--fs) * 2); line-height: calc(var(--lh) * 2);
  font-weight: 700; letter-spacing: -0.02em;
  color: var(--fg-bright);
}
.md .tag { font-weight: 700; }
.md .links li + li { margin-top: 0; }

/* 5b. htop pane: drawn with real characters, coloured with meaning */
.htop { overflow: hidden; white-space: pre; }
.htop .g { color: var(--green); }
.htop .y { color: var(--yellow); }
.htop .r { color: var(--red); }
.htop .v { color: var(--fg-bright); }
.htop .n { color: var(--aqua); }
.htop .hdr { display: inline-block; width: 44ch; background: var(--green); color: var(--bg); }
.htop .S { color: var(--dim); }
.htop .R { color: var(--green); font-weight: 700; }
.htop .bin { font-weight: 700; }

/* 5c. nsg --info: aligned key/value pairs */
.info { display: grid; grid-template-columns: 20ch minmax(0, 1fr); max-width: 100ch; }
.info dt { color: var(--aqua); }
.info dt::after { content: ":"; color: var(--dim); }
.info dd { max-width: 78ch; }

/* 5d. ls -F output: directories bold blue, trailing slash plain */
.ls { display: flex; flex-wrap: wrap; gap: 0 2ch; max-width: 90ch; }
.ls li { color: var(--blue); font-weight: 700; }
.ls li::after { content: "/"; color: var(--fg); font-weight: 400; }

/* 5e. Operating range: a ruler with major and minor ticks */
.range { display: grid; grid-template-columns: repeat(5, 1fr); max-width: 104ch; padding-top: 1px; }
.range li { position: relative; padding: var(--lh) 0 0 1ch; }
.range li::before {                               /* axis and minor ticks */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: var(--lh);
  border-top: 1px solid var(--aqua);
  background: repeating-linear-gradient(90deg, var(--dim) 0 1px, transparent 1px 2ch) left top / 100% 5px no-repeat;
}
.range li::after {                                /* major tick */
  content: ""; position: absolute; left: 0; top: 0; width: 1px; height: calc(var(--lh) / 2);
  background: var(--aqua);
}
.range li:last-child { border-right: 1px solid var(--aqua); }
.range small { display: block; color: var(--dim); }

/* 5f. less footer, grep-style hit, [Y/n] answer */
.less { display: inline-block; padding-right: 1ch; background: var(--fg); color: var(--bg); }
.hit { background: var(--sel); color: var(--sel-fg); padding: 0 0.5ch; }
.yn .y { color: var(--green); font-weight: 700; }

/* 5g. Footer: outside the session, after detach */
.foot { max-width: 180ch; margin: 0 auto; padding: var(--lh) 2ch; }
.foot .msg { color: var(--yellow); }

/* --------------------------------------------------------------------------
   6. Status line — pinned, one line, reads like tmux
   -------------------------------------------------------------------------- */
.status {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; gap: 1ch;
  padding: 0 1ch;
  overflow-x: auto; scrollbar-width: none;
  background: var(--bar); color: var(--dim-bar);
  white-space: nowrap;
}
.status::-webkit-scrollbar { display: none; }
.status .sess { color: var(--green); font-weight: 700; }
.windows { display: flex; flex: 1; }
.status .w { color: var(--fg); text-decoration: none; padding: 0 1ch; }
.status .w:hover { color: var(--yellow); }
.status .w::after { content: attr(data-flag); }
.status .right { display: flex; gap: 1ch; margin-left: auto; }

/* current-window flag follows the :target, no JavaScript needed */
.w-about[data-flag] { background: var(--sel); color: var(--sel-fg); font-weight: 700; }
body:has(#sheet:target, #account:target, #contact:target) .w-about { background: none; color: var(--fg); font-weight: 400; }
body:has(#sheet:target, #account:target, #contact:target) .w-about::after { content: "-"; }
body:has(#sheet:target) .w-sheet,
body:has(#account:target) .w-account,
body:has(#contact:target) .w-contact { background: var(--sel); color: var(--sel-fg); font-weight: 700; }
body:has(#sheet:target) .w-sheet::after,
body:has(#account:target) .w-account::after,
body:has(#contact:target) .w-contact::after { content: "*"; }

/* Theme switch: a status-right segment that is a real button.
   theme.js mirrors the dark theme in aria-checked; CSS shows the matching word. */
.switch {
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: var(--fg); cursor: pointer;
}
.switch:hover { color: var(--yellow); }
.switch__label { color: var(--dim-bar); }
.switch__on { display: none; }
.switch[aria-checked="true"] .switch__on { display: inline; }
.switch[aria-checked="true"] .switch__off { display: none; }

/* --------------------------------------------------------------------------
   7. Motion
   -------------------------------------------------------------------------- */
.cursor { animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .cursor { animation: none; }
}

/* --------------------------------------------------------------------------
   8. Responsive — one column, borders re-joined, ruler turns vertical
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
  :root { --fs: 13px; --lh: 22px; }

  .win.hero > .pane.active { height: calc(var(--lh) * 28 + 2px); }

  .win.hero, .win.split { grid-template-columns: minmax(0, 1fr); }
  .win > .pane + .pane { border-left: 1px solid var(--border); border-top: 0; }
  .win.hero > .pane + .pane { border-left-color: var(--green); border-top: 0; }
  .monitor, .range-command, .range { display: none; }

  .info { grid-template-columns: minmax(0, 1fr); }
  .info dd { padding-left: 2ch; }

  /* tmux never wraps its status line: smaller type, tighter segments,
     session name and clock dropped, the switch shortened to [dark] / [light] */
  .status { font-size: 11px; }
  .status .w { padding: 0 0.5ch; }
  .status .sess, .status .host { display: none; }
  .switch__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
