/* ---------------------------------------------------------------
   Shared dark terminal / CRT theme
   Imported by both the landing page and the bookshelf.
   ------------------------------------------------------------- */

:root {
  color-scheme: dark;
  --bg: #14161a;
  --bg-elevated: #1e2127;
  --text: #eceef2;
  --text-muted: #a6adb8;
  --text-faint: #737a86;
  --border: #30353e;
  --accent: #8ab0dd;
  --accent-soft: #1f2a38;
  --mono: "SF Mono", "Menlo", "Consolas", monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  line-height: 1.5;
  min-height: 100vh;
  /* Phosphor glow — one strength everywhere (the heavier variant). */
  text-shadow: 0 0 1.5px rgba(138, 176, 221, 0.45);
}

/* Deploy stamp (vYYYYMMDDHHMM) in the connect line: half as visible as
   the faint line it sits in. */
.build-tag { color: #454b55; }

/* While arrow navigation drives the selection (keynav.js sets kbd-nav),
   the idle mouse cursor must not paint a second one: pointer-events off
   kills :hover until the mouse actually moves again. */
html.kbd-nav body { pointer-events: none; }

/* =====================================================================
   CRT SCANLINE SYSTEM

   body::after    0.22  OVER text    page bg, modal bg (z-index 10)
   .crt-heavy     0.22  BEHIND text  data items (::before, z-index -1)
   .crt-light     0.15  OVER text    header chrome (::after, z-index 1)
   hover/select   0.11  BEHIND text  via .selectable background-image

   Data items (cards, articles) carry .crt-heavy — lifted above
   body::after (z-11), own scanlines behind text so text reads clean.
   On hover, .selectable switches to 0.11 intensity.

   All layers share the same fixed-grid gradient so scanlines align.
   ===================================================================== */

/* --- .crt-heavy: standard scanlines BEHIND text via ::before -------- */
.crt-heavy {
  position: relative;
  z-index: 11;
  background-color: var(--bg);
}
.crt-heavy::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: -1;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.22) 0 1px, transparent 1px 3px);
  background-attachment: fixed;
  border-radius: inherit;
}

/* --- .crt-light: lighter scanlines OVER text via ::after ------------- */
.crt-light {
  position: relative;
  z-index: 11;
  background-color: var(--bg-elevated);
}
.crt-light::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.15) 0 1px, transparent 1px 3px);
  background-attachment: fixed;
  border-radius: inherit;
}
/* ::after does not work on <input> and <select> (void/replaced
   elements). Fall back to background-image (behind text — acceptable
   for short-label controls). */
input.crt-light,
select.crt-light {
  background-image: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.15) 0 1px, transparent 1px 3px);
  background-attachment: fixed;
}

/* --- .crt-clean: lightest scanlines, text reads clean ---------------- */
.crt-clean {
  position: relative;
  z-index: 11;
  background-color: var(--bg);
  background-image: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.11) 0 1px, transparent 1px 3px);
  background-attachment: fixed;
}

/* =====================================================================
   SELECTION COMPONENT — the single definition of what "selected" looks
   like, for EVERY selectable item on the site (menu entries, book
   cards, news items). Modules mark items with class="selectable" and
   MUST NOT hand-roll their own item hover/focus styles.

   On hover the item transitions to .crt-clean intensity (0.11) with a
   category-hued tint.
   ===================================================================== */
.selectable {
  border: 1px solid transparent;
  border-radius: 5px;
  cursor: pointer;
}
.selectable.passive { cursor: default; }
.selectable:hover,
.selectable:focus-visible,
.selectable:active {
  border-color: var(--sel, var(--cat, var(--accent)));
  background-color: var(--bg);
  background-image:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.11) 0 1px, transparent 1px 3px),
    linear-gradient(
      var(--sel-soft, var(--cat-soft, var(--accent-soft))),
      var(--sel-soft, var(--cat-soft, var(--accent-soft))));
  background-attachment: fixed;
  outline: none;
  position: relative;
  z-index: 11;
}
/* When a selectable item carries .crt-light, hide the ::after overlay
   on selection — the background-image scanlines take over. */
.selectable.crt-light:hover::after,
.selectable.crt-light:focus-visible::after,
.selectable.crt-light:active::after {
  content: none;
}
/* Same for .crt-heavy: hide the ::before overlay on selection. */
.selectable.crt-heavy:hover::before,
.selectable.crt-heavy:focus-visible::before,
.selectable.crt-heavy:active::before {
  content: none;
}

body::after {
  content: "";
  position: fixed; inset: 0; z-index: 10; pointer-events: none;
  background: repeating-linear-gradient(0deg,
    rgba(0,0,0,0.22) 0 1px, transparent 1px 3px);
}

/* Keyboard focus fallback: anything without its own :focus-visible
   treatment gets a visible accent ring. Components that already style
   focus like their hover state (menu entries, cards, news items)
   override this with outline: none. Mouse clicks never show it —
   that's what :focus-visible gives over :focus. */
:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 2px;
}

/* =====================================================================
   MOBILE / TOUCH — background-attachment: fixed is what viewport-anchors
   every element's scanlines so they align seamlessly (desktop: perfect).
   But mobile browsers (iOS Safari/iPad, mobile Firefox) rasterize fixed
   backgrounds wrong — the 1px/3px grid renders as coarse thick bands.
   On touch devices we drop back to `scroll`: each element paints its own
   scanlines from its own top. They stay crisp; the only cost is that the
   grid phase can jump slightly at element edges instead of aligning
   across the page — a fair trade for legible lines. body::after is a
   position:fixed element (not background-attachment), so it is unaffected
   and keeps painting the crisp page-level grid. */
@media (hover: none), (pointer: coarse) {
  .crt-heavy::before,
  .crt-light::after,
  input.crt-light,
  select.crt-light,
  .crt-clean,
  .selectable:hover,
  .selectable:focus-visible,
  .selectable:active {
    background-attachment: scroll;
  }
}
