/* ==========================================================================
   GVS.Components - status and error pages.
   --------------------------------------------------------------------------
   Consumed as _content/GVS.Components/gvs-status.css. Pairs with
   GvsStatusPage; promoted here from four identical per-app copies.
   --------------------------------------------------------------------------
   From the Claude Design kit's gvs-status.css, with one deliberate change: the
   kit ships its own palette on :root, keyed to prefers-color-scheme. That is
   right for the standalone pages, which render when no application is running.
   It is wrong inside the app, where the user picks light or dark themselves and
   the shell applies it as data-theme - an OS-keyed palette would render a dark
   404 inside a light app.

   So the kit's :root palette is dropped and every token points at the app's own
   --gvs-* equivalent, which already handles both themes. One palette, not two.

   The standalone pages keep the kit's literal values: nginx's 502 page is fully
   self-contained, and the sign-in pages use the authority layout's own styles.
   ========================================================================== */

/* gvs-status.css — GVS status and error pages.
   Plain CSS. No framework, no build step, no web font, no JavaScript.
   Colours come from the app's --gvs-* tokens (see the note above); the kit's
   literal values are kept only in the standalone pages that render with no app.
   Light and dark follow the app's own data-theme, not the operating system.

   Montserrat is named first and used where it happens to be installed; it is
   never downloaded. Everything falls back to the system UI font.

   Two framings, set on the block:
     .gs.gs-standalone  centred on an empty page — user not signed in, or app not running
     .gs.gs-inshell     dropped into the content area of a working app

   The kit's :root[data-scheme] review hook is not carried across. */






/* ---------- preview shells (delete when lifting the markup) --------------- */
.gs-preview { margin: 0; background: var(--gvs-bg); font-family: inherit; -webkit-text-size-adjust: 100%; }
.gs-preview.standalone { min-height: 100vh; display: grid; place-items: center; padding: 32px 20px; }
.gs-preview.inshell { padding: 40px clamp(20px, 5vw, 56px) 64px; }

/* ---------- the block ----------------------------------------------------- */
.gs { font-family: inherit; color: var(--gvs-fg); line-height: 1.55; }
.gs *, .gs *::before, .gs *::after { box-sizing: border-box; }
.gs.gs-inshell { max-width: 640px; }
/* Centres a standalone card. The design kit did this with a class on <body>, which an app does
   not have — without it the card sits in the top-left of whatever layout it lands in. Height is
   capped rather than 100vh because these render inside a layout that already has its own top
   offset, and 100vh would push the card below the fold. */
/* In-shell the wrapper must not exist as far as layout is concerned: display:contents removes the
   box while keeping the children in the parent's flow, so a flex or grid page root treats the
   status section as its own direct child exactly as before. */
.gs-wrap-none { display: contents; }

.gs-standalone-wrap {
  box-sizing: border-box;
  min-height: min(100vh, 78vh);
  display: grid;
  place-items: center;
  padding: 32px 20px;
}

.gs.gs-standalone {
  width: min(560px, 100%); background: var(--gvs-surface); border: 1px solid var(--gvs-border);
  border-radius: 16px; box-shadow: var(--gvs-elev-2); padding: 40px;
}
@media (max-width: 480px) { .gs.gs-standalone { padding: 28px 22px; border-radius: 14px; } }

/* brand mark — typographic, so nothing has to load */
.gs-brand {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 13px; background: var(--gvs-primary);
  color: #fff; font-weight: 800; font-size: 16px; letter-spacing: .02em; margin-bottom: 22px;
}
.gs-standalone .gs-brand { margin-bottom: 26px; }

.gs-eyebrow {
  margin: 0 0 10px; font-size: 11.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gvs-fg-3);
}
.gs-eyebrow.bad { color: var(--gvs-danger-500); }
.gs-eyebrow.warn { color: var(--gvs-warning-500); }
.gs-eyebrow.info { color: var(--gvs-info-500); }
.gs-eyebrow.ok { color: var(--gvs-success-500); }

.gs-h1 {
  margin: 0 0 12px; font-size: 27px; font-weight: 800; letter-spacing: -.02em;
  line-height: 1.2; color: var(--gvs-fg); text-wrap: pretty;
}
@media (max-width: 480px) { .gs-h1 { font-size: 23px; } }
.gs-lead { margin: 0; font-size: 16px; color: var(--gvs-fg-2); max-width: 46ch; text-wrap: pretty; }
.gs-lead + .gs-lead { margin-top: 10px; }

/* a quotable reference, or the licence / role that's missing */
.gs-detail {
  margin: 24px 0 0; padding: 16px 18px; background: var(--gvs-bg);
  border: 1px solid var(--gvs-border); border-radius: 10px;
}
.gs-detail dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; }
/* Nothing inside .gs-detail uses --s-fg-3: that grey is tuned against the page
   background, and this panel is --s-sunken. Labels and note both take fg-2. */
.gs-detail dt { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--gvs-fg-2); }
.gs-detail dd { margin: 0; font-size: 14.5px; color: var(--gvs-fg); }
.gs-detail dd.ref { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.5px; word-break: break-all; user-select: all; }
/* --s-fg-3 is for uppercase labels only. Sentences use --s-fg-2: several of
   these notes carry the one instruction the user needs, so they can't be the
   faintest text on the page. */
.gs-detail p { margin: 12px 0 0; font-size: 13px; color: var(--gvs-fg-2); }
@media (max-width: 420px) { .gs-detail dl { grid-template-columns: 1fr; gap: 2px; } .gs-detail dd { margin-bottom: 8px; } }

/* what still works / what won't — offline */
.gs-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 26px; }
@media (max-width: 560px) { .gs-cols { grid-template-columns: 1fr; gap: 14px; } }
.gs-col { border: 1px solid var(--gvs-border); border-radius: 10px; padding: 16px 18px; background: var(--gvs-surface); }
.gs-col h2 { margin: 0 0 10px; font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--gvs-fg-3); }
.gs-col.ok h2 { color: var(--gvs-success-500); }
.gs-col.no h2 { color: var(--gvs-warning-500); }
.gs-col ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.gs-col li { font-size: 14.5px; color: var(--gvs-fg-2); padding-left: 16px; position: relative; }
.gs-col li::before { content: ""; position: absolute; left: 0; top: .55em; width: 6px; height: 6px; border-radius: 50%; background: var(--gvs-border-strong); }
.gs-col.ok li::before { background: var(--gvs-success-500); }
.gs-col.no li::before { background: var(--gvs-warning-500); }

/* ---------- actions ------------------------------------------------------- */
.gs-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.gs-standalone .gs-actions { margin-top: 26px; }
.gs-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 0 20px; border-radius: 8px; border: 1px solid var(--gvs-border-strong);
  background: var(--gvs-surface); color: var(--gvs-fg); font: inherit; font-size: 15px; font-weight: 600;
  text-decoration: none; cursor: pointer; transition: background .12s, border-color .12s, color .12s;
}
.gs-btn:hover { border-color: var(--gvs-fg-3); }
.gs-btn:focus-visible { outline: 3px solid color-mix(in srgb, var(--gvs-primary) 40%, transparent); outline-offset: 2px; }
/* --gvs-fg-on-primary, NOT --gvs-on-primary. The short name does not exist, so the declaration
   was invalid at computed-value time and `color` silently fell back to inheriting the page text:
   black on teal in light mode, where white was intended. An undefined custom property fails this
   quietly - no console error, no fallback, just the wrong colour. */
.gs-btn.primary { background: var(--gvs-primary); border-color: var(--gvs-primary); color: var(--gvs-fg-on-primary); }
.gs-btn.primary:hover { background: var(--gvs-primary-hover); border-color: var(--gvs-primary-hover); }
.gs-btn.wide { width: 100%; }
@media (max-width: 420px) { .gs-actions { flex-direction: column; } .gs-btn { width: 100%; } }

.gs-note { margin: 22px 0 0; font-size: 14px; color: var(--gvs-fg-2); max-width: 52ch; text-wrap: pretty; }
.gs-note a { color: var(--gvs-primary); }
.gs-note a:hover { color: var(--gvs-primary-hover); }
.gs-hr { height: 1px; border: 0; background: var(--gvs-border); margin: 26px 0 0; }

/* ---------- sign-in chrome (design 6 sits on /Account/Login's page) ------- */
.gs-signin { text-align: center; }
.gs-signin .gs-brand { margin-left: auto; margin-right: auto; display: flex; }
.gs-signin .gs-lead { margin-left: auto; margin-right: auto; }
.gs-signin .gs-detail { text-align: left; }
.gs-signin .gs-actions { justify-content: center; }
.gs-signin .gs-product { margin: 0 0 4px; font-size: 22px; font-weight: 800; letter-spacing: -.02em; }
.gs-legal { margin: 22px 0 0; font-size: 13.5px; color: var(--gvs-fg-2); }
.gs-legal a { color: var(--gvs-primary); }

/* ==========================================================================
   Offline notice (GvsOfflineNotice)
   --------------------------------------------------------------------------
   Sits above a product's content while it has no connection. Not a page: these
   applications keep working offline, so replacing the view would remove the very
   thing the notice says still works.

   Its own palette rather than the status tones: this is a persistent piece of
   chrome, not a page, and it has to read as informational at a glance without
   competing with whatever the user is actually doing.
   ========================================================================== */

.gs-offline {
  margin: 0 0 18px;
  background: var(--gvs-surface);
  border: 1px solid var(--gvs-border);
  border-left: 3px solid var(--gvs-warning-500);
  border-radius: var(--gvs-radius-lg, 12px);
  overflow: hidden;
}

.gs-offline-head {
  display: flex;
  align-items: center;
  /* Explicit, because a host stylesheet's button reset can otherwise centre the row. */
  justify-content: flex-start;
  gap: 10px;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: 0;
  font: inherit;
  color: var(--gvs-fg);
  text-align: left;
  cursor: pointer;
}

.gs-offline-head:hover { background: var(--gvs-bg); }

.gs-offline-head:focus-visible {
  outline: 3px solid var(--gvs-primary);
  outline-offset: -3px;
}

/* A steady dot, not a pulse: something blinking in the corner of a ward screen for the
   length of a wifi outage is a distraction, not information. */
.gs-offline-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gvs-warning-500);
}

.gs-offline-title { font-weight: 700; font-size: 14.5px; }

.gs-offline-summary {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--gvs-fg-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gs-offline-chev { flex: none; color: var(--gvs-fg-3); font-size: 13px; }

.gs-offline-body {
  padding: 0 16px 16px;
  border-top: 1px solid var(--gvs-border);
  padding-top: 14px;
}

.gs-offline-lead {
  margin: 0 0 14px;
  font-size: 14px;
  color: var(--gvs-fg-2);
  max-width: 70ch;
}

/* .gs-cols carries a 26px top margin for the standalone page, where it follows a lead
   paragraph with room around it. Inside the notice the lead is already spaced. */
.gs-offline .gs-cols { margin-top: 0; gap: 14px; }
.gs-offline .gs-col { padding: 12px 14px; }
.gs-offline .gs-col li { font-size: 13.5px; }

/* One column below 560px: two lists of short items side by side stop being scannable long
   before the viewport runs out of room. */
@media (max-width: 560px) {
  .gs-offline .gs-cols { grid-template-columns: 1fr; }
  .gs-offline-summary { display: none; }
}


/* ==========================================================================
   Status bar (#blazor-error-ui, #snackbar)
   --------------------------------------------------------------------------
   Two intents, one bar: something has gone wrong, and a new version is ready.

   Lives here rather than in each app's own stylesheet because all four link this
   file, and the framework's default — a lightyellow strip pinned
   "color-scheme: light only", so it stayed yellow in dark mode — was identical
   in all of them.

   Its own dark palette rather than the --gvs-* tokens: the crash bar has to look
   right with whatever is left of a broken page, which is also why it reads the
   same in light and dark. Class names are the framework's; Blazor looks for
   .reload and .dismiss.
   ========================================================================== */

#blazor-error-ui,
#snackbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2147483000;
  box-sizing: border-box;
  display: none;
  align-items: center;
  gap: 14px;
  padding: 13px clamp(14px, 4vw, 24px);
  background: #0A1A2E;
  color: #fff;
  font-size: 14.5px;
  line-height: 1.45;
  border-top: 3px solid #D7263D;
  box-shadow: 0 -6px 24px rgba(10, 26, 46, .28);
  text-align: left;
}

/* The update bar is not a fault, so it does not get the danger edge. */
#snackbar { border-top-color: #1FA094; cursor: pointer; }

/* Blazor sets display:block inline when it shows the bar, and the app's own script adds
   .show to the snackbar; the flex layout has to win over both. */
#blazor-error-ui[style*="display: block"],
#blazor-error-ui[style*="display:block"],
#snackbar.show {
  display: flex !important;
}

#blazor-error-ui .gvs-bar-text,
#snackbar .gvs-bar-text { flex: 1; min-width: 0; }

#blazor-error-ui .gvs-bar-text b,
#snackbar .gvs-bar-text b { font-weight: 700; }

#blazor-error-ui .gvs-bar-text span,
#snackbar .gvs-bar-text span {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, .7);
}

#blazor-error-ui .reload,
#snackbar .act {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 16px;
  border-radius: 8px;
  background: #fff;
  color: #0A1A2E;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background .12s;
}

#blazor-error-ui .reload:hover,
#snackbar .act:hover { background: #E6ECF2; }

#blazor-error-ui .dismiss {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 8px;
  cursor: pointer;
  color: rgba(255, 255, 255, .65);
  font-size: 20px;
  line-height: 1;
  transition: background .12s, color .12s;
}

#blazor-error-ui .dismiss:hover { background: rgba(255, 255, 255, .12); color: #fff; }

#blazor-error-ui .reload:focus-visible,
#blazor-error-ui .dismiss:focus-visible,
#snackbar .act:focus-visible {
  outline: 3px solid rgba(255, 255, 255, .5);
  outline-offset: 2px;
}
