/*
 * The HD-2D layer and the content layer (tickets 930 and 973; design note §5, z/notes/console-design-*.md).
 *
 * Linked LAST in index.html, so it wins by source order and needs no !important. It changes how the
 * console is lit and layered, never what it says: text and data stay at native resolution.
 *
 * Two layers:
 *   decoration     one band, at most 160px tall, behind the top bar, the local nav row and the page head
 *                  (js/hd_band.js draws a pixel night harbor on its canvas; a masked backdrop blur gives the
 *                  tilt-shift on its top edge; a warm bloom sits behind the title). It scrolls away with
 *                  the page. The pointer light (js/pointer_light.js feeds --light-x/--light-y) lives only
 *                  inside it. The sign-in cove, the Home diorama, the War room harbor and the empty-state
 *                  vignette are the other places decoration may be (their own sheets).
 *   content        panels, tiles, tables, lists, forms, charts and text: flat, opaque, crisp. A plate is
 *                  `--panel` with a plain border. No blur, no gold edge, no hover lift, no bloom.
 * The control layer (the top bar, its menus, the search overlay, the phone tab bar) keeps its glass.
 *
 * The scene's light never uses the accent hue and never recolors status, severity or selection. Reduced
 * motion: the band is a still frame already (it is never animated) and the pointer light is off.
 * Reduced transparency or more contrast: every glass surface is opaque. Forced colors: system colours.
 *
 * Look rules: no web font, no CDN, no inline style, no image file (the band is drawn on a canvas).
 */

:root {
  /* The fill of the control layer's glass: the dense one of the top bar, a menu or the tab bar (the page
     text behind a menu must never read through it). */
  --hud-fill: rgba(22, 22, 26, 0.64);
  --hud-fill-2: rgba(20, 20, 24, 0.86);
  --plane-2: var(--hud-fill-2);

  /* The 1px gradient edge of a control-layer plate (also the sign-in card's). */
  --hud-edge: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.16),
    rgba(222, 199, 107, 0.22) 35%,
    rgba(255, 255, 255, 0.03) 70%
  );
  --hud-blur-2: 20px;

  /* The shadow that sets a menu, a dialog or the tab bar above the page. */
  --elev-3: 0 1px 0 rgba(255, 255, 255, 0.08) inset, 0 28px 64px -20px rgba(0, 0, 0, 0.9);

  /* Where the pointer is, in px. Off screen until the first move. */
  --light-x: -2000px;
  --light-y: -2000px;
}

/* ---- The band ---------------------------------------------------------------------------- */

/* Out of flow: it takes no height from the page (ticket 926), sits under the top bar, the local nav row
   and the page head (z-index -1 paints above the page colour and below all content), and scrolls away
   with the page. The bottom 40% fades into the page colour. Everything drawn here is dark enough that
   --ink-body text clears 4.5:1 over it (js/hd_band.js BAND_PALETTE). */
.hd-band {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 160px;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent);
  mask-image: linear-gradient(to bottom, #000 60%, transparent);
}

@media (max-width: 760px) {
  .hd-band {
    height: 120px;
  }
}

/* The canvas is a fixed wide strip anchored to the right: the moon and the buildings keep to the right
   edge and a wider screen shows more sky. js/hd_band.js sets data-scale (3 above 760px, 2 at 760px and
   narrower); the CSS size is a whole multiple of the canvas, so the pixels stay square. The 3x picture is
   162px tall and the band clips it to 160. */
.hd-band__scene {
  position: absolute;
  top: 0;
  right: 0;
  display: block;
  width: 3840px;
  height: 162px;
  image-rendering: pixelated;
}

.hd-band__scene[data-scale="2"] {
  height: 120px;
}

/* Tilt-shift on the top edge: a static strip whose backdrop is the picture, blurred a little and faded
   out going down. It sits inside the masked band, so it samples the canvas and nothing else. */
.hd-band::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 56px;
  z-index: 1;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
  mask-image: linear-gradient(to bottom, #000, transparent);
}

/* A soft warm bloom behind the title area at the left: low-alpha peach, never the accent. */
.hd-band::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(60%, 720px);
  z-index: 1;
  background: radial-gradient(ellipse at 18% 70%, rgba(255, 168, 112, 0.12), transparent 70%);
}

/* The sign-in cove is its own scene; the War room harbor and the Present board fill the screen. */
body.signed-out .hd-band,
body.is-kiosk .hd-band,
body.is-board .hd-band {
  display: none;
}

/* The local nav row sits fully over the band and the page head starts inside its fade, so neither has a
   fill of its own; the row's text is --ink-body or --ink, which clear 4.5:1 over any band pixel. */
.local-nav {
  background: none;
}

.local-nav__link {
  color: var(--ink-body);
}

.local-nav__link:hover,
.local-nav__link.is-current {
  color: var(--ink);
}

/* ---- The pointer light ------------------------------------------------------------------- */

/* One empty element inside the band (index.html) holds one moon-white glow. The glow is painted once and
   only moved, by `transform`, to where js/pointer_light.js says the pointer is; the band clips it. The
   blend is on the overlay, not on the glow: a blend mode only reaches what is inside its own stacking
   context (the band's). No `background-attachment: fixed`: it repaints on scroll and iOS ignores it. */
.depth-light {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
  mix-blend-mode: screen;
}

.depth-light::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 640px;
  height: 640px;
  background: radial-gradient(circle, rgba(190, 205, 255, 0.08), transparent 45%);
  transform: translate3d(calc(var(--light-x) - 320px), calc(var(--light-y) - 320px), 0);
  will-change: transform;
}

/* No pointer to follow on a touch screen. */
@media (hover: none) {
  .depth-light {
    display: none;
  }
}

/* ---- The content layer: flat, opaque, crisp ------------------------------------------------- */

.card,
.stat-tile,
.table-scroll,
.glass,
.home-number {
  background: var(--panel);
  border: 1px solid var(--border);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}

/* The page head (js/page_head.js, tickets 931 and 972) has no plate and no hairline: the title sits on
   the foot of the band. z-index 1 lifts the head's menus (the Reports "Present" menu) over the panels drawn
   after it. The strip it carries from index.html (#evidence-summary) is hidden at its home on the pages
   that move it into the head, so the page does not jump up when the head draws it (ticket 926); the
   Overview board keeps it at home. */
.workspace-head {
  position: relative;
  z-index: 1;
  padding: var(--space-4) 0 var(--space-3);
}

body[data-route="investigate"] #evidence-summary:not(.is-in-head),
body[data-route="decoys"] #evidence-summary:not(.is-in-head),
body[data-route="reports"] #evidence-summary:not(.is-in-head),
body[data-route="war-room"] #evidence-summary:not(.is-in-head),
body[data-route="overview"]:not(.is-board) #evidence-summary:not(.is-in-head) {
  display: none;
}

/* A home tile whose value is text ("Oct 21, 17:46 UTC") takes one step down and one line, cut with
   an ellipsis if the column is ever too narrow; the full text rides on its title. */
.home-number__value--text {
  font-size: var(--fs-lg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-mono);
}

/* The Filters dialog and the request detail drawer hold forms, tables and text, so they are opaque; a
   shadow alone sets them above the page. The overlay itself stays the dark scrim it is. */
.capture-settings {
  background: var(--panel);
  border: 1px solid var(--border-strong);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--elev-3);
}

.detail-panel {
  background: var(--panel);
  border-left: 1px solid var(--border-strong);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--elev-3);
}

/* ---- The control layer: menus and the top bar -------------------------------------------- */

.nav-panel,
.global-search__results {
  background:
    linear-gradient(var(--plane-2), var(--plane-2)) padding-box,
    var(--hud-edge) border-box;
  border: 1px solid transparent;
  -webkit-backdrop-filter: blur(var(--hud-blur-2)) saturate(140%);
  backdrop-filter: blur(var(--hud-blur-2)) saturate(140%);
  box-shadow: var(--elev-3);
}

/* The top bar is glass over the band, with a neutral hairline under it. The glass is on ::before, not on
   the navbar itself: an element with a backdrop-filter is a backdrop root, which would make the menus
   inside it blur only the navbar and not the page behind them. This replaces console-simple.css's solid
   #111 navbar on purpose. */
.navbar {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom: 1px solid transparent;
  box-shadow: 0 10px 28px -20px rgba(0, 0, 0, 0.85);
}

.navbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(var(--plane-2), var(--plane-2));
  -webkit-backdrop-filter: blur(var(--hud-blur-2)) saturate(140%);
  backdrop-filter: blur(var(--hud-blur-2)) saturate(140%);
}

.navbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  pointer-events: none;
  background: rgba(255, 255, 255, 0.08);
}

/* ---- The empty-state vignette (js/pixel_vignette.js) ---------------------------------------- */

/* A 64x44 picture at 3x, above the one line of fact in an empty state or on the not-found page. */
.pixel-vignette {
  display: block;
  width: 192px;
  height: 132px;
  image-rendering: pixelated;
}

/* ---- Fallbacks -------------------------------------------------------------------------- */

/* No backdrop-filter: a glass fill would show the page text through it, so the control layer goes solid
   and the band has no tilt-shift. */
@supports not (backdrop-filter: blur(1px)) {
  :root {
    --hud-fill: var(--panel);
    --hud-fill-2: var(--panel);
  }

  .hd-band::before {
    display: none;
  }
}

/* Reduced transparency: every remaining glass surface is opaque (the top bar, its menus, the search
   overlay and the tab bar read --plane-2) and the band has no blur layer. */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --hud-fill: var(--panel);
    --hud-fill-2: var(--panel);
  }

  .nav-panel,
  .global-search__results,
  .navbar::before,
  .hd-band::before {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .hd-band::before,
  .depth-light {
    display: none;
  }
}

/* More contrast: every panel is opaque and the picture goes. */
@media (prefers-contrast: more) {
  :root {
    --hud-fill: var(--panel);
    --hud-fill-2: var(--panel);
  }

  .nav-panel,
  .global-search__results,
  .navbar::before,
  .view-root:has(> .login-brand) > .login-panel {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .hd-band {
    display: none;
  }
}

/* Forced colors: the system palette rules. No glass, picture, light or bloom; panels keep a plain system
   border. */
@media (forced-colors: active) {
  .card,
  .stat-tile,
  .table-scroll,
  .glass,
  .home-number,
  .nav-panel,
  .global-search__results,
  .capture-settings {
    background: Canvas;
    border: 1px solid CanvasText;
    box-shadow: none;
  }

  .detail-panel {
    background: Canvas;
    border-left: 1px solid CanvasText;
    box-shadow: none;
  }

  .navbar {
    background: Canvas;
    box-shadow: none;
    border-bottom: 1px solid CanvasText;
  }

  .navbar::before,
  .navbar::after,
  .hd-band,
  .pixel-vignette {
    display: none;
  }
}

/* Reduced motion: no light follows the pointer. The band is never animated, so it is already still. */
@media (prefers-reduced-motion: reduce) {
  .depth-light {
    display: none;
  }
}

/* On a phone the Investigations list is a stack of row cards and its wrapper is deliberately flat
   (investigations.css, 640px and narrower), so the wrapper is not a panel there. Last in the file so it
   also wins over the forced-colors border above. */
@media (max-width: 640px) {
  .investigations-scroll {
    background: none;
    border: 0;
    box-shadow: none;
  }
}

/* A printed page is flat and white: no picture, no light, no vignette. */
@media print {
  .hd-band,
  .navbar::before,
  .navbar::after,
  .pixel-vignette {
    display: none;
  }

  .workspace-head {
    padding-inline: 0;
  }
}
