:root {
  --purple-deep: #1a0e2e;
  --purple-mid: #2d1854;
  --purple-vivid: #6b2fa0;
  --purple-light: #9b59c6;
  --purple-glow: rgba(155, 89, 198, 0.25);
  --glass: rgba(26, 14, 46, 0.55);
  --glass-heavy: rgba(26, 14, 46, 0.75);
  --glass-light: rgba(255, 255, 255, 0.06);
  --white: #ffffff;
  --text: #f0eaf5;
  --muted: rgba(240, 234, 245, 0.6);
  --border: rgba(155, 89, 198, 0.25);
  --border-light: rgba(255, 255, 255, 0.12);
  --success: #34d399;
  --danger: #fb7185;
  --radius: 12px;
  --radius-sm: 8px;
}

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

html, body {
  height: 100%;
  width: 100%;
}

body {
  font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--text);
  background-color: var(--purple-deep);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a { color: var(--text); }

/* ── Main content area ── */
.page-body {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  position: relative;
}

/* ── Card ── */
.card {
  background: var(--glass);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 40px 44px;
  width: 100%;
  max-width: 520px;
  box-shadow:
    0 24px 80px rgba(0, 0, 0, 0.35),
    0 0 0 1px rgba(155, 89, 198, 0.08) inset,
    0 1px 0 rgba(255, 255, 255, 0.05) inset;
}

.card-logo {
  display: block;
  height: 36px;
  margin: 0 auto 28px;
  opacity: 0.95;
}

.card h1 {
  font-size: 26px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}

.card .subtitle {
  text-align: center;
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 32px;
  line-height: 1.65;
}

/* ── Status indicator ── */
.status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--glass-light);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  font-size: 13px;
  margin-bottom: 22px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--success);
  flex-shrink: 0;
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.4);
}

.status.error .status-dot {
  background: var(--danger);
  box-shadow: 0 0 8px rgba(251, 113, 133, 0.4);
}

/* ── Buttons ── */
.actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 22px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 14px 20px;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: all 0.25s ease;
}

.button-primary {
  background: linear-gradient(135deg, var(--purple-vivid), var(--purple-light));
  color: var(--white);
  box-shadow: 0 4px 20px var(--purple-glow);
}

.button-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 30px rgba(155, 89, 198, 0.4);
}

.button-primary:disabled {
  opacity: 0.6;
  cursor: wait;
  transform: none;
}

.button-secondary {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  border: 1px solid var(--border-light);
}

.button-secondary:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: var(--border);
}

/* ── Support panel ── */
.support-panel {
  position: absolute;
  left: calc(50% + 280px);
  top: 50%;
  transform: translateY(-50%) translateX(20px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 260px;
  opacity: 0;
  pointer-events: none;
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.35s ease;
}

.support-panel.open {
  transform: translateY(-50%) translateX(0);
  opacity: 1;
  pointer-events: auto;
}

.support-info {
  background: rgba(107, 47, 160, 0.15);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}

.support-info-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  display: block;
  margin-bottom: 8px;
}

.support-info ul {
  margin: 0;
  padding-left: 16px;
}

.support-info li {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.6;
}

.support-info-hours {
  display: block;
  font-size: 10px;
  color: var(--muted);
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  text-align: center;
}

.support-item {
  background: var(--glass-heavy);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.2s;
}

.support-item:hover {
  border-color: var(--purple-light);
}

.support-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.support-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.support-item a {
  color: var(--purple-light);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
}

.support-item a:hover {
  color: var(--white);
}

.support-hours {
  font-size: 11px;
  color: var(--muted);
}

.support-detail {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.5;
  margin-top: 4px;
}

/* ── Debug cog ── */
.debug-cog {
  position: fixed;
  bottom: 18px;
  left: 18px;
  width: 32px;
  height: 32px;
  padding: 6px;
  background: none;
  border: none;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
  z-index: 10;
}

.debug-cog svg {
  width: 100%;
  height: 100%;
  stroke: var(--muted);
  transition: stroke 0.2s;
}

.debug-cog:hover svg {
  stroke: var(--purple-light);
}

.debug-cog:hover {
  transform: rotate(45deg);
}

.support-panel.open ~ .debug-cog {
  opacity: 1;
  pointer-events: auto;
}

/* ── Debug panel ── */
.debug-panel {
  margin-top: 20px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.debug-panel summary {
  padding: 10px 14px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  background: var(--glass-light);
  color: var(--muted);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.debug-panel #log {
  padding: 12px 14px;
  background: rgba(0, 0, 0, 0.35);
  font-family: 'SF Mono', Consolas, monospace;
  font-size: 11px;
  max-height: 200px;
  overflow: auto;
  white-space: pre-wrap;
  color: var(--muted);
}

/* ── Spinner ── */
.spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-top-color: var(--white);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  display: none;
}

.button.loading .spinner { display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Responsive ── */
@media (max-width: 860px) {
  .support-panel {
    position: static;
    transform: translateX(20px);
    width: 100%;
    max-width: 520px;
    flex-direction: row;
    margin-top: 20px;
  }

  .support-panel.open {
    transform: translateX(0);
  }

  .support-panel .support-item {
    flex: 1;
  }

  .page-body {
    flex-direction: column;
  }
}

@media (max-width: 600px) {
  .card {
    padding: 28px 22px;
  }

  .card h1 { font-size: 22px; }

  .support-panel {
    flex-direction: column;
  }
}

/* ── Portal additions: signed-in identity, app picker, streaming view ── */
.identity {
  text-align: center;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 22px;
}
.identity strong { color: var(--text); font-weight: 600; }

.app-picker {
  display: flex;
  gap: 8px;
  margin-bottom: 22px;
}
.app-picker label {
  flex: 1;
  position: relative;
  cursor: pointer;
}
.app-picker input { position: absolute; opacity: 0; pointer-events: none; }
.app-picker span {
  display: block;
  text-align: center;
  padding: 12px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-light);
  background: var(--glass-light);
  font-size: 14px;
  transition: all 0.2s ease;
}
.app-picker input:checked + span {
  border-color: var(--purple-light);
  background: rgba(155, 89, 198, 0.18);
  box-shadow: 0 0 0 1px var(--purple-light) inset;
}

/* Full-screen streaming view */
#viewStreaming {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  background: var(--purple-deep);
}
.stream-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 16px;
  background: var(--glass-heavy);
  border-bottom: 1px solid var(--border);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
.stream-bar img { height: 24px; opacity: 0.95; }
.stream-bar .button {
  width: auto;
  padding: 9px 18px;
  font-size: 14px;
}
#appstreamContainer { flex: 1; position: relative; background: #000; }
#appstreamContainer iframe { border: 0; width: 100%; height: 100%; }

/* Minimisable stream bar — toggle tab on the right.
   Both tabs are position:fixed with a very high z-index so they render ABOVE the AppStream
   iframe (an absolutely-positioned tab hanging over the iframe gets painted over by it). */
.stream-bar { position: relative; padding-right: 84px; }   /* clear space for the toggle tab */
.stream-bar-actions { display: flex; align-items: center; gap: 10px; }

.stream-tab {
  position: fixed;
  top: 0;
  right: 16px;
  z-index: 2147483000;         /* above the embedded stream iframe */
  width: 54px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: var(--glass-heavy);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  transition: background 0.2s ease;
}
.stream-tab:hover { background: var(--purple-vivid); }

/* Collapse tab (▴) shows while the bar is open; expand handle (▾) shows while collapsed.
   When collapsed, the bar is display:none, which also hides its child collapse tab. */
#streamBarHandle { display: none; }
#viewStreaming.bar-collapsed .stream-bar { display: none; }
#viewStreaming.bar-collapsed #streamBarHandle { display: inline-flex; }

/* Compact, clearly-labelled size selector (not front-and-centre) */
.size-select { margin-bottom: 22px; }
.size-label {
  display: block;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.app-picker { margin: 0 auto; max-width: 340px; }
.app-picker span { padding: 8px 8px; font-size: 13px; }

/* Size as a compact, centred segmented control (replaces the three separate boxes) */
#viewLaunch .status { margin-bottom: 16px; }
#viewLaunch .actions { margin-top: 16px; }
.size-select { margin-top: 18px; margin-bottom: 6px; text-align: center; }

/* Stack of picker rows: one row (single instance) or instance + size rows.
   Rows centre and never overflow the card - segments wrap as a last resort. */
.picker-stack { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.picker-stack .app-picker { max-width: 100%; flex-wrap: wrap; justify-content: center; }

.app-picker {
  display: inline-flex;
  gap: 0;
  margin: 0 auto;
  max-width: none;
  width: auto;
  border: 1px solid var(--border-light);
  border-radius: 999px;
  overflow: hidden;
  background: var(--glass-light);
}
.app-picker label { flex: 0 0 auto; }
.app-picker span {
  display: block;
  border: none;
  border-radius: 0;
  padding: 7px 22px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  transition: background 0.2s ease, color 0.2s ease;
}
.app-picker label + label span { border-left: 1px solid var(--border-light); }
.app-picker input:checked + span {
  background: var(--purple-vivid);
  color: #fff;
  box-shadow: none;
}

/* ── Custom in-portal login ── */
.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-form .subtitle { margin-bottom: 6px; }
.auth-input {
  width: 100%;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-light);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 15px;
}
.auth-input::placeholder { color: var(--muted); }
.auth-input:focus { outline: none; border-color: var(--purple-light); }
.auth-msg { font-size: 13px; color: var(--muted); }
.auth-msg.error { color: var(--danger); }
.linkbtn {
  background: none; border: none;
  color: var(--purple-light); font-size: 13px; font-weight: 600;
  cursor: pointer; padding: 4px; align-self: center;
}
.linkbtn:hover { color: var(--white); text-decoration: underline; }

/* ── Two-step verification (TOTP) setup ── */
.mfa-qr {
  align-self: center;
  width: 176px; height: 176px;
  padding: 8px;
  background: #ffffff;               /* QR must be dark-on-light to scan reliably */
  border-radius: var(--radius-sm);
}
.mfa-qr:empty { display: none; }     /* hide the white box if the QR couldn't render */
.mfa-qr img, .mfa-qr canvas { display: block; width: 100%; height: 100%; }
.mfa-manual { font-size: 12px; color: var(--muted); margin: 4px 0 0; text-align: center; }
.mfa-secret {
  align-self: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px; letter-spacing: 2px; font-weight: 600;
  color: var(--text);
  padding: 8px 12px;
  background: var(--glass-light);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  user-select: all;                  /* one tap/click selects the whole key to copy */
  word-break: break-all; text-align: center;
}
.mfa-secret:empty { display: none; }

/* ── Settings gear + panel (holds the display-size control) ── */
.card { position: relative; }
.card-gear {
  position: absolute; top: 16px; right: 16px;
  width: 34px; height: 34px; padding: 7px;
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  color: var(--muted); cursor: pointer;
  transition: color .2s, border-color .2s, background .2s;
}
.card-gear svg { width: 100%; height: 100%; }
.card-gear:hover { color: var(--purple-light); border-color: var(--border); background: var(--glass-light); }
.settings-panel {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  background: var(--glass-light);
  padding: 16px;
  margin-bottom: 22px;
  text-align: center;
}
.settings-title { display: block; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }
.settings-hint { font-size: 11px; color: var(--muted); margin-top: 10px; }

/* Purple radial gradient background (replaces the PNG). A customer can still override this
   by setting "backgroundImage" in their portal-config; blank = use this gradient. */
body {
  background:
    radial-gradient(1100px 620px at 50% -12%, rgba(123, 60, 184, 0.55), transparent 62%),
    radial-gradient(820px 520px at 88% 118%, rgba(155, 89, 198, 0.18), transparent 55%),
    linear-gradient(160deg, #241041 0%, #1a0e2e 55%, #100718 100%);
  background-attachment: fixed;
  background-repeat: no-repeat;
}

/* Separate, subtler "Tip:" line under the status box */
.status-tip {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
  text-align: left;
  margin: -12px 4px 20px;
  padding-left: 22px;
  position: relative;
}
.status-tip::before {
  content: '💡';
  position: absolute;
  left: 0;
  top: 0;
}

/* Branded "Connecting…" overlay — covers the stream area (and the tabs) during every launch/retry
   so users never see the black frame or AppStream's own error/404 page. */
.stream-connecting {
  position: fixed;
  inset: 0;
  z-index: 2147483600;          /* above the stream iframe and the pull-tabs */
  display: none;                /* toggled to flex by JS */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  text-align: center;
  padding: 32px;
  background:
    radial-gradient(1100px 620px at 50% -12%, rgba(123, 60, 184, 0.55), transparent 62%),
    linear-gradient(160deg, #241041 0%, #1a0e2e 55%, #100718 100%);
  color: var(--text);
}
.stream-connecting .card-logo { height: 40px; margin: 0 0 4px; }
.stream-connecting #connText { font-size: 15px; color: var(--text); max-width: 460px; line-height: 1.6; }
.conn-spinner { width: 30px; height: 30px; border-width: 3px; }

/* Slim the stream bar — it's just a small logo + Disconnect now, so keep it minimal.
   (Still fully collapsible via the pull-tab for 100% stream height.) */
.stream-bar { padding: 5px 14px; }
.stream-bar img { height: 17px; }
.stream-bar .button { width: auto; padding: 5px 14px; font-size: 13px; }

/* Refine the collapse/expand pull-tab: smaller, subtler, and keep the slim bar clear of it */
.stream-tab {
  width: 40px;
  height: 17px;
  right: 12px;
  font-size: 11px;
  border-radius: 0 0 9px 9px;
  color: var(--muted);
  opacity: 0.9;
}
.stream-tab:hover { opacity: 1; color: var(--white); }
.stream-bar { padding-right: 62px; }   /* clear space so Disconnect never sits under the tab */

/* ── Brand controls overlaid on AppStream's own toolbar (fixed, above the iframe) ──
   Lets us drop our separate bar and reclaim the height. NB: AWS's toolbar is white and can
   auto-hide/reflow — these float regardless, so the logo sits in a dark chip for contrast. */
.ec-brand-logo {
  position: fixed; top: 8px; left: 16px; z-index: 2147483000;
  height: 26px; padding: 6px 11px; box-sizing: content-box;
  border-radius: 9px; background: var(--purple-deep);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.ec-brand-disconnect {
  position: fixed; top: 9px; right: 16px; z-index: 2147483000;
  padding: 8px 18px; border: none; border-radius: 9px;
  background: linear-gradient(135deg, var(--purple-vivid), var(--purple-light));
  color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
  box-shadow: 0 2px 12px rgba(107, 47, 160, 0.55);
  transition: filter 0.2s ease, transform 0.2s ease;
}
.ec-brand-disconnect:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* ── Animated "Connecting…" splash ── */
.stream-connecting { animation: ecFade 0.4s ease; }
@keyframes ecFade { from { opacity: 0; } to { opacity: 1; } }

.conn-logo { position: relative; display: flex; align-items: center; justify-content: center; }
.conn-logo img { height: 46px; position: relative; z-index: 1; animation: ecBreathe 3s ease-in-out infinite; }
.conn-logo::before {
  content: ''; position: absolute; width: 210px; height: 210px; border-radius: 50%;
  background: radial-gradient(circle, rgba(155, 89, 198, 0.5), transparent 60%);
  animation: ecPulse 2.4s ease-in-out infinite;
}
@keyframes ecPulse { 0%, 100% { transform: scale(0.85); opacity: 0.35; } 50% { transform: scale(1.25); opacity: 0.75; } }
@keyframes ecBreathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }

.conn-bar {
  width: 220px; height: 3px; border-radius: 3px;
  background: rgba(255, 255, 255, 0.08); overflow: hidden; position: relative;
}
.conn-bar span {
  position: absolute; top: 0; left: -45%; width: 45%; height: 100%;
  background: linear-gradient(90deg, transparent, var(--purple-light), transparent);
  animation: ecSlide 1.3s ease-in-out infinite;
}
@keyframes ecSlide { 0% { left: -45%; } 100% { left: 100%; } }

/* Beautify the brand overlay on AWS's white toolbar: dark (inverted) logo — no chip — to match
   AWS's own dark-grey icons, and a cleaner Disconnect button. (Overrides the earlier rules.) */
.ec-brand-logo {
  top: 13px; left: 22px;
  height: 24px; padding: 0;
  background: none; box-shadow: none;
  filter: invert(1); opacity: 0.8;   /* white logo -> dark, reads cleanly on the white bar */
}
.ec-brand-disconnect {
  top: 11px; right: 20px;
  padding: 8px 20px; border-radius: 8px;
  background: var(--purple-vivid);
  box-shadow: 0 2px 8px rgba(107, 47, 160, 0.3);
}
.ec-brand-disconnect:hover {
  background: var(--purple-light);
  box-shadow: 0 4px 14px rgba(155, 89, 198, 0.45);
  transform: translateY(-1px);
  filter: none;
}

/* Sit the brand overlay in line with AWS's toolbar icons: each element is a fixed, full-bar-
   height flex band that vertically centres its content. (Tweak the 50px if it sits off the row.) */
.ec-brand { position: fixed; top: 0; height: 50px; z-index: 2147483000; display: flex; align-items: center; }
.ec-brand-left { left: 22px; }
.ec-brand-right { right: 20px; }
.ec-brand-left img { height: 26px; filter: invert(1); opacity: 0.8; }
.ec-brand-right .ec-brand-disconnect {
  position: static;
  padding: 8px 20px; border: none; border-radius: 8px;
  background: var(--purple-vivid); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
  box-shadow: 0 2px 8px rgba(107, 47, 160, 0.3);
  transition: background .2s, box-shadow .2s, transform .2s;
}
.ec-brand-right .ec-brand-disconnect:hover { background: var(--purple-light); box-shadow: 0 4px 14px rgba(155, 89, 198, 0.45); transform: translateY(-1px); }

/* AWS's toolbar is shorter than 50px — shrink the band so our items centre on the row, not low. */
.ec-brand { height: 42px; }

/* Slightly darker purple for the Disconnect button */
.ec-brand-right .ec-brand-disconnect { background: #56238a; }
.ec-brand-right .ec-brand-disconnect:hover { background: var(--purple-vivid); }

/* Logo must contrast whichever way AWS's toolbar renders (it follows the OS colour scheme):
   light toolbar -> dark logo (invert the white asset); dark toolbar -> white logo (no invert). */
@media (prefers-color-scheme: dark) {
  .ec-brand-left img { filter: none; opacity: 0.95; }
}

/* (Reverted the purple badge — back to the clean inverted logo. It follows OS dark mode via the
   media query above; the AppStream-Preferences dark toggle can't be detected from our CSS, so in
   that specific case the logo won't show — accepted trade-off for the cleaner look.) */

/* ============================================================================
   Admin telemetry dashboard (admin.html)
   Same glass theme as the portal, but a wide multi-panel layout instead of the
   centred card. Chart colours live in admin.js (validated data-viz palette).
   ============================================================================ */
.admin-body {
  min-height: 100vh;
  background-color: var(--purple-deep);
  color: var(--text);
}
.admin-shell {
  max-width: 1180px;
  /* width:100% matters: body is a column flex container and the auto margins stop
     the shell stretching, so without it the shell shrink-wraps its CONTENT - the
     page loaded ~700px wide then blew out to 1180px as charts/tables arrived. */
  width: 100%;
  margin: 0 auto;
  padding: 24px 20px 56px;
}

.admin-head {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.admin-logo { height: 34px; width: auto; }
.admin-head-text { flex: 1 1 260px; }
.admin-head-text h1 { font-size: 1.35rem; margin: 0; letter-spacing: -0.01em; }
.admin-sub { margin: 2px 0 0; font-size: 0.8rem; color: var(--muted); }
.admin-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.admin-auto { font-size: 0.78rem; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.admin-btn-sm { padding: 8px 14px; font-size: 0.8rem; width: auto; text-decoration: none; }
.admin-btn-xs { padding: 5px 10px; font-size: 0.72rem; width: auto; }

.admin-panel {
  background: var(--glass);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
  margin-bottom: 18px;
  backdrop-filter: blur(14px);
}
.admin-denied { text-align: center; max-width: 520px; margin: 60px auto; }
.admin-denied h2 { margin: 0 0 8px; font-size: 1.1rem; }
.admin-denied p { color: var(--muted); font-size: 0.88rem; margin: 0 0 18px; }

.panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.panel-head h2 { font-size: 0.95rem; margin: 0; font-weight: 600; }
.panel-note { font-size: 0.75rem; color: var(--muted); }
.panel-foot { font-size: 0.75rem; color: var(--muted); margin: 12px 0 0; line-height: 1.5; }

/* KPI row — hero figure first, then supporting tiles */
.kpi-row {
  display: grid; gap: 12px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  /* Reserve the populated height so the page doesn't jump when the KPIs render
     (hero card: label 14 + 2.3rem value + hint + 2x14 padding ~ 108px). */
  min-height: 108px;
}
.kpi {
  background: var(--glass); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px;
}
.kpi-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.kpi-value { font-size: 1.6rem; font-weight: 600; margin-top: 4px; letter-spacing: -0.02em; }
.kpi-hero .kpi-value { font-size: 2.3rem; }
.kpi-hint { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }

/* Charts */
.chart-grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.chart-figure { margin: 0; }
.chart-figure figcaption { display: flex; flex-direction: column; margin-bottom: 6px; }
.chart-title { font-size: 0.82rem; font-weight: 600; }
.chart-sub { font-size: 0.72rem; color: var(--muted); }
/* Reserve the FINAL chart height up front: charts render their SVG at 200-210px
   (admin.js frame()), and data arrives in two waves (fleet metrics fast, Cost
   Explorer slow) - a smaller placeholder made the whole page expand twice. */
.chart-host { position: relative; min-height: 210px; }
.chart-svg { display: block; overflow: visible; }
.chart-axis { fill: rgba(240, 234, 245, 0.6); font-size: 10px; font-family: inherit; }
.chart-empty {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 160px; padding: 12px; font-size: 0.78rem; color: var(--muted);
  border: 1px dashed var(--border); border-radius: var(--radius-sm);
}
.chart-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.74rem; color: var(--muted); }
.legend-item i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

.chart-tip {
  position: absolute; top: 4px; transform: translateX(-50%);
  background: var(--glass-heavy); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 6px 9px; pointer-events: none;
  font-size: 0.72rem; white-space: nowrap; z-index: 3; backdrop-filter: blur(8px);
}
.tip-head { display: block; color: var(--muted); margin-bottom: 3px; }
.tip-row { display: flex; align-items: center; gap: 6px; }
.tip-row i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

/* Horizontal bars (cost by service) */
.hbars { display: flex; flex-direction: column; gap: 8px; }
.hbar-row { display: grid; grid-template-columns: minmax(150px, 2fr) minmax(80px, 2fr) auto; gap: 10px; align-items: center; }
.hbar-name {
  font-size: 0.74rem; color: var(--muted); line-height: 1.3;
  /* Wrap rather than truncate — "Amazon WorkSpaces Applications" must stay identifiable. */
  overflow-wrap: anywhere;
}
.hbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 4px; height: 14px; overflow: hidden; }
.hbar-fill { height: 100%; border-radius: 4px; }
.hbar-value { font-size: 0.74rem; font-variant-numeric: tabular-nums; text-align: right; }

/* Time-range control */
.range-row { display: flex; gap: 4px; }
.range-btn {
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--border-light);
  color: var(--muted); border-radius: var(--radius-sm); padding: 4px 10px;
  font: inherit; font-size: 0.72rem; cursor: pointer;
}
.range-btn:hover { background: rgba(255, 255, 255, 0.1); color: var(--text); }
.range-btn-on { background: rgba(107, 47, 160, 0.35); border-color: var(--purple-light); color: var(--white); }

/* Tables */
.table-wrap { overflow-x: auto; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.table-caption { text-align: left; font-size: 0.75rem; color: var(--muted); padding: 14px 0 6px; }
.admin-table th {
  text-align: left; font-weight: 600; font-size: 0.7rem; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
.admin-table td { padding: 9px 10px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.admin-table .col-user { font-weight: 500; }
.admin-table .col-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.72rem; color: var(--muted); }
.admin-table .col-action { text-align: right; }
.table-empty { color: var(--muted); text-align: center; padding: 18px 10px; }

/* Status pill — colour plus a text label, never colour alone */
.pill {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 0.68rem; text-transform: capitalize; border: 1px solid transparent;
}
.pill-good { background: rgba(52, 211, 153, 0.15); border-color: rgba(52, 211, 153, 0.4); color: #6ee7b7; }
.pill-warn { background: rgba(251, 113, 133, 0.15); border-color: rgba(251, 113, 133, 0.4); color: #fda4af; }

/* Toast */
.admin-toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: var(--glass-heavy); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 11px 18px; font-size: 0.8rem;
  z-index: 50; backdrop-filter: blur(10px); box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
}
.admin-toast-bad { border-color: rgba(251, 113, 133, 0.5); }

/* Admin link on the launch card */
.admin-link { font-size: 0.75rem; }

@media (max-width: 640px) {
  .admin-shell { padding: 16px 12px 40px; }
  .kpi-hero .kpi-value { font-size: 1.9rem; }
  .hbar-row { grid-template-columns: minmax(70px, 1fr) 2fr auto; }
}

/* Fleet boot scripts (escape hatch) */
.hatch-intro { font-size: 0.78rem; color: var(--muted); margin: 0 0 10px; }
.hatch-pre {
  margin: 10px 0 0; padding: 12px; max-height: 260px; overflow: auto;
  background: rgba(0, 0, 0, 0.35); border: 1px solid var(--border-light);
  border-radius: var(--radius-sm); font-size: 0.72rem; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre-wrap; word-break: break-word;
}

/* Right-sizing stat strip */
.rs-stats {
  display: grid; gap: 10px; margin-bottom: 16px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  /* Same jump-prevention as .kpi-row: reserve the populated stat-card height. */
  min-height: 78px;
}
.rs-stat {
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border-light);
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.rs-stat-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.rs-stat-value { font-size: 1.3rem; font-weight: 600; margin-top: 2px; }
.rs-stat-hint { font-size: 0.68rem; color: var(--muted); }

/* Service-hours editor */
.sched-form { display: flex; flex-direction: column; gap: 14px; }
.sched-toggle { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text); }
.sched-row { display: flex; gap: 14px; flex-wrap: wrap; }
.sched-field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 170px; min-width: 150px; }
.sched-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.sched-hint { font-size: 0.68rem; color: var(--muted); line-height: 1.35; }
.sched-input { width: 100%; margin: 0; padding: 8px 10px; font-size: 0.85rem; }
.sched-input[readonly] { opacity: 0.7; cursor: default; }
.sched-days { border: none; padding: 0; margin: 0; }
.day-picker { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.day-chip {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--border-light);
  border-radius: var(--radius-sm); padding: 5px 10px; font-size: 0.75rem;
}
.day-chip:has(input:checked) { background: rgba(107, 47, 160, 0.35); border-color: var(--purple-light); color: var(--white); }
.sched-actions { display: flex; gap: 10px; flex-wrap: wrap; }
