[hidden] { display: none !important; }
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: radial-gradient(ellipse at 50% 50%, #0b2438 0%, #04101a 40%, var(--ground) 78%);
  color: var(--ink);
  font: 400 16px/1.5 var(--font-body);
  overflow: hidden;
}
button, input { font: inherit; color: inherit; }
button:focus-visible, input:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.label { font-family: var(--font-display); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--dim); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* Login */
.login { position: fixed; inset: 0; display: grid; place-content: center; justify-items: center; gap: 12px; padding: 16px; }
.login-orb { width: 220px; height: 220px; }
.login input[type="password"] { width: min(300px, 80vw); padding: 12px 14px; border-radius: 4px; border: 1px solid var(--line); background: rgba(var(--blue-rgb), 0.05); }
.login button { padding: 10px 22px; border-radius: 4px; border: 1px solid rgba(var(--blue-rgb), 0.5); background: rgba(var(--blue-rgb), 0.12); cursor: pointer; font-family: var(--font-display); letter-spacing: 0.12em; text-transform: uppercase; }
.error { color: var(--danger); margin: 0; }

/* Stage: a 16:9 visor. Every position below is in 1280x720 stage units (--u), the same numbers hud.js draws in. */
.app { position: fixed; inset: 0; }
.stage {
  --u: calc(min(100vw, 177.778vh) / 1280);
  position: absolute; left: 50%; top: 50%;
  width: calc(1280 * var(--u)); height: calc(720 * var(--u));
  transform: translate(-50%, -50%);
}
.hud { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.orb { position: absolute; left: calc(416.5 * var(--u)); top: calc(148.5 * var(--u)); width: calc(447 * var(--u)); height: calc(447 * var(--u)); display: block; }
.scan { position: absolute; inset: 0; pointer-events: none; z-index: 10;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.16) 0 1px, transparent 1px 3px), radial-gradient(ellipse at 50% 50%, transparent 58%, rgba(0, 0, 0, 0.72)); }

/* Clock and status */
.clock { position: absolute; left: calc(110 * var(--u)); top: calc(30 * var(--u)); }
.clock-time { font-family: var(--font-number); font-weight: 700; font-size: calc(30 * var(--u)); line-height: 1; font-variant-numeric: tabular-nums; text-shadow: 0 0 calc(8 * var(--u)) rgba(var(--blue-rgb), 0.6); }
.clock-date, .mark { font-family: var(--font-display); font-size: max(10px, calc(11 * var(--u))); letter-spacing: 0.18em; text-transform: uppercase; color: rgba(var(--blue-rgb), 0.8); margin-top: calc(6 * var(--u)); }
.status-block { position: absolute; right: calc(110 * var(--u)); top: calc(44 * var(--u)); text-align: right; }
.status { font-family: var(--font-display); font-size: max(11px, calc(13 * var(--u))); letter-spacing: 0.16em; text-transform: uppercase; color: rgb(var(--blue-rgb)); text-shadow: 0 0 calc(8 * var(--u)) rgba(var(--blue-rgb), 0.7); }
body[data-mode="home"][data-health="nominal"] .status { color: rgb(var(--life-rgb)); text-shadow: 0 0 calc(8 * var(--u)) rgba(var(--life-rgb), 0.7); }
/* Degraded is a warning tone of its own — not the Trading area amber. */
body[data-mode="home"][data-health="degraded"] .status { color: rgb(255, 150, 90); text-shadow: 0 0 calc(8 * var(--u)) rgba(255, 150, 90, 0.7); }
/* Checking or unreachable claims nothing: stays Jarvis blue. */
body[data-health="checking"] .status, body[data-health="unreachable"] .status { color: rgb(var(--blue-rgb)); text-shadow: 0 0 calc(8 * var(--u)) rgba(var(--blue-rgb), 0.7); }
body[data-mode="offline"] .status { color: var(--danger); text-shadow: none; }
.mark { color: rgba(var(--blue-rgb), 0.7); }

/* Right-hand column */
.column { position: absolute; left: calc(920 * var(--u)); top: calc(190 * var(--u)); width: calc(250 * var(--u)); display: grid; gap: calc(52 * var(--u)); transition: opacity 260ms var(--ease-out); }
.column.is-empty { opacity: 0; }
.card-wrap { --area-rgb: var(--blue-rgb); position: relative; height: calc(88 * var(--u)); clip-path: inset(0 0 100% 0); animation: wipe 700ms var(--ease-out) forwards; }
.card-wrap::after { content: ""; position: absolute; left: 0; right: 0; top: 0; height: calc(1.5 * var(--u)); background: rgba(var(--area-rgb), 0.8); box-shadow: 0 0 calc(10 * var(--u)) rgba(var(--area-rgb), 0.9); opacity: 0; animation: scan-edge 700ms var(--ease-out) forwards; animation-delay: inherit; }
@keyframes wipe { to { clip-path: inset(0 0 0 0); } }
@keyframes scan-edge { 0% { top: 0; opacity: 1; } 100% { top: 100%; opacity: 0; } }
/* Notched panels: the shape is clipped, so a box-shadow border would lose its diagonals. The border is
   an ::after ring instead — the outer notch polygon plus the same polygon inset 1px, cut out evenodd
   (0.414px = sqrt(2) - 1, the 1px perpendicular inset of a 45deg edge measured along an axis). */
.card, .ask { --notch: calc(10 * var(--u)); --edge: rgba(var(--area-rgb), 0.5); }
.card::after, .ask::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; background: var(--edge);
  clip-path: polygon(evenodd,
    var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch), var(--notch) 0,
    calc(var(--notch) + 0.414px) 1px, 1px calc(var(--notch) + 0.414px), 1px calc(100% - 1px), calc(100% - var(--notch) - 0.414px) calc(100% - 1px),
    calc(100% - 1px) calc(100% - var(--notch) - 0.414px), calc(100% - 1px) 1px, calc(var(--notch) + 0.414px) 1px);
}
.card {
  position: relative; height: 100%;
  padding: calc(9 * var(--u)) calc(14 * var(--u)) 0 calc(16 * var(--u));
  /* Persistent thin top line in the area colour (spec 4) — stays after the wipe's scan edge fades. */
  background:
    linear-gradient(rgba(var(--area-rgb), 0.7), rgba(var(--area-rgb), 0.7)) top / 100% 1px no-repeat,
    linear-gradient(180deg, rgba(var(--area-rgb), 0.15), rgba(var(--area-rgb), 0.03));
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
}
.card::before { content: ""; position: absolute; left: 0; top: calc(12 * var(--u)); width: calc(3 * var(--u)); height: calc(18 * var(--u)); background: rgba(var(--area-rgb), 0.95); }
.card-title { font-family: var(--font-display); font-size: max(10px, calc(11 * var(--u))); letter-spacing: 0.18em; text-transform: uppercase; color: rgba(var(--area-rgb), 0.9); }
.card-value { font-family: var(--font-number); font-weight: 700; font-size: calc(26 * var(--u)); line-height: 1.15; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 0 calc(6 * var(--u)) rgba(235, 248, 255, 0.5); }
.card-value.is-text { font-size: calc(21 * var(--u)); }
.card-sub { font-size: max(10px, calc(11 * var(--u))); color: rgba(150, 180, 205, 0.85); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Under the ring: exchange, live words, greeting. Kept clear of both the ask console (x 96-396) and the column (x 920+). */
.exchange, .words, .greeting { position: absolute; left: calc(420 * var(--u)); right: calc(420 * var(--u)); text-align: center; }
.exchange { top: calc(648 * var(--u)); opacity: 0; transition: opacity 600ms var(--ease-out); }
.exchange.is-open { opacity: 1; }
.exchange-you { font-family: var(--font-display); font-size: max(11px, calc(13 * var(--u))); color: rgba(150, 180, 205, 0.9); }
.exchange-jarvis { font-family: var(--font-display); font-size: max(13px, calc(17 * var(--u))); line-height: 1.3; color: rgba(235, 248, 255, 0.95); text-shadow: 0 0 calc(4 * var(--u)) rgba(235, 248, 255, 0.4);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
body[data-mode="offline"] .exchange-jarvis { color: var(--danger); }
.words { top: calc(672 * var(--u)); font-weight: 300; font-size: max(14px, calc(18 * var(--u))); }
.words .w { opacity: 0.18; transition: opacity 240ms var(--ease-out); }
.words .w.lit { opacity: 1; }
.greeting { top: calc(672 * var(--u)); font-family: var(--font-display); font-size: max(13px, calc(16 * var(--u))); opacity: 0; letter-spacing: 0.3em; transition: opacity 800ms var(--ease-out), letter-spacing 1200ms var(--ease-out); }
.greeting.is-open { opacity: 1; letter-spacing: 0.08em; }

/* Ask console, bottom-left */
.ask {
  position: absolute; left: calc(96 * var(--u)); top: calc(652 * var(--u)); width: calc(300 * var(--u));
  display: flex; gap: calc(6 * var(--u)); align-items: center; padding: calc(4 * var(--u));
  background: rgba(4, 12, 20, 0.72);
  --notch: calc(8 * var(--u)); --edge: rgba(var(--blue-rgb), 0.3);
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
}
.ask input { flex: 1; min-width: 0; background: transparent; border: 0; padding: calc(4 * var(--u)) calc(6 * var(--u)); font-size: max(12px, calc(13 * var(--u))); }
.ask input:focus-visible { outline: none; }
.ask:focus-within { --edge: rgba(var(--blue-rgb), 0.8); }
.mic, .mute { border: 1px solid rgba(var(--blue-rgb), 0.35); background: rgba(var(--blue-rgb), 0.08); padding: calc(4 * var(--u)) calc(10 * var(--u)); cursor: pointer; font-family: var(--font-display); font-size: max(10px, calc(11 * var(--u))); letter-spacing: 0.12em; text-transform: uppercase; }
.mic[aria-pressed="true"] { background: rgba(var(--blue-rgb), 0.3); border-color: var(--blue); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-delay: 0ms !important; transition-duration: 1ms !important; }
}
