/* ══════════════════════════════════════════════════════════════════
   Reset, type, and the application shell.
   ══════════════════════════════════════════════════════════════════ */

[hidden] { display: none !important; }

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* ── Type ──
   Licensed brand faces lead each stack and resolve from the machine when
   installed; the open fallback behind them means nothing ever drops to a
   system default. Density is deliberate: this is a tool someone stares at
   all day, not a page they land on once. */
:root {
  --font-display: 'Franie', 'Franie Variable', 'Outfit', ui-sans-serif, system-ui, sans-serif;
  --font-sans: 'Aptos', 'Aptos Display', 'Outfit', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'Geist Mono', 'Geist Mono Variable', ui-monospace, 'Cascadia Mono', Consolas, monospace;
}

body {
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Applied globally so it cannot be forgotten on a one-off heading. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-display);
  line-height: 1.1;
  letter-spacing: -0.01em;
  font-weight: 600;
}

p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; padding: 0; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }

/* Every readout, every hours figure, every percentage. Non-tabular digits
   make a dashboard twitch as values change. */
.tabular { font-variant-numeric: tabular-nums; }

/* The title shape: a short mono accent line above a display-face heading. */
.kicker {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: hsl(var(--signal-ok-ink));
}

/* Pixel-specific scale, not a t-shirt ramp. */
.t-label   { font-size: 11px; color: hsl(var(--muted-foreground)); }
.t-ui      { font-size: 12.5px; }
.t-title   { font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.t-section { font-family: var(--font-display); font-size: 17px; font-weight: 600; }
.t-page    { font-family: var(--font-display); font-size: 19px; font-weight: 600; }

/* Big numbers are font-light. Scale carries the emphasis; weight would shout. */
.t-readout {
  font-family: var(--font-display);
  font-size: 46px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.t-readout-lg { font-size: 52px; }
.t-readout-sm { font-size: 30px; font-weight: 300; font-family: var(--font-display); line-height: 1; font-variant-numeric: tabular-nums; }

.t-muted { color: hsl(var(--muted-foreground)); }
.t-mono { font-family: var(--font-mono); font-size: 11px; }
.t-prose { max-width: 68ch; color: hsl(var(--muted-foreground)); }

/* ── Focus ── visible everywhere, one shape. */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));
  border-radius: var(--r-sm);
}

::selection { background: hsl(var(--primary) / 0.28); color: hsl(var(--foreground)); }

/* Thin, but never hidden on a scrollable region. */
* { scrollbar-width: thin; scrollbar-color: hsl(var(--foreground) / 0.2) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: hsl(var(--foreground) / 0.18); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
.no-scrollbar { scrollbar-width: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

/* ══════════════════════════════════════════════════════════════════
   App shell — one scroll container.

   h-screen + overflow-hidden on the frame, overflow-y-auto on <main>.
   The nav never scrolls away and there is never a double scrollbar.
   ══════════════════════════════════════════════════════════════════ */

.shell { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }

/* Reserve the scrollbar gutter so the content column does not shift sideways
   when a short page becomes a long one.

   Named as a container so page layouts respond to the width they actually
   get rather than the viewport's. With a rail beside them those two numbers
   differ by ~206px, which is enough to push a four-column dashboard row into
   two on a laptop if the breakpoints keep measuring the wrong thing. */
.shell-main {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  scrollbar-gutter: stable;
  container: content / inline-size;
}

.shell-inner {
  width: 100%;
  max-width: 1480px;
  margin: 0 auto;
  padding: 14px 16px 44px;
}
@container content (min-width: 640px) { .shell-inner { padding-left: 28px; padding-right: 28px; } }

/* ── Top nav ──
   Categories only, on the centre line of the page. Three columns with equal
   outer tracks put them there no matter how wide the brand or the actions
   grow — a flex row with auto margins would drift as either side changed.
   The brand still starts where the menu below it does. */
.topnav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid hsl(var(--border) / 0.08);
  background: hsl(var(--background));
  flex: none;
}
.topnav > * { min-width: 0; }
/* Symmetric, or the centre track is not the centre of the page. */
@media (min-width: 640px) { .topnav { padding-left: 22px; padding-right: 22px; } }

.brand { display: flex; align-items: center; gap: 10px; justify-self: start; }
.brand-mark {
  width: 28px; height: 28px;
  border-radius: var(--r-sm);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 14px; font-weight: 700;
  flex: none;
}
.brand-name { font-family: var(--font-display); font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.brand-tenant { font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); }

/* ── Tier one: categories ──
   Twelve labelled items in a single row need a ~1950px viewport. A MacBook is
   1440–1512px, so that row never fitted and degraded into a scrolling strip.
   The category row is three pills — it fits with room to spare at any laptop
   width, and the pages live in the rail below. */
.nav-cats {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: var(--r-md);
  background: hsl(var(--foreground) / 0.05);
  justify-self: center;
}

.nav-cat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: calc(var(--r-md) - 4px);
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
  transition: color 0.14s var(--ease), background 0.14s var(--ease);
}
.nav-cat:hover { color: hsl(var(--foreground)); }
.nav-cat[data-active] {
  background: hsl(var(--input));
  color: hsl(var(--foreground));
  font-weight: 500;
  box-shadow: 0 1px 2px hsl(var(--brand-black) / 0.14);
}

/* ── Tier two: the pages inside the active category ──
   A separate menu, not an extension of the top bar: its own floating cards
   held at the vertical middle of the page, touching no other edge. Vertical
   space is not scarce the way horizontal space is, so the page list stops
   competing with the content for width, and a category can grow past five
   pages without the layout caring. */
.shell-body { display: flex; flex: 1; min-height: 0; align-items: center; }

.sidenav {
  width: 222px;
  flex: none;
  align-self: center;
  max-height: 100%;
  overflow-y: auto;
  padding: 16px;
}
/* Left edge lines up with the brand mark in the bar above. */
@media (min-width: 640px) { .sidenav { padding-left: 22px; } }

/* The main column still owns the full height — only the menu is centred. */
.shell-main { align-self: stretch; }

.sidenav-inner { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }

/* The category name is its own container, separate from the options below it. */
.sidenav-label {
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  padding: 5px 11px;
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: var(--r-md);
  background: hsl(var(--card));
  user-select: none;
}

/* The options sit in a card of their own, on the same surface as every other
   card on the page so the menu reads as part of the same material. */
.sidenav-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: var(--r-lg);
  background: hsl(var(--card));
}

/* A grouping inside a category — Copilot's pages within Areas. Quieter than
   the category label above it, so the hierarchy reads at a glance. */
.sidenav-divider {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 9px 2px 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  user-select: none;
}
.sidenav-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: hsl(var(--border) / 0.14);
}
/* Laid down as a strip the divider is a separator, not a heading. */
@media (max-width: 900px) {
  .sidenav-divider { margin: 0 2px; }
  .sidenav-divider::after { display: none; }
}

/* Shared by the sidebar, the audit button, and the theme toggle. */
.nav-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border-radius: calc(var(--r-md) - 4px);
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
  transition: color 0.14s var(--ease), background 0.14s var(--ease);
}
.nav-item:hover { color: hsl(var(--foreground)); }
.nav-item[data-active] {
  background: hsl(var(--input));
  color: hsl(var(--foreground));
  font-weight: 500;
  box-shadow: 0 1px 2px hsl(var(--brand-black) / 0.14);
}
.nav-item-ic { display: grid; place-items: center; flex: none; opacity: 0.8; }
.nav-item-ic svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.nav-item[data-active] .nav-item-ic { opacity: 1; }

/* In the sidebar an item is a full-width row, not a pill: the whole width is
   the hit target, and the count sits hard against the right edge. */
.sidenav .nav-item {
  position: relative;
  width: 100%;
  padding: 7px 10px 7px 12px;
  border-radius: var(--r-sm);
}
.sidenav .nav-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sidenav .nav-item:hover { background: hsl(var(--foreground) / 0.035); }

/* The current page carries a marker rather than a colour: in this system a
   colour always means a status, and "you are here" is not one. */
.sidenav .nav-item[data-active] {
  box-shadow: none;
  background: hsl(var(--foreground) / 0.06);
}
.sidenav .nav-item[data-active]::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 99px;
  background: hsl(var(--foreground) / 0.55);
}
/* Laid down as a strip the marker moves to the bottom edge. */
@media (max-width: 900px) {
  .sidenav .nav-item[data-active]::before { top: auto; left: 8px; right: 8px; bottom: 0; width: auto; height: 2px; }
}

/* Count of open findings for that area — the reason to go there. */
.nav-count {
  font-family: var(--font-mono);
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 99px;
  font-variant-numeric: tabular-nums;
  background: hsl(var(--signal-watch) / 0.15);
  color: hsl(var(--signal-watch-ink));
}
.nav-count[data-tone='risk'] { background: hsl(var(--signal-risk) / 0.15); color: hsl(var(--signal-risk-ink)); }

.topnav-end { display: flex; align-items: center; gap: 8px; justify-self: end; }

/* ── Responsive ──
   The sidebar is the first thing to change shape: below 900px it lies down
   into a horizontal strip under the top bar, which is the one place a
   scrolling row is fine because a category holds at most five pages. Labels
   are never dropped — unlabelled icons were what made the old nav unusable. */
@media (max-width: 900px) {
  .shell-body { flex-direction: column; align-items: stretch; }
  .sidenav {
    width: 100%;
    align-self: stretch;
    max-height: none;
    padding: 12px 16px 0;
    overflow-x: auto;
    overflow-y: hidden;
  }
  .sidenav-inner { flex-direction: row; align-items: center; gap: 8px; }
  .sidenav-items { flex-direction: row; gap: 2px; padding: 6px; }
  .sidenav .nav-item { width: auto; }
}

@media (max-width: 700px) {
  .brand-text { display: none; }
  .topnav { gap: 10px; padding: 8px 14px; }
  .nav-cat { padding: 6px 10px; }
  .sidenav { padding-left: 14px; padding-right: 14px; }
  .sidenav-label { display: none; }
  #collectedAt { display: none; }
}

/* The categories can only sit on the exact centre line while both outer
   tracks are at least as wide as the wider of the brand and the actions.
   Measured, per band:

     above 1100px   needs 1065px   (search button shows its label and ⌘K)
     700–1100px     needs  831px   (label hidden, wordmark and clock still on)
     below 700px    needs  705px   (wordmark and clock gone too)

   840px clears every band, so below it the categories take a line of their
   own, where centring means filling the line rather than sitting in the
   middle of it. On the shared row they are always exactly centred, never
   approximately. */
@media (max-width: 840px) {
  .topnav { grid-template-columns: 1fr auto; row-gap: 8px; }
  .brand { grid-area: 1 / 1; }
  .topnav-end { grid-area: 1 / 2; }
  .nav-cats { grid-area: 2 / 1 / 3 / -1; justify-self: stretch; }
  .nav-cat { flex: 1; justify-content: center; }
  #runBtn .nav-item-label { display: none; }
}

/* ── Page header: kicker + title + subtitle + right-aligned actions ── */
.page-header {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 22px;
}
@container content (min-width: 620px) {
  .page-header { flex-direction: row; align-items: flex-end; justify-content: space-between; }
}
.page-header-text { min-width: 0; }
.page-header-sub { margin-top: 6px; color: hsl(var(--muted-foreground)); max-width: 74ch; }
.page-header-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ── Generic layout helpers ── */
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.section { display: flex; flex-direction: column; gap: 14px; margin-top: 26px; }
.section-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.section-head-fill { flex: 1; }

/* ══════════════════════════════════════════════════════════════════
   Reduced motion — one global block.
   Because the finished state is always the base style (never the
   keyframe's end), everything still displays correctly here.
   ══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
