/* The dashboard. Layout only - colours, type and motion live in fluent.css.

   The window is a navigation rail plus one scrolling column, the shape
   Windows' own utilities use. Only the column scrolls, so the rail and the
   page heading never move, and "what is on my camera right now" is always the
   first thing on screen. */

body {
  background: var(--solid-base);
  overflow: hidden;
}

.shell {
  display: flex;
  height: 100%;
}

/* --- navigation rail --- */
.rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
  width: 62px;
  padding: 10px 0 8px;
  gap: 2px;
  background: var(--solid-secondary);
  border-right: 1px solid var(--divider);
}

.rail-brand {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-bottom: 10px;
  border-radius: var(--radius-card);
  background: var(--accent-tint);
}

.rail-brand svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: round;
}

.rail-gap {
  flex: 1;
}

.rail-item {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 2px;
  width: 54px;
  padding: 7px 2px 6px;
  font: inherit;
  font-size: 10px;
  line-height: 13px;
  color: var(--text-secondary);
  background: none;
  border: none;
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: background var(--fast) var(--ease-out),
    color var(--fast) var(--ease-out);
}

.rail-item svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rail-item:hover {
  background: var(--control-hover);
  color: var(--text);
}

.rail-item:active {
  background: var(--control-pressed);
}

.rail-item.on {
  color: var(--accent);
  background: var(--accent-tint);
}

/* Fluent's selection indicator: a short accent bar down the leading edge. */
.rail-item.on::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 50%;
  width: 3px;
  height: 18px;
  margin-top: -9px;
  border-radius: 999px;
  background: var(--accent);
}

/* --- the one scrolling column --- */
.content {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  /* Reserve the track so nothing shifts sideways the moment a list grows
     past the window. */
  scrollbar-gutter: stable;
}

.page {
  display: none;
  flex-direction: column;
  gap: 18px;
  padding: 16px 16px 18px 20px;
  min-height: 100%;
  animation: page-in var(--normal) var(--ease-out) both;
}

.page.on {
  display: flex;
}

@keyframes page-in {
  from {
    opacity: 0;
    transform: translateY(5px);
  }
}

.page-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.page-head h1 {
  flex: 1;
  min-width: 0;
}

/* --- hero status --- */
.hero {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  border-radius: var(--radius-card);
  border: 1px solid var(--stroke);
  background: var(--card);
  box-shadow: var(--shadow-card);
  transition: border-color var(--normal) var(--ease-out),
    background var(--normal) var(--ease-out);
}

.hero-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--text-secondary);
  background: var(--control);
  transition: color var(--normal) var(--ease-out),
    background var(--normal) var(--ease-out);
}

.hero-icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.hero-text {
  min-width: 0;
}

.hero-text p + p {
  margin-top: 2px;
}

/* Something is actually looking through the camera. This is the one place the
   app raises its voice, so it still means something when it does. */
.hero[data-state="live"] {
  border-color: color-mix(in srgb, var(--critical) 45%, transparent);
  background: var(--critical-tint);
}

.hero[data-state="live"] .hero-icon {
  color: var(--critical);
  background: color-mix(in srgb, var(--critical) 16%, transparent);
}

.hero[data-state="live"] #hero-title {
  color: var(--critical);
}

/* Open but not streaming: worth knowing, not worth alarm. */
.hero[data-state="open"] .hero-icon {
  color: var(--accent);
  background: var(--accent-tint);
}

/* The history summary is a fact, never an alarm. */
.hero-quiet .hero-icon {
  color: var(--accent);
  background: var(--accent-tint);
}

.hero[hidden] {
  display: none;
}

/* --- problem banner --- */
.banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  font-size: 13px;
  line-height: 18px;
  color: var(--text);
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, var(--caution) 40%, transparent);
  background: color-mix(in srgb, var(--caution) 10%, transparent);
}

.banner[hidden] {
  display: none;
}

.banner svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  fill: none;
  stroke: var(--caution);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- groups --- */
.group[hidden] {
  display: none;
}

.group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.counter {
  min-width: 20px;
  padding: 0 6px;
  font-size: 11px;
  line-height: 18px;
  font-weight: 600;
  text-align: center;
  color: var(--text-secondary);
  background: var(--control);
  border-radius: 999px;
}

.counter[hidden] {
  display: none;
}

.group-note {
  margin: -4px 0 8px;
}

.list {
  list-style: none;
  border-radius: var(--radius-card);
  border: 1px solid var(--stroke);
  background: var(--card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.list:empty {
  display: none;
}

.empty {
  padding: 14px 16px;
  border-radius: var(--radius-card);
  border: 1px solid var(--stroke);
  background: var(--card);
}

.empty[hidden] {
  display: none;
}

/* --- rows --- */
.row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 10px 14px;
  animation: row-in var(--slow) var(--ease-out) both;
}

.row + .row {
  border-top: 1px solid var(--divider);
}

@keyframes row-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

.row-text {
  flex: 1;
  min-width: 0;
}

.row-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
}

.row-title .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row-sub {
  display: block;
  margin-top: 1px;
  font-size: 12px;
  line-height: 16px;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A path elided to one line is still recognisable; a sentence is not. */
.row-sub.wrap {
  white-space: normal;
  overflow: visible;
}

/* Something observed that the reader should weigh for themselves. Never
   folded away with the rest of the detail: an app wearing someone else's name
   has to be visible without anyone thinking to look for it. */
.row-sub.alarm {
  color: var(--critical);
}

.row .btn {
  flex: none;
}

.row.is-muted .avatar,
.row.is-muted .row-title .name {
  opacity: 0.6;
}

/* --- an expandable watcher row ---
   Collapsed it answers "who, and for how long". The executable, the PID, the
   camera and the publisher are one click away, because five lines per app
   turns three apps into a scrolling window. */
.row-main {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  background: none;
  border: none;
  border-radius: var(--radius-control);
  cursor: pointer;
}

.row-more {
  display: none;
}

.row-main[aria-expanded="true"] .row-more {
  display: block;
  animation: fold-out var(--normal) var(--ease-out) both;
}

@keyframes fold-out {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
}

.chev {
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 2px;
  border-right: 1.5px solid var(--text-tertiary);
  border-bottom: 1.5px solid var(--text-tertiary);
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--normal) var(--ease-out);
}

.row-main[aria-expanded="true"] .chev {
  transform: translateY(2px) rotate(-135deg);
}

.row-main:hover .chev {
  border-color: var(--text);
}

/* --- history --- */
.day + .day {
  margin-top: 16px;
}

.day-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}

.day-total {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-tertiary);
}

/* A session that is still running, so the log and the dashboard agree. */
.row.is-open .avatar {
  box-shadow: inset 0 0 0 1px var(--critical);
}

/* --- toggle switch: Fluent's ToggleSwitch, at the size a row wants ---
   The checkbox stays in the DOM and keeps its own focus and keyboard
   behaviour; only its painting is borrowed by the track beside it. */
.switch {
  position: relative;
  display: inline-flex;
  flex: none;
  width: 40px;
  height: 20px;
}

.switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.switch .track {
  pointer-events: none;
  width: 100%;
  height: 100%;
  border-radius: 999px;
  border: 1px solid var(--text-secondary);
  background: var(--control);
  transition: background var(--fast) var(--ease-out),
    border-color var(--fast) var(--ease-out);
}

.switch .track::before {
  content: "";
  position: absolute;
  top: 5px;
  left: 5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--text-secondary);
  transition: left var(--fast) var(--ease-out),
    width var(--fast) var(--ease-out), height var(--fast) var(--ease-out),
    top var(--fast) var(--ease-out), background var(--fast) var(--ease-out);
}

.switch input:hover + .track {
  background: var(--control-hover);
}

.switch input:checked + .track {
  background: var(--accent);
  border-color: transparent;
}

.switch input:checked + .track::before {
  top: 4px;
  left: 22px;
  width: 12px;
  height: 12px;
  background: var(--on-accent);
}

.switch input:disabled {
  cursor: default;
}

.switch input:disabled + .track,
.switch input:disabled + .track::before {
  opacity: 0.4;
}

.switch input:focus-visible + .track {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* --- dialog: Fluent's ContentDialog, on the platform's own <dialog> --- */
.dialog {
  width: min(330px, calc(100% - 40px));
  /* fluent.css zeroes every margin, which takes with it the `auto` the
     browser uses to centre a modal dialog. */
  margin: auto;
  padding: 20px 22px 18px;
  color: var(--text);
  background: var(--solid-base);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--radius-overlay);
  box-shadow: var(--shadow-flyout);
}

.dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

.dialog[open] {
  animation: dialog-in var(--normal) var(--ease-out) both;
}

@keyframes dialog-in {
  from {
    opacity: 0;
    transform: scale(0.97);
  }
}

.dialog p {
  margin-top: 8px;
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* --- footer --- */
.alert-page { padding: 32px clamp(20px, 4vw, 64px) 28px; }
.alert-layout { width: 100%; max-width: 860px; margin: 0 auto; }
.alert-summary { padding: 0 0 26px; }
#alert-title { max-width: 760px; font-size: clamp(23px, 2.7vw, 34px); line-height: 1.22; font-weight: 600; letter-spacing: -.025em; margin: 8px 0 0; overflow-wrap: anywhere; }
/* This heading receives programmatic focus, but is not an input or control. */
#alert-title:focus { outline: none; }
.alert-meta { display: flex; flex-wrap: wrap; gap: 16px 36px; }
.alert-meta > span { display: grid; gap: 5px; }
.alert-meta-label { display: block; color: var(--text-secondary); font-size: 12px; font-weight: 400; }
.alert-meta strong { font-size: 13px; font-weight: 500; }
.alert-evidence { padding: 22px 24px 0; background: var(--card); border: 1px solid var(--stroke-strong); border-radius: 14px; }
.alert-section-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; justify-content: space-between; }
.alert-layout h2 { font-size: 15px; line-height: 22px; font-weight: 600; }
.alert-signature { padding: 4px 9px; border-radius: 6px; background: var(--layer); color: var(--text-secondary); font-size: 11px; line-height: 16px; }
.alert-signature[data-tone="verified"] { color: var(--success); background: color-mix(in srgb, var(--success) 10%, transparent); }
.alert-signature[data-tone="caution"] { color: var(--caution); background: color-mix(in srgb, var(--caution) 8%, transparent); }
.alert-publisher { display: flex; gap: 14px; align-items: flex-start; margin: 24px 0 18px; }
.alert-shield { display: grid; place-items: center; flex-shrink: 0; width: 42px; height: 44px; border-radius: 12px; color: var(--text-secondary); background: var(--layer); }
.alert-shield svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.alert-publisher[data-tone="verified"] .alert-shield { color: var(--success); background: color-mix(in srgb, var(--success) 10%, transparent); }
.alert-publisher:not([data-tone="verified"]) .alert-shield svg path + path { display: none; }
.alert-publisher strong { display: block; margin: 3px 0 5px; font-size: 17px; line-height: 24px; font-weight: 600; overflow-wrap: anywhere; }
.alert-publisher p { color: var(--text-secondary); font-size: 13px; line-height: 20px; }
.alert-evidence-note { color: var(--text-secondary); font-size: 12px; line-height: 19px; margin-bottom: 20px; }
.alert-warnings { padding: 14px 16px; margin: 16px 0; background: color-mix(in srgb, var(--caution) 7%, transparent); border-left: 2px solid var(--caution); border-radius: 4px; }
.alert-warnings h3 { font-size: 13px; color: var(--caution); margin-bottom: 6px; }
.alert-warnings ul { padding-left: 17px; font-size: 13px; line-height: 21px; }
.alert-file-details { border-top: 1px solid var(--divider); }
.alert-file-details summary { padding: 14px 0; color: var(--text-secondary); font-size: 12px; cursor: pointer; }
.alert-file-details dl { display: grid; grid-template-columns: 85px minmax(0, 1fr); gap: 12px; padding: 4px 0 20px; font-size: 12px; }
.alert-file-details dt { color: var(--text-secondary); }
.alert-file-details dd { margin: 0; overflow-wrap: anywhere; user-select: text; }
.alert-decision { padding: 26px 0 20px; }
.alert-decision .alert-actions { margin-top: 0; }
.alert-decision > p { color: var(--text-secondary); font-size: 13px; line-height: 21px; margin-top: 7px; max-width: 700px; }
.alert-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 18px; }
.alert-actions .btn { padding: 9px 18px; white-space: normal; }
.alert-actions .link { font-size: 13px; margin-left: auto; padding: 8px 0; }
.alert-decision .alert-mute-note { font-size: 12px; margin-top: 12px; }
.alert-footer { border-top: 1px solid var(--divider); padding-top: 16px; color: var(--text-secondary); font-size: 11px; line-height: 18px; }
@media (max-width: 650px) {
  .alert-page { padding: 20px 16px; }
  .alert-evidence { padding: 18px 16px 0; }
  .alert-actions .link { margin-left: 0; }
}

.page-foot {
  margin-top: auto;
  padding-top: 8px;
  text-align: center;
}

/* A button, not an anchor: a webview swallows target="_blank", so the shell
   opens the site instead. It should still read as a link. */
.link {
  font: inherit;
  font-size: 12px;
  color: var(--accent);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.link:hover {
  text-decoration: underline;
}

.link[hidden] {
  display: none;
}

/* --- scrollbar: present when it is needed, invisible until then --- */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: transparent;
  background-clip: content-box;
  transition: background var(--fast) var(--ease-out);
}

.content:hover::-webkit-scrollbar-thumb {
  background: var(--text-tertiary);
  background-clip: content-box;
}
