/*
  File: style.css
  Description:
  Main stylesheet for hal.portal.

  Purpose:
  - Define the visual layout and theme for the static portal
  - Support a terminal/CLI aesthetic with the Nord colour palette
  - Style dynamic status content rendered by portal.js
  - Keep the design lightweight, readable, and maintainable

  Theme:
  - Monospace font throughout
  - Sharp corners — no border-radius anywhere
  - High-contrast dark background (#1e2430) with accent highlights (#88c0d0)
  - Scanline overlay for a CRT/terminal feel
  - Status animations: pulse (online), blink (degraded)
  - Badges are rectangular with a coloured border matching their text
*/

/* -------------------------------------------------------------------------- */
/* Root theme variables — Nord-inspired palette                               */
/* -------------------------------------------------------------------------- */

:root {
  /* Core palette */
  --bg:      #1e2430;
  --surface: #2a3344;
  --text:    #ffffff;
  --accent:  #88c0d0;
  --muted:   #8fa1b3;
  --border:  rgba(136, 192, 208, 0.3);

  /* Status colours */
  --ok-bg:     #1e3320;
  --ok-text:   #c0e89a;
  --warn-bg:   #3a2e14;
  --warn-text: #f5d58a;
  --bad-bg:    #3a1e1e;
  --bad-text:  #e07a7a;

  --neutral-bg:   rgba(255, 255, 255, 0.05);
  --neutral-text: var(--muted);
}

/* -------------------------------------------------------------------------- */
/* Base reset and page defaults                                               */
/* -------------------------------------------------------------------------- */

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: 'Courier New', Courier, monospace;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--bg);
  line-height: 1.6;
}

/*
  Scanlines overlay — repeating horizontal bands to mimic a CRT terminal.
  pointer-events: none ensures it never blocks any interaction.
  z-index places it above all content without hiding anything.
*/
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  background: repeating-linear-gradient(
    to bottom,
    transparent,
    transparent 2px,
    rgba(0, 0, 0, 0.07) 2px,
    rgba(0, 0, 0, 0.07) 4px
  );
}

/*
  Center and constrain content width so the layout remains readable
  on large displays.
*/
.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2rem 1.2rem 3rem;
}

/* -------------------------------------------------------------------------- */
/* Typography                                                                 */
/* -------------------------------------------------------------------------- */

h1,
h2,
h3,
p {
  margin-top: 0;
}

/*
  All headings follow the terminal convention: uppercase with slight spacing.
  Accent colour marks them as structural, not content.
*/
h1,
h2,
h3 {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent);
}

a {
  color: inherit;
}

/* -------------------------------------------------------------------------- */
/* Hero section                                                               */
/* -------------------------------------------------------------------------- */

.hero {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

/*
  Logo is rendered as a square in line with the sharp-corners principle.
  The accent border frames it as an operational element.
*/
.logo {
  width: 56px;
  height: 56px;
  border-radius: 0;
  flex-shrink: 0;
}

/*
  The prompt-style prefix on h1 reinforces the terminal aesthetic
  without altering the accessible text content.
*/
.hero h1::before {
  content: '> ';
  color: var(--accent);
}

.hero h1 {
  margin: 0;
  font-size: clamp(1.4rem, 4vw, 2.2rem);
}

/* -------------------------------------------------------------------------- */
/* Dashboard sections                                                         */
/* -------------------------------------------------------------------------- */

.dashboard-section {
  margin-top: 2.2rem;
}

/* -------------------------------------------------------------------------- */
/* Status grid                                                                */
/* -------------------------------------------------------------------------- */

/*
  The grid is the main dynamic rendering target.
  minmax(280px, 1fr) keeps panels readable at any viewport width.
*/
.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}

/*
  The 2px accent top border visually anchors each panel as an operational
  unit, consistent with the style guide's card convention.
*/
.status-group {
  padding: 1rem;
  border-radius: 0;
  border: 1px solid var(--border);
  border-top: 2px solid var(--accent);
  background: var(--surface);
}

.status-group h3 {
  margin: 0 0 0.85rem;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
}

.status-loading {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
}

/* -------------------------------------------------------------------------- */
/* Status line items                                                          */
/* -------------------------------------------------------------------------- */

.status-line {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.8rem;
  align-items: start;
  padding: 0.8rem 0;
  border-bottom: 1px solid rgba(136, 192, 208, 0.1);
}

.status-line:last-child {
  border-bottom: none;
}

.status-line-left {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 0.2rem;
}

.status-name {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
  word-break: break-word;
}

.status-description {
  font-size: 0.8rem;
  color: var(--muted);
  word-break: break-word;
}

.status-line-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.45rem;
  min-width: fit-content;
}

/* -------------------------------------------------------------------------- */
/* Status dot                                                                 */
/* -------------------------------------------------------------------------- */

/*
  The status dot is a small square indicator rendered inside each badge.
  border-radius: 0 keeps it sharp. Animated variants show live state.
*/
.status-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 0;
  flex-shrink: 0;
}

/* Pulse: the online dot grows and fades to signal an active service. */
@keyframes pulse-ok {
  0%, 100% { transform: scale(1);   opacity: 1;   }
  50%       { transform: scale(1.5); opacity: 0.5; }
}

.status-dot-ok {
  background: var(--ok-text);
  animation: pulse-ok 2.2s ease-in-out infinite;
}

/* Blink: the degraded dot fades in and out to signal an unstable service. */
@keyframes blink-warn {
  0%, 100% { opacity: 1;   }
  50%       { opacity: 0.2; }
}

.status-dot-warn {
  background: var(--warn-text);
  animation: blink-warn 1s ease-in-out infinite;
}

/* Offline dot: static red — no animation, service is down. */
.status-dot-bad {
  background: var(--bad-text);
}

/* Neutral dot: static muted — used for planned and internal states. */
.status-dot-neutral {
  background: var(--muted);
}

/* -------------------------------------------------------------------------- */
/* Badges                                                                     */
/* -------------------------------------------------------------------------- */

/*
  Badges are rectangular blocks with a coloured border matching the text.
  border: 1px solid currentColor ties the border to the text colour
  without needing per-variant overrides.
*/
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.6rem;
  border-radius: 0;
  border: 1px solid currentColor;
  font-size: 0.75rem;
  font-family: 'Courier New', Courier, monospace;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.badge-live {
  background: var(--ok-bg);
  color: var(--ok-text);
}

.badge-offline {
  background: var(--bad-bg);
  color: var(--bad-text);
}

.badge-degraded {
  background: var(--warn-bg);
  color: var(--warn-text);
}

.badge-planned {
  background: var(--neutral-bg);
  color: var(--neutral-text);
}

.badge-internal {
  background: var(--surface);
  color: var(--muted);
}

/* -------------------------------------------------------------------------- */
/* Buttons                                                                    */
/* -------------------------------------------------------------------------- */

.btn {
  display: inline-block;
  padding: 0.3rem 0.6rem;
  border-radius: 0;
  border: 1px solid var(--border);
  text-decoration: none;
  font-size: 0.75rem;
  font-family: 'Courier New', Courier, monospace;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
}

.btn-auth {
  background: transparent;
  color: var(--warn-text);
  border-color: var(--warn-text);
}

.btn-auth:hover,
.btn-auth:focus-visible {
  background: rgba(245, 213, 138, 0.1);
  outline: none;
}

/* -------------------------------------------------------------------------- */
/* Footer                                                                     */
/* -------------------------------------------------------------------------- */

.footer {
  margin-top: 2.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
  text-align: center;
  color: var(--muted);
  font-size: 0.75rem;
}

.footer-brand {
  margin-bottom: 0.55rem;
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.footer-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
}

.footer-item strong,
.footer-item time {
  color: var(--text);
}

.footer-sep {
  color: var(--muted);
}

/* -------------------------------------------------------------------------- */
/* Network group — full-width card with ping animation                       */
/* -------------------------------------------------------------------------- */

/*
  The network card spans all grid columns so it sits as a wide band below
  the three category cards above it.
*/
.status-group--network {
  grid-column: 1 / -1;
}

/*
  Override status-line to flex so the ping-track can stretch between the
  service name and the badge. Grid layout does not support a fluid middle
  column without a third explicit template.
*/
.status-group--network .status-line {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

.status-group--network .status-line-left {
  flex: 0 1 auto;
  min-width: 0;
}

.status-group--network .status-line-right {
  flex: 0 0 auto;
}

/*
  The ping track is a thin horizontal line that fills the space between the
  service name and the badge. It acts as the travel path for the dot.
*/
.ping-track {
  flex: 1;
  position: relative;
  height: 1px;
  background: rgba(136, 192, 208, 0.12);
  align-self: center;
  overflow: hidden;
  min-width: 2rem;
}

/*
  Traveling dot — a small square that moves left to right along the track,
  simulating a network probe packet. The dot pauses at the far end before
  the next cycle, giving the impression of a real round-trip.
  animation-delay uses a CSS custom property set per-item in portal.js so
  each row starts at a different phase.
*/
@keyframes ping-travel {
  0%   { left: -5px; }
  65%  { left: calc(100% + 5px); }
  100% { left: calc(100% + 5px); }
}

.ping-track::after {
  content: '';
  position: absolute;
  top: -2px;
  left: -5px;
  width: 5px;
  height: 5px;
  background: var(--ok-text);
  animation: ping-travel 2.8s ease-in-out infinite;
  animation-delay: var(--ping-delay, 0s);
}

/* -------------------------------------------------------------------------- */
/* Summary bar                                                                */
/* -------------------------------------------------------------------------- */

/*
  The summary bar sits above the group cards and gives an at-a-glance count
  per status. The left accent border ties it visually to the card style.
*/
.status-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem;
  padding: 0.7rem 1rem;
  margin-bottom: 1.2rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  background: var(--surface);
}

/*
  Each count item uses the same dot-plus-label pattern as status badges
  so the visual language stays consistent across the dashboard.
*/
.summary-count {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  font-family: 'Courier New', Courier, monospace;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.summary-count-online   { color: var(--ok-text); }
.summary-count-degraded { color: var(--warn-text); }
.summary-count-offline  { color: var(--bad-text); }
.summary-count-planned  { color: var(--muted); }
.summary-count-internal { color: var(--muted); }

/* -------------------------------------------------------------------------- */
/* Accessibility                                                              */
/* -------------------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* -------------------------------------------------------------------------- */
/* Responsive adjustments                                                     */
/* -------------------------------------------------------------------------- */

@media (max-width: 720px) {
  .wrap {
    padding: 1.4rem 1rem 2rem;
  }

  .hero {
    padding-bottom: 1.2rem;
  }

  .hero-meta {
    justify-content: center;
  }

  .status-line {
    grid-template-columns: 1fr;
  }

  .status-line-right {
    align-items: flex-start;
  }

  .footer-meta {
    flex-direction: column;
    gap: 0.25rem;
  }

  .footer-sep {
    display: none;
  }
}
