/* ===================================================================
   ProcIntel V2 — APPLICATION SHELL
   Stage 1 of the approved V1 UI/UX redesign.

   The rail, the top bar and the workspace container: the frame every
   screen sits inside. Screen CONTENT is untouched here and is redesigned
   in each screen's own stage, so expect existing page structure inside
   the new shell for now. That is the intended intermediate state.

   RESPONSIVE. Four breakpoints, named in tokens.css and repeated here
   as literals because @media cannot read a custom property:
       640   phone
       900   tablet -- the rail becomes an overlay drawer
      1180   small laptop -- the rail collapses to icons
      1440   full desktop workspace
   =================================================================== */

/* -------------------------------------------------------------------
   PAGE GROUND
   ------------------------------------------------------------------- */
html { background: var(--surface-base); }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--surface-base);
}

/* A single, very restrained atmospheric wash. The mockup's depth comes
   from one soft cool gradient behind the workspace, not from glow on
   individual components. Fixed so it does not travel with scroll, and
   pointer-events:none so it can never intercept a click. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(1200px 620px at 22% -12%, rgba(70, 104, 150, 0.14), transparent 62%),
    radial-gradient(980px 520px at 96% 2%, rgba(201, 169, 97, 0.055), transparent 58%);
}
.app-shell { position: relative; z-index: 1; }

/* Scrollbars, so the shell does not end at a bright system gutter. */
* { scrollbar-width: thin; scrollbar-color: var(--surface-hover) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--surface-hover);
  border: 2px solid transparent;
  background-clip: content-box;
  border-radius: var(--radius-pill);
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--border-strong); background-clip: content-box; }

/* -------------------------------------------------------------------
   THE RAIL

   V1 PREMIUM UX. The rail now carries the brand, so the top
   bar can be a quiet utility layer. Separation is a hairline and gold
   appears only on the ACTIVE item -- a single small bar, never the
   full-height gold edge V1 carried, and never two indicators at once.
   ------------------------------------------------------------------- */
.sidebar {
  width: var(--rail-width);
  background: var(--surface-shell);
  color: var(--text-secondary);
  border-right: 1px solid var(--border-default);
  transition: width var(--dur-base) var(--ease-out);
}
html.sidebar-collapsed .sidebar { width: var(--rail-width-collapsed); }

.sidebar-top {
  height: var(--topbar-height);
  padding: 0 var(--sp-7);
  border-bottom: 1px solid var(--border-subtle);
}
.sidebar-brand { gap: var(--sp-4); }
.sidebar-brand-mark { height: 18px; }
.sidebar-brand-icon { height: 24px; }

.sidebar-nav { padding: var(--sp-6) 0 var(--sp-5); }
.sidebar-group { gap: 1px; margin-bottom: var(--sp-7); }
.sidebar-group-label {
  margin: 0 var(--sp-7) var(--sp-3);
  color: var(--text-muted);
  font-size: var(--fs-label);
  letter-spacing: var(--tracking-label);
}
/* Operator instrumentation is visibly a different place: a hairline
   above the group, so an operator never mistakes a back-office tool for
   part of the subscriber product. */
.sidebar-group-label-ops {
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border-subtle);
  margin-top: calc(var(--sp-3) * -1);
}

.sidebar-link {
  position: relative;
  gap: var(--sp-5);
  margin: 0 var(--sp-4);
  padding: 7px var(--sp-5);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: var(--fs-meta);
  font-weight: var(--fw-medium);
  line-height: 1.3;
  transition: var(--motion-hover);
}
.sidebar-link:hover { background: var(--surface-panel); color: var(--text-primary); }

/* ACTIVE -- a raised surface, primary-weight text, and one small gold
   bar. Legacy style.css also draws an underline (::after) on the active
   item; that is suppressed here so there is exactly one indicator. */
.sidebar-link.is-active {
  background: var(--surface-raised);
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}
.sidebar-link::after { content: none; display: none; }
.sidebar-link.is-active::before {
  content: "";
  position: absolute;
  left: calc(var(--sp-4) * -1);
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  background: var(--accent-primary);
}
.sidebar-link.is-active .sidebar-icon { color: var(--accent-primary); }
.sidebar-icon { width: 16px; height: 16px; color: var(--text-muted); flex: none; }
.sidebar-link:hover .sidebar-icon { color: var(--text-secondary); }
.sidebar-link:focus-visible { outline-offset: -2px; }

.sidebar-link-badge {
  margin-left: auto;
  padding: 1px var(--sp-4);
  border-radius: var(--radius-pill);
  background: var(--wash-accent);
  color: var(--accent-primary);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

.sidebar-bottom { border-top: 1px solid var(--border-subtle); padding: var(--sp-4); }
.sidebar-collapse-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  width: 100%;
  padding: var(--sp-4) var(--sp-5);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--fs-caption);
  cursor: pointer;
  transition: var(--motion-hover);
}
.sidebar-collapse-toggle:hover { background: var(--surface-panel); color: var(--text-primary); }
html.sidebar-collapsed .sidebar-collapse-chevron { transform: rotate(180deg); }
.sidebar-collapse-chevron { width: 15px; height: 15px; transition: transform var(--dur-base) var(--ease-out); }

/* COLLAPSED -- icons only. Each link keeps its title AND an aria-label
   in the markup, so the accessible name survives the hidden text. Group
   labels become hairlines rather than vanishing, so the grouping is
   still legible without words. */
html.sidebar-collapsed .sidebar-link { justify-content: center; padding-left: 0; padding-right: 0; }
html.sidebar-collapsed .sidebar-link-badge { display: none; }
html.sidebar-collapsed .sidebar-collapse-toggle { justify-content: center; }
html.sidebar-collapsed .sidebar-top { justify-content: center; padding: 0; }

/* -------------------------------------------------------------------
   THE TOP BAR

   Reduced from the V1 header's ~100px two-row block to a single 56px
   row. The collection telemetry that used to live here (active
   sources, collection failures, scheduler state) is operator
   instrumentation and Stage 0 already restricted it to operators; the
   shell simply no longer gives it the most valuable strip on the page.
   ------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--surface-shell) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-default);
}
/* A browser without color-mix gets the solid surface, which is correct
   rather than merely acceptable. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .site-header { background: var(--surface-shell); }
}

.header-shell, .header-main {
  min-height: var(--topbar-height);
  padding: 0 var(--page-gutter);
  gap: var(--sp-6);
}
/* The one-line operational metrics. Nowrap, because three stacked words
   inside a 56px bar was the most visibly broken thing in the operator
   shell. They only appear at full desktop width (legacy hides them
   below 1440px, and they are repeated on Collection Health). */
.header-status-detail { white-space: nowrap; gap: var(--sp-3); }
.header-status-metric { color: var(--text-muted); font-size: var(--fs-caption); }
.header-last-collection { color: var(--text-muted); font-size: var(--fs-caption); }
.header-brand-mark { width: 152px; max-width: 38vw; }
.header-tagline {
  color: var(--text-muted);
  font-size: var(--fs-caption);
  letter-spacing: 0.02em;
}

/* The decorative world-map motif is retired from the shell. It was
   nearly invisible, it cost a 46 KB background image on every page, and
   the new ground already carries its own atmosphere. */
.header-map-motif { display: none; }

.header-operations { gap: var(--sp-5); }
.header-status-group { gap: var(--sp-4); }
.header-divider { width: 1px; height: 20px; background: var(--border-default); }

/* -------------------------------------------------------------------
   HEADER SEARCH — V1 Stage 2.2

   Search lives in the shell because the question does not belong to a
   page. Sized to be obviously a text field (not an icon that opens
   one), but bounded so it never competes with the wordmark or pushes
   the access controls off the row -- `min-width: 0` is what actually
   guarantees that, since a flex item defaults to min-width:auto and
   would otherwise refuse to shrink below its placeholder.
   ------------------------------------------------------------------- */
.header-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 260px;
  min-width: 0;
}
.header-search-icon {
  position: absolute;
  left: var(--sp-4);
  display: inline-flex;
  width: 16px; height: 16px;
  color: var(--text-muted);
  pointer-events: none;
}
.header-search-icon svg { width: 100%; height: 100%; }

/* Two classes, deliberately. The global form rule in components.css is
   `input[type="search"]` -- element plus attribute, specificity (0,1,1)
   -- which beat this component's single class and reset the left
   padding to 12px, so the icon sat on top of the placeholder ("earch
   intelligence"). Measured in the browser, not guessed. */
.header-search .header-search-input {
  width: 100%;
  min-width: 0;
  height: 32px;
  padding: 0 42px 0 30px;   /* room for the icon left, the hint right */
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--fs-meta);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.header-search-input::placeholder { color: var(--text-muted); }
.header-search-input:hover { border-color: var(--border-strong); }
.header-search-input:focus {
  outline: 2px solid var(--accent-primary);
  outline-offset: -1px;
  border-color: var(--accent-primary);
  background: var(--surface-raised);
}
.header-search-input::-webkit-search-cancel-button { filter: invert(1) opacity(0.55); }

/* The hint gets out of the way once the field is in use -- at that
   point the reader has plainly found the field and the shortcut is
   just clutter over their own text. */
.header-search-kbd {
  position: absolute;
  right: var(--sp-3);
  padding: 1px var(--sp-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xs);
  background: var(--surface-raised);
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  line-height: 1.5;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.header-search:focus-within .header-search-kbd { opacity: 0; }

.header-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: var(--motion-hover);
}
.header-icon-btn:hover {
  background: var(--surface-raised);
  border-color: var(--border-default);
  color: var(--text-primary);
}
.header-icon-btn svg { width: 17px; height: 17px; }
.header-search-link { display: none; }

.header-access { gap: var(--sp-5); }
.header-user-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
}
.header-user-avatar svg { width: 15px; height: 15px; }
.header-user-label {
  color: var(--text-secondary);
  font-size: var(--fs-meta);
  font-weight: var(--fw-medium);
}
.header-settings-link, .header-admin-login-link, .header-admin-logout-btn {
  color: var(--text-secondary);
  font-size: var(--fs-meta);
  text-decoration: none;
}
.header-settings-link:hover, .header-admin-login-link:hover, .header-admin-logout-btn:hover {
  color: var(--text-primary);
}

.header-help-popover {
  background: var(--surface-hover);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  color: var(--text-secondary);
  font-size: var(--fs-meta);
  padding: var(--sp-6);
}

.preview-banner {
  background: var(--wash-accent);
  border-bottom: 1px solid var(--accent-muted);
  color: var(--accent-primary);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  letter-spacing: 0.02em;
  padding: var(--sp-3) var(--page-gutter);
  text-align: center;
}

/* -------------------------------------------------------------------
   THE WORKSPACE
   ------------------------------------------------------------------- */
.app-main { background: transparent; min-width: 0; }
.content {
  padding: var(--sp-9) var(--page-gutter) var(--sp-12);
  background: transparent;
}
.content-dashboard      { max-width: 1280px; }
.content-table          { max-width: 1600px; }
.content-detail         { max-width: 1100px; }
.content-reading        { max-width: 760px; }
.content-event-workspace{ max-width: 1240px; }

.site-footer {
  padding: var(--sp-8) var(--page-gutter);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-muted);
  font-size: var(--fs-caption);
  background: transparent;
}
.site-footer-links { gap: var(--sp-6); }
.site-footer-links a { color: var(--text-muted); text-decoration: none; }
.site-footer-links a:hover { color: var(--text-secondary); text-decoration: underline; }
.site-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4) var(--sp-8);
}
.site-footer-status { margin: 0; color: var(--text-muted); font-size: var(--fs-caption); }
.site-footer-status-label {
  display: inline-block;
  margin-right: var(--sp-4);
  padding: 1px var(--sp-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xs);
  color: var(--text-secondary);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* -------------------------------------------------------------------
   REPORTS STAY LIGHT.

   The approved strategy is a dark workspace with a lighter editorial
   report surface. Stage 1 does not redesign reports -- it makes sure
   the architecture ALLOWS that difference, by scoping the V2 ground to
   the app shell rather than forcing it globally, and by leaving the
   print stylesheet alone.
   ------------------------------------------------------------------- */
@media print {
  body::before { display: none !important; }
  .site-header, .sidebar, .site-footer { display: none !important; }
}

/* -------------------------------------------------------------------
   RESPONSIVE
   ------------------------------------------------------------------- */

/* >= 900 -- THE RAIL IS A RAIL.

   Legacy style.css turns the sidebar into an off-canvas drawer below
   1024px, while this layer documents 900px as that point. Between the
   two the product followed neither design. The V2 breakpoint is now
   authoritative: from 900px up the sidebar is a persistent rail and the
   brand lives at its top; below 900px it is the drawer and the brand
   returns to the top bar. Overridden by source order, not !important,
   and without editing the legacy file. */
@media (min-width: 900px) {
  .sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    transform: none;
    box-shadow: none;
    width: var(--rail-width);
  }
  html.sidebar-collapsed .sidebar { width: var(--rail-width-collapsed); }
  .sidebar-top { display: flex; height: var(--topbar-height); padding: 0 var(--sp-7); }
  html.sidebar-collapsed .sidebar-top { display: flex; height: var(--topbar-height); padding: 0; }
  .sidebar-brand-wordmark { display: block; }
  .sidebar-brand-icon { display: none; }
  html.sidebar-collapsed .sidebar-brand-wordmark { display: none; }
  html.sidebar-collapsed .sidebar-brand-icon { display: block; }
  .sidebar-close { display: none; }
  .sidebar-bottom { display: block; }
  .nav-toggle { display: none; }
  html.sidebar-collapsed .sidebar-link-label { width: 0; opacity: 0; }
  html.sidebar-collapsed .sidebar-group-label {
    height: 0; margin: var(--sp-3) var(--sp-6); padding: 0; opacity: 1;
    font-size: 0; border-top: 1px solid var(--border-default);
  }
  html.sidebar-collapsed .sidebar-link { justify-content: center; padding: 8px 0; margin: 0 var(--sp-4); }

  /* The top bar is a utility layer: search on the left, context and
     account on the right. Exactly one wordmark is visible at any width
     -- here it is the rail's. */
  .header-brand { display: none; }
  .header-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: center;
    height: var(--topbar-height);
    min-height: var(--topbar-height);
    padding: 0 var(--page-gutter);
  }
  .header-operations {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-width: 0;
    gap: var(--sp-5);
  }
  .header-operations > .header-search { order: -1; margin-right: auto; flex: 0 1 420px; }
  /* Spacing, not stacked hairlines. The dividers sat beside elements
     that are conditionally absent (an empty status group, the phone-only
     search link), which left two bars side by side. One quiet rule now
     separates the account block, which is always present. */
  .header-operations > .header-divider { display: none; }
  .header-access { padding-left: var(--sp-6); border-left: 1px solid var(--border-default); }
  /* The operator's collection verdict stays in the bar; the three
     supporting metrics do not. They repeat Collection Health, and a
     one-line strip of them collided with the search field at 1440px.
     The chip's tooltip still carries the full description. */
  .site-header .header-status-detail { display: none; }
}

/* >= 1440 -- full desktop. Slightly more generous gutters. */
@media (min-width: 1440px) {
  :root { --page-gutter: var(--sp-10); }
}

/* < 1180 -- small laptop. The rail collapses to icons by default so the
   workspace keeps its width. A reader who wants labels can still expand
   it, and the choice persists. */
@media (max-width: 1179.98px) {
  :root { --page-gutter: var(--sp-7); }
  .header-tagline { display: none; }
  .header-brand-mark { width: 132px; }
  .header-search { flex-basis: 280px; }
}

/* < 900 -- tablet. The rail becomes the existing off-canvas drawer;
   that behaviour already works, so this restyles rather than rebuilds
   it. */
@media (max-width: 899.98px) {
  :root { --page-gutter: var(--sp-6); }
  .sidebar {
    position: fixed;
    z-index: 60;
    box-shadow: var(--shadow-lg);
    border-right: 1px solid var(--border-strong);
  }
  .sidebar-overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(4, 6, 10, 0.6);
    backdrop-filter: blur(2px);
  }
  .content { padding-top: var(--sp-7); }
  /* Touch targets. */
  .sidebar-link { padding: var(--sp-5) var(--sp-5); }
  .nav-toggle, .sidebar-close { min-width: 40px; min-height: 40px; }
  /* No modifier key on a touch device, so the hint is removed rather
     than advertising a shortcut that cannot be pressed. */
  .header-search { flex-basis: 168px; }
  .header-search-kbd { display: none; }
  .header-search-input { padding-right: var(--sp-4); }
}

/* < 640 -- phone. Monitoring and reading, not a shrunken terminal.
   Wide tables scroll inside their own container so the PAGE never
   scrolls sideways. */
@media (max-width: 639.98px) {
  :root {
    --page-gutter: var(--sp-5);
    --panel-padding: var(--sp-6);
    --card-padding: var(--sp-5);
  }
  .content { padding-top: var(--sp-6); padding-bottom: var(--sp-10); }
  h1, .page-title { font-size: 24px; }
  .header-brand-mark { width: 112px; }
  .header-user-label { display: none; }
  /* At phone width the header row cannot hold a usable text field AND
     the access controls. Search keeps its full page at /search, reached
     from the rail, so the shell control is dropped rather than shrunk
     to something too small to type into. */
  .header-search { display: none; }
  .header-search-link { display: inline-flex; }
  /* ONE ROW. Legacy lets this header wrap onto a second line, which cost
     ~60px of a 844px screen on every page. Brand left, then only what a
     phone reader needs: search, account and sign-out. Help and the
     decorative avatar are dropped here -- neither is an action. */
  .header-main {
    flex-wrap: nowrap;
    min-height: var(--topbar-height);
    padding: 0 var(--page-gutter);
    gap: var(--sp-4);
  }
  .header-operations { margin-left: auto; gap: var(--sp-4); min-width: 0; }
  .header-operations > .header-divider,
  .header-actions,
  .header-user-avatar { display: none; }
  .header-access { gap: var(--sp-5); }
  .nav-toggle { min-width: 36px; min-height: 36px; }

  .events-table-scroll,
  .table-scroll,
  .items-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .filter-bar { padding: var(--sp-5); gap: var(--sp-5); }
  .filter-group { width: 100%; }
}

/* Belt and braces: nothing may make the document itself scroll
   sideways at any width. */
html, body { max-width: 100%; overflow-x: hidden; }

/* The shell's single primary action: account creation, for an
   anonymous visitor. Deliberately the only gold fill in the chrome. */
.header-cta {
  display: inline-flex;
  align-items: center;
  padding: var(--sp-3) var(--sp-6);
  border-radius: var(--radius-sm);
  background: var(--accent-primary);
  color: var(--accent-on);
  font-size: var(--fs-meta);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  white-space: nowrap;
  transition: var(--motion-hover);
}
.header-cta:hover { background: var(--accent-hover); color: var(--accent-on); }

/* Anonymous phone header: brand, search, "Sign in" and the gold
   "Create account" measured 417px on a 390px screen. The CTA keeps its
   label -- it is the one action the chrome offers a visitor -- and gives
   up padding instead. */
@media (max-width: 639.98px) {
  /* Fluid rather than a fifth breakpoint: the four agreed breakpoints
     are a guarded decision, and the last few pixels on the narrowest
     phones (360px) are recovered by scaling with the viewport. */
  .header-main { gap: var(--sp-3); }
  .header-operations { gap: var(--sp-3); }
  .header-access { gap: clamp(var(--sp-2), 1.6vw, var(--sp-4)); }
  .header-brand-mark { width: clamp(84px, 25.6vw, 100px); }
  .header-cta {
    padding: var(--sp-3) clamp(var(--sp-3), 2vw, var(--sp-4));
    font-size: clamp(var(--fs-caption), 3.3vw, var(--fs-meta));
  }
}
