/* FixCamera console.

   One set of variables for every page. The palette is carried over from the
   original status page (validated for colour-vision separation and contrast);
   light and dark are both chosen explicitly rather than inverted. */

:root {
  color-scheme: light;
  --plane:      #f9f9f7;
  --surface:    #fcfcfb;
  --border:     #e4e3df;
  --ink:        #0b0b0b;
  --ink-2:      #52514e;
  --muted:      #898781;
  --series-1:   #2a78d6;
  --series-2:   #eb6834;
  --accent:     var(--series-1);
  --accent-ink: #ffffff;
  --good:       #0ca30c;
  --warning:    #fab219;
  --serious:    #ec835a;
  --critical:   #d03b3b;

  --radius:     8px;
  --gap:        16px;
  --nav-width:  200px;
  --topbar-h:   56px;
  --font: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --plane:    #0d0d0d;
    --surface:  #1a1a19;
    --border:   #2e2e2c;
    --ink:      #ffffff;
    --ink-2:    #c3c2b7;
    --muted:    #898781;
    --series-1: #3987e5;
    --series-2: #d95926;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --plane:    #0d0d0d;  --surface: #1a1a19;  --border: #2e2e2c;
  --ink:      #ffffff;  --ink-2:   #c3c2b7;  --muted:  #898781;
  --series-1: #3987e5;  --series-2: #d95926;
}

* { box-sizing: border-box; }
html, body { max-width: 100%; overflow-x: hidden; }
body {
  margin: 0; background: var(--plane); color: var(--ink);
  font: 15px/1.6 var(--font);
}
[hidden] { display: none !important; }
h1, h2, h3 { font-weight: 600; margin: 0; }
h1 { font-size: 1.25rem; }
h2 { font-size: 1.05rem; margin-bottom: 8px; }
.muted { color: var(--muted); }
.spacer { flex: 1; }

/* --------------------------------------------------------------- controls */
button, select, input {
  font: inherit; color: var(--ink); max-width: 100%;
}
.btn, select {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 12px; cursor: pointer;
}
.btn:hover, select:hover { border-color: var(--muted); }
.btn:disabled, select:disabled { cursor: default; opacity: .6; }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn.link {
  background: none; border: none; color: var(--ink-2);
  text-decoration: underline; text-underline-offset: 3px; padding: 6px 0;
}
a:focus-visible, button:focus-visible, select:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* ------------------------------------------------------------------- boot */
.boot { max-width: 420px; margin: 18vh auto; padding: 0 20px; text-align: center; }

/* ------------------------------------------------------------------ login */
.login {
  width: calc(100% - 32px); max-width: 340px; margin: 12vh auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 26px;
}
.login h1 { margin-bottom: 4px; }
.login p { font-size: .85rem; margin: 0 0 18px; }
.login label { display: block; font-size: .8rem; color: var(--ink-2); margin: 12px 0 4px; }
.login input {
  width: 100%; padding: 8px 10px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--plane);
}
.login button[type=submit] { width: 100%; margin-top: 18px; padding: 9px; }
.err { color: var(--critical); font-size: .82rem; margin: 12px 0 0; }

/* ------------------------------------------------------------------ shell */
.shell {
  display: grid; min-height: 100vh;
  grid-template-columns: var(--nav-width) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas: "top top" "nav main";
}
.topbar {
  grid-area: top; display: flex; align-items: center; flex-wrap: wrap;
  gap: 8px 16px; padding: 10px 20px; min-height: var(--topbar-h);
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.brand { font-weight: 600; font-size: 1.1rem; }
.pickers { display: flex; gap: 8px 16px; flex-wrap: wrap; min-width: 0; }
.picker { display: flex; align-items: center; gap: 6px; min-width: 0; }
.picker label { font-size: .82rem; color: var(--ink-2); white-space: nowrap; }
.picker select { min-width: 0; max-width: 240px; }
.user { font-size: .85rem; overflow-wrap: anywhere; }
.nav-toggle { display: none; }

.sidenav {
  grid-area: nav; background: var(--surface);
  border-right: 1px solid var(--border); padding: 12px 0;
}
.sidenav ul { list-style: none; margin: 0; padding: 0; }
.sidenav a {
  display: block; padding: 8px 20px; color: var(--ink-2); text-decoration: none;
  border-left: 3px solid transparent;
}
.sidenav a:hover { color: var(--ink); background: var(--plane); }
.sidenav a[aria-current="page"] {
  color: var(--ink); font-weight: 600; border-left-color: var(--accent);
  background: var(--plane);
}

.content { grid-area: main; padding: 20px; min-width: 0; outline: none; }
.content > * { max-width: 1100px; }

/* ---------------------------------------------------------- shared blocks */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-bottom: var(--gap);
}
.empty { color: var(--muted); padding: 20px 0; text-align: center; margin: 0; }
.error-box {
  background: var(--surface); border: 1px solid var(--critical);
  border-radius: var(--radius); padding: 14px 16px; margin-bottom: var(--gap);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.error-text { margin: 0; color: var(--critical); }

/* ----------------------------------------------------------------- toasts */
.toasts {
  position: fixed; right: 16px; bottom: 16px; z-index: 50;
  display: flex; flex-direction: column; gap: 8px;
  max-width: calc(100vw - 32px); width: 320px; pointer-events: none;
}
.toast {
  pointer-events: auto; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border); border-left: 4px solid var(--accent);
  border-radius: 6px; padding: 10px 12px; font-size: .88rem;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .12); overflow-wrap: anywhere;
}
.toast.success { border-left-color: var(--good); }
.toast.warning { border-left-color: var(--warning); }
.toast.error   { border-left-color: var(--critical); }

/* ------------------------------------------------------------- page head */
.page-head {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px;
  padding-bottom: 12px; margin-bottom: var(--gap); border-bottom: 1px solid var(--border);
}
.page-head h2 { margin: 0; overflow-wrap: anywhere; }
.meta { color: var(--muted); font-size: .85rem; font-variant-numeric: tabular-nums; }
/* Online state: words and glyph carry the meaning, colour only reinforces. */
.badge { font-size: .82rem; white-space: nowrap; }
.badge.online  { color: var(--good); }
.badge.offline { color: var(--muted); }

/* Voltage status line (tiles and overview cards). */
.s { font-size: .78rem; margin: 4px 0 0; display: flex; align-items: center; gap: 5px; }
.s .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.s.good     { color: var(--good); }
.s.warning  { color: var(--warning); }
.s.serious  { color: var(--serious); }
.s.critical { color: var(--critical); }
.s.good .dot     { background: var(--good); }
.s.warning .dot  { background: var(--warning); }
.s.serious .dot  { background: var(--serious); }
.s.critical .dot { background: var(--critical); }

/* --------------------------------------------------------------- overview */
.cam-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
}
.cam-card {
  display: block; color: inherit; text-decoration: none; min-width: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px;
}
.cam-card:hover { border-color: var(--muted); }
.cam-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.cam-head h3 { font-size: 1rem; overflow-wrap: anywhere; }
.cam-card .meta { margin: 4px 0 0; }
.readings {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  margin: 10px 0 0;
}
.reading dt { color: var(--muted); font-size: .74rem; }
.reading dd {
  margin: 0; font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.reading dd small, .tile .v small {
  font-size: .75rem; font-weight: 400; color: var(--ink-2); margin-left: 3px;
}
.gaps.failed { color: var(--critical); }

/* ---------------------------------------------------------- device status */
.tiles {
  display: grid; gap: 10px; margin-bottom: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
}
.tile {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px; min-width: 0;
}
.tile .k { color: var(--muted); font-size: .76rem; letter-spacing: .04em; }
.tile .v {
  font-size: 1.5rem; font-weight: 600; margin-top: 2px;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.filters { display: flex; gap: 8px; align-items: center; margin-bottom: var(--gap); flex-wrap: wrap; }
.seg {
  display: inline-flex; flex-wrap: wrap; border: 1px solid var(--border);
  border-radius: 6px; overflow: hidden; background: var(--surface);
}
.seg button { border: none; background: none; padding: 6px 14px; cursor: pointer; }
.seg button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

.chart {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px 16px 8px; margin-bottom: var(--gap);
}
.chart h2 { font-size: .95rem; margin: 0 0 2px; }
.chart .sub { color: var(--muted); font-size: .78rem; margin: 0 0 10px; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: .8rem; color: var(--ink-2); margin-bottom: 8px; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 14px; height: 2px; border-radius: 1px; }
.legend-event b { color: var(--critical); font-weight: 400; font-size: .7rem; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; touch-action: pan-y; }
.chart-grid { stroke: var(--border); stroke-width: 1; }
.chart-axis { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.chart-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-band { fill-opacity: .15; stroke: none; }
.chart-event { fill: var(--critical); stroke: var(--surface); stroke-width: 1.5; }
.chart-crosshair { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
/* A ring in the surface colour keeps a marker legible on its own line. */
.chart-marker { stroke: var(--surface); stroke-width: 2; }

.chart-tip {
  position: fixed; pointer-events: none; z-index: 40; max-width: calc(100vw - 16px);
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  padding: 8px 10px; font-size: .8rem; box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
  font-variant-numeric: tabular-nums;
}
.chart-tip b { display: block; color: var(--muted); font-weight: 400; font-size: .74rem; margin-bottom: 3px; }
.chart-tip .row { display: flex; align-items: center; gap: 6px; }
.chart-tip .row i { width: 10px; height: 2px; border-radius: 1px; flex: none; }
.chart-tip .row.event { color: var(--critical); }

.scroll { overflow-x: auto; max-width: 100%; }
.chart table { width: 100%; border-collapse: collapse; font-size: .82rem; font-variant-numeric: tabular-nums; }
.chart th, .chart td { text-align: right; padding: 6px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.chart th:first-child, .chart td:first-child { text-align: left; }
.chart th { color: var(--muted); font-weight: 500; }
.chart td.note-event { color: var(--critical); text-align: left; }

/* --------------------------------------------------------- settings pages */
.notice {
  display: flex; align-items: flex-start; gap: 8px; margin: 0 0 var(--gap);
  padding: 10px 14px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--warning);
}
.notice-icon { flex: none; font-style: normal; }
.settings-status { display: grid; gap: 4px; }
.st-row { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; overflow-wrap: anywhere; }
.st-label { color: var(--ink-2); min-width: 5em; }
.st-delivery .notice-icon { color: var(--serious); }
.st-device { color: var(--ink-2); }
.settings-notes ul { margin: 0; padding-left: 1.2em; color: var(--ink-2); font-size: .88rem; }

.form-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 6px 0; }
.check { display: inline-flex; align-items: center; gap: 6px; }
.check input { width: 16px; height: 16px; margin: 0; }
.field { display: inline-flex; align-items: center; gap: 6px; }
.field label { font-size: .82rem; color: var(--ink-2); }
input.num {
  width: 6.5em; padding: 5px 8px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--plane);
}
input:disabled { opacity: .6; }
.btn.small { padding: 3px 8px; font-size: .8rem; }

.win-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px;
  padding: 8px 10px; margin: 4px 0 8px;
  background: var(--plane); border: 1px solid var(--border); border-radius: 6px;
  font-size: .86rem;
}
.win-toolbar select { padding: 3px 6px; }
.win-copy-done { font-size: .8rem; }
.win-list { display: grid; gap: 2px; }
.win-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  padding: 6px 0; border-bottom: 1px solid var(--border);
}
.win-row:last-child { border-bottom: none; }
.win-day { width: 2.5em; font-weight: 600; }
.win-row .field-error { flex-basis: 100%; }
.win-hint { font-size: .8rem; }

/* Errors: a cross and words, not colour alone. */
.field-error { color: var(--critical); font-size: .84rem; }
.field-error p { margin: 2px 0; }
.field-error p::before { content: "✕ "; }

.tb-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: .82rem; color: var(--ink-2); margin: 0 0 8px; }
.tb-legend span { display: inline-flex; align-items: center; gap: 6px; }
.tb-swatch { display: inline-block; width: 18px; height: 10px; border-radius: 2px; }
.tb-list { display: grid; gap: 4px; }
.tb-row { display: grid; grid-template-columns: 2.5em minmax(0, 1fr); align-items: center; gap: 8px; }
.tb-day { font-size: .82rem; color: var(--ink-2); }
.tb-bar {
  position: relative; height: 22px; border-radius: 3px; overflow: hidden;
  background-color: var(--plane); border: 1px solid var(--border);
  background-image: linear-gradient(to right, var(--border) 1px, transparent 1px);
  background-size: calc(100% / 24) 100%;
}
.tb-seg { position: absolute; }
.tb-seg.tb-capture { top: 0; height: 50%; }
.tb-seg.tb-upload  { bottom: 0; height: 50%; }
/* Capture is solid, upload is hatched: the two differ by pattern and by
   position (top/bottom half), so colour is not the only cue. */
.tb-capture { background: var(--series-1); }
.tb-upload {
  background: repeating-linear-gradient(45deg, var(--series-2) 0 3px, transparent 3px 6px);
  box-shadow: inset 0 0 0 1px var(--series-2);
}
.tb-scale { position: relative; height: 1.2em; font-size: .72rem; color: var(--muted); }
.tb-scale span { position: absolute; transform: translateX(-50%); }
.tb-scale span:first-child { transform: none; }
.tb-scale span:last-child { transform: translateX(-100%); }

.warn-list { list-style: none; margin: 0 0 var(--gap); padding: 0; }
.warn-list li {
  display: flex; gap: 8px; padding: 8px 12px; margin-bottom: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 4px solid var(--warning); border-radius: 6px;
}
.error-box.conflict { flex-direction: column; align-items: flex-start; gap: 6px; }
.error-box.conflict p { margin: 0; }

.save-bar {
  position: sticky; bottom: 0; z-index: 5;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 10px 14px; margin-bottom: var(--gap);
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .06);
}
.save-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.dirty { color: var(--serious); font-size: .88rem; display: inline-flex; gap: 6px; align-items: center; }
.save-result:empty { display: none; }
.save-line { margin: 6px 0 0; font-size: .86rem; overflow-wrap: anywhere; }
.save-line.success { color: var(--good); }
.save-line.error { color: var(--critical); }
.save-line.success::before { content: "✓ "; }
.save-line.error::before { content: "✕ "; }

.drawer-root { position: fixed; inset: 0; z-index: 60; }
.drawer-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .35); }
.drawer {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(420px, 100%); overflow-y: auto; outline: none;
  background: var(--surface); border-left: 1px solid var(--border); padding: 16px;
}
.drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.drawer-head h2 { margin: 0; }
.drawer-note { margin: 0 0 12px; }
.hist-list { list-style: none; margin: 0; padding: 0; }
.hist-item { padding: 10px 0; border-bottom: 1px solid var(--border); }
.hist-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.hist-tag {
  font-size: .74rem; color: var(--ink-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 0 8px;
}
.hist-changes { margin: 6px 0 0; padding-left: 1.2em; font-size: .86rem; overflow-wrap: anywhere; }

/* camera / storage settings */
.notice-support { font-size: .95rem; }
.notice-support .notice-icon { color: var(--serious); }
input.text {
  padding: 5px 8px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--plane);
}
input[aria-invalid="true"] { border-color: var(--critical); }
.path-root { margin: 0 0 6px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; overflow-wrap: anywhere; }
.path-root code { font-size: .9rem; }
.path-row { flex-wrap: nowrap; }
.path-row label { flex: none; font-size: .82rem; color: var(--ink-2); }
.path-input { flex: 1 1 auto; min-width: 0; width: 100%; }
.path-ok { margin: 2px 0; font-size: .84rem; color: var(--good); overflow-wrap: anywhere; }
.path-ok:empty { display: none; }
.path-rules { margin: 6px 0 0; padding-left: 1.2em; font-size: .84rem; }

/* ----------------------------------------------------------------- photos */
.sub-head { font-size: .9rem; font-weight: 600; margin: 0 0 8px; color: var(--ink-2); }
.folder-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.folder-btn {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 0;
  min-width: 0; max-width: 100%; padding: 6px 12px; cursor: pointer; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
}
.folder-btn:hover { border-color: var(--muted); }
.folder-btn[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* The tick carries "selected"; the accent border only reinforces it. */
.folder-btn[aria-pressed="true"] .folder-name::before { content: "✓ "; }
.folder-name { font-weight: 600; overflow-wrap: anywhere; }
.folder-meta { font-size: .76rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.photo-filters .hint { margin: 6px 0 0; }

.sel-bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px 12px; margin-bottom: var(--gap);
}
.sel-count { font-weight: 600; font-variant-numeric: tabular-nums; }
.sel-hint { font-size: .84rem; color: var(--muted); }
.sel-hint.over { color: var(--critical); }

.photo-grid {
  list-style: none; margin: 0 0 var(--gap); padding: 0;
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr));
}
.photo-tile {
  min-width: 0; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.photo-tile.removed { border-style: dashed; }
.thumb-btn { display: block; width: 100%; padding: 0; border: none; background: none; cursor: zoom-in; }
.thumb {
  aspect-ratio: 4 / 3; width: 100%;
  display: flex; align-items: center; justify-content: center;
  background: var(--plane);
}
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-tile.removed .thumb img { opacity: .5; }
.thumb.unavailable { outline: 1px dashed var(--border); outline-offset: -6px; }
.thumb-text { font-size: .8rem; color: var(--muted); padding: 4px; text-align: center; }
.tile-foot { display: grid; gap: 2px; padding: 6px 8px 8px; font-size: .8rem; min-width: 0; }
.tile-foot .meta { font-size: .74rem; }
.tile-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ------------------------------------------------ one photo per day builder */
.daily-builder .form-row { margin-bottom: 8px; }
.daily-builder input.text, .daily-builder select { padding: 5px 8px; }
.daily-result { margin-top: 10px; }
.daily-strip {
  display: grid; gap: 8px; margin: 8px 0 12px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 112px), 1fr));
  max-height: 460px; overflow-y: auto; padding-right: 4px;
}
.daily-tile {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; overflow: hidden; min-width: 0;
}
.daily-tile.missing { border-style: dashed; }
.daily-tile.missing .thumb-text { color: var(--serious); }
.daily-caption { font-size: .72rem; padding: 4px 6px 6px; overflow-wrap: anywhere; }
.daily-options { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }
.tag-removed { color: var(--critical); font-size: .74rem; }
.more-row { display: flex; align-items: center; gap: 10px; margin-bottom: var(--gap); }

/* ----------------------------------------------------------------- energy */
.tile-hint { color: var(--muted); font-size: .74rem; margin-top: 2px; }
.energy-svg { display: block; width: 100%; height: auto; overflow: visible; }
.energy-hit { fill: transparent; }
.energy-measured { fill: var(--series-1); }
.energy-estimated { fill: var(--series-1); fill-opacity: .22; stroke: var(--series-1); stroke-opacity: .55; stroke-dasharray: 3 2; }
.energy-bar.in-progress .energy-measured { fill-opacity: .7; }
.energy-bar:focus { outline: none; }
.energy-bar.active .energy-hit,
.energy-bar:focus-visible .energy-hit { fill: var(--border); fill-opacity: .45; }
.energy-mark { fill: var(--serious); font-size: 12px; font-weight: 700; }
.energy-bar.level-none .energy-mark { fill: var(--muted); }
.legend i.swatch { width: 12px; height: 10px; border-radius: 2px; }
.energy-measured-swatch { background: var(--series-1); }
.energy-estimated-swatch {
  background: color-mix(in srgb, var(--series-1) 22%, transparent);
  outline: 1px dashed color-mix(in srgb, var(--series-1) 55%, transparent); outline-offset: -1px;
}
.energy-mark-text { color: var(--serious); font-weight: 700; }
.energy-readout { margin: 6px 0 8px; font-size: .84rem; color: var(--ink-2); min-height: 1.3em; font-variant-numeric: tabular-nums; }
.chart tr[data-level="low"] td:nth-child(6) { color: var(--serious); }
.chart tr[data-level="none"] td { color: var(--muted); }
.energy-note { line-height: 1.6; margin: 0 0 var(--gap); }

.modal-root {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.modal-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .45); }
.modal {
  position: relative; width: min(460px, 100%); max-height: calc(100vh - 32px); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; outline: none;
}
.modal.wide { width: min(1000px, 100%); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.modal-head h2 { margin: 0; overflow-wrap: anywhere; }
.preview { display: grid; gap: 12px; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.preview-image {
  min-height: 200px; display: flex; align-items: center; justify-content: center;
  background: var(--plane); border-radius: 6px;
}
.preview-image img { max-width: 100%; max-height: 70vh; display: block; }
.meta-list { margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; font-size: .86rem; }
.meta-list dt { color: var(--muted); }
.meta-list dd { margin: 0; overflow-wrap: anywhere; }
.video-form p { margin: 0 0 6px; }

/* ------------------------------------------------------------ narrow view */
@media (max-width: 720px) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "top" "nav" "main";
  }
  .topbar { padding: 8px 12px; }
  .nav-toggle { display: inline-block; }
  .pickers { order: 10; width: 100%; }
  .picker { flex: 1 1 140px; }
  .picker select { flex: 1; width: 100%; max-width: none; }
  .sidenav { display: none; border-right: none; border-bottom: 1px solid var(--border); padding: 4px 0; }
  .sidenav.open { display: block; }
  .content { padding: 12px; }
  .toasts { right: 16px; left: 16px; width: auto; }
  .readings { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tile .v { font-size: 1.25rem; }
  .seg button { padding: 6px 10px; }
  .preview { grid-template-columns: minmax(0, 1fr); }
  .photo-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 130px), 1fr)); }
}

/* ------------------------------------------- storage page: CM4 SSD status */
.cm4-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; margin-bottom: 8px; }
.cm4-head h2 { margin: 0; }
.cm4-updated { margin-left: auto; }
.cm4-status-wrap { margin-bottom: 12px; }
.cm4-when { font-variant-numeric: tabular-nums; }
.cm4-busy { color: var(--accent); font-weight: 600; }
.cm4-notice { margin: 8px 0 0; overflow-wrap: anywhere; }
.cm4-warn { border-left-color: var(--serious); }
.cm4-warn .notice-icon { color: var(--serious); }
.cm4-error .error-box { margin-bottom: 12px; }

.cm4-capacity { margin-bottom: 14px; }
.cm4-figures { margin: 0 0 8px; }
/* Track and fill use theme variables only; the percentage is also written
   out next to the bar, and a low SSD gets a text warning. */
.cm4-meter {
  position: relative; height: 12px; width: 100%; overflow: hidden;
  background: var(--plane); border: 1px solid var(--border); border-radius: 6px;
}
.cm4-meter-fill { height: 100%; max-width: 100%; background: var(--accent); }
.cm4-meter.low { border-color: var(--serious); }
.cm4-meter.low .cm4-meter-fill { background: var(--serious); }
.cm4-meter-text { margin: 4px 0 0; }

.cm4-empty { padding: 8px 0 4px; }
.cm4-empty p { margin: 0 0 4px; }
.cm4-empty-title { font-weight: 600; }
.cm4-empty-token { color: var(--ink-2); }

.cm4-months .sub-head { margin-top: 4px; }
.cm4-table { width: 100%; border-collapse: collapse; font-size: .84rem; font-variant-numeric: tabular-nums; }
.cm4-table th, .cm4-table td {
  text-align: right; padding: 6px 10px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.cm4-table th:first-child, .cm4-table td:first-child { text-align: left; }
.cm4-table thead th { color: var(--muted); font-weight: 500; }
.cm4-table tbody th { font-weight: 600; }
.cm4-table tfoot th, .cm4-table tfoot td { font-weight: 600; border-bottom: none; border-top: 2px solid var(--border); }
.cm4-table td.cm4-action { text-align: right; padding-top: 3px; padding-bottom: 3px; }
/* Rows that still owe photos: a tinted band, an edge mark and the word
   "需补传", so the highlight does not rely on colour. */
.cm4-table tr.cm4-need th, .cm4-table tr.cm4-need td {
  background: color-mix(in srgb, var(--warning) 14%, transparent);
}
.cm4-table tr.cm4-need th:first-child { box-shadow: inset 3px 0 0 var(--warning); }
.cm4-flag {
  display: inline-block; margin-left: 8px; padding: 0 6px; border-radius: 10px;
  font-size: .74rem; font-weight: 500; color: var(--ink);
  border: 1px solid var(--warning); background: var(--surface);
}

@media (max-width: 480px) {
  .cm4-updated { margin-left: 0; flex-basis: 100%; }
  .cm4-figures .reading dd { font-size: 1rem; }
  .cm4-table th, .cm4-table td { padding: 6px 8px; }
}

/* ------------------------------ storage page: upload a month (CM4 tasks) */
.cm4-task-intro { margin: -4px 0 10px; }
.cm4-task-form { margin-bottom: 14px; }
.cm4-task-form select, .cm4-task-form input.text { padding: 5px 8px; }
.cm4-month-field { flex-wrap: wrap; min-width: 0; max-width: 100%; }
.cm4-month-field select, .cm4-month-field input { min-width: 0; max-width: 100%; }
.cm4-month-hint { margin: 0 0 4px; overflow-wrap: anywhere; }
.cm4-mode {
  min-width: 0; margin: 8px 0 6px; padding: 6px 12px 8px;
  border: 1px solid var(--border); border-radius: 6px;
}
.cm4-mode legend { padding: 0 4px; font-size: .82rem; color: var(--ink-2); }
.cm4-radio {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline;
  gap: 0 8px; margin: 4px 0;
}
.cm4-radio input { width: 16px; height: 16px; margin: 0; align-self: center; }
.cm4-radio-note { grid-column: 2; margin: 0; overflow-wrap: anywhere; }
.cm4-include { margin-top: 4px; }
.cm4-submit-row { margin-top: 10px; }
.cm4-confirm { margin: 8px 0 0; border-left-color: var(--accent); }
.cm4-confirm .notice-icon { color: var(--accent); font-weight: 700; }
.cm4-confirm-body { min-width: 0; }
.cm4-confirm-body .form-row { margin-bottom: 0; }
.cm4-result, .cm4-list-result { margin: 0 0 8px; }
.cm4-task-head { border-top: 1px solid var(--border); padding-top: 12px; }
.cm4-task-head .sub-head { margin: 0; }
.cm4-task-head .meta { margin-left: auto; }

.cm4-task-table { width: 100%; border-collapse: collapse; font-size: .84rem; font-variant-numeric: tabular-nums; }
.cm4-task-table th, .cm4-task-table td {
  text-align: left; vertical-align: top; padding: 6px 10px;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.cm4-task-table thead th { color: var(--muted); font-weight: 500; }
.cm4-task-table td .meta { font-size: .78rem; }
.cm4-task-table td.cm4-task-summary { white-space: normal; min-width: 9em; max-width: 16em; }
.cm4-task-table td.cm4-task-reason { white-space: normal; min-width: 8em; max-width: 20em; overflow-wrap: anywhere; }
.cm4-task-table td.cm4-task-action { padding-top: 3px; padding-bottom: 3px; }
/* Status: glyph and words carry the state; the dot takes the level colour,
   the words stay in the body ink so they read on both themes. */
.cm4-task-table .s.cm4-task-status { display: inline-flex; margin: 0; font-size: inherit; color: var(--ink); }
.s.cm4-task-status.muted .dot { background: var(--muted); }
.cm4-task-icon { display: inline-block; min-width: 1.1em; text-align: center; font-variant-emoji: text; }
.cm4-cancel-confirm { display: inline-flex; gap: 6px; }
/* The row a 409 pointed at: tint, edge mark and the words "已有同类指令". */
.cm4-task-table tr.cm4-task-hl td { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.cm4-task-table tr.cm4-task-hl td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.cm4-flag.cm4-flag-hl { border-color: var(--accent); margin-left: 6px; }

@media (max-width: 480px) {
  .cm4-mode { padding: 6px 10px 8px; }
  .cm4-task-head .meta { margin-left: 0; flex-basis: 100%; }
  .cm4-task-table th, .cm4-task-table td { padding: 6px 8px; }
}

/* ------------------------------ storage page: capture and upload test */
/* Intro, button hint and "no test yet" use --ink-2: --muted text is about
   3.5:1 on the light surface, and the hint carries "请先保存 Dropbox 路径再测试". */
.cm4-capture-intro { margin: -4px 0 10px; overflow-wrap: anywhere; color: var(--ink-2); }
/* Every secondary line in this card (creator and time, check detail and
   time, the re-check hint, the thumbnail caption) likewise: --ink-2. */
.cm4-capture-card .meta { color: var(--ink-2); }
.cm4-capture-info { margin-bottom: 10px; }
.cm4-capture-info .st-label { min-width: 6.5em; }
/* Long Dropbox paths wrap anywhere instead of widening the card. */
.cm4-capture-path {
  font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  font-size: .86rem; overflow-wrap: anywhere; word-break: break-all; min-width: 0;
}
.cm4-capture-notices .cm4-notice { margin: 0 0 8px; }
.cm4-capture-notices:empty { display: none; }
.cm4-capture-notice .notice-icon { font-variant-emoji: text; }
.cm4-capture-dirty strong, .cm4-capture-mismatch strong { font-weight: 600; }
.cm4-capture-actions { margin: 4px 0 0; }
.cm4-capture-hint { overflow-wrap: anywhere; color: var(--ink-2); }
.cm4-capture-hint:empty { display: none; }
.cm4-capture-messages { margin: 0 0 4px; }
/* Messages keep the body ink (the theme's green and red text fall under
   4.5:1 on one theme or the other); the leading tick or cross carries the
   tone in colour. */
.save-line.cm4-capture-line { color: var(--ink); }
.save-line.cm4-capture-line.success::before { color: var(--good); }
.save-line.cm4-capture-line.error::before { color: var(--critical); }
.save-line.cm4-capture-line.info::before { content: "ⓘ "; color: var(--accent); }
.cm4-capture-error-text { color: var(--ink); }

.cm4-capture-test { margin-top: 12px; }
.cm4-capture-test:empty { display: none; }
.cm4-capture-none { margin: 0; color: var(--ink-2); }
.cm4-capture-head { border-top: 1px solid var(--border); padding-top: 12px; }
.cm4-capture-head .sub-head { margin: 0; }

/* Four steps: number, tick, arrow or cross plus words; the current step
   also says "（进行中）", so colour is never the only cue. */
.cm4-capture-steps {
  list-style: none; margin: 0 0 12px; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px;
}
.cm4-capture-step {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--plane); color: var(--ink-2); font-size: .84rem; overflow-wrap: anywhere;
}
.cm4-capture-mark {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 1.5em; height: 1.5em; border-radius: 50%; font-size: .78rem; font-weight: 700;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink);
  font-variant-emoji: text; font-variant-numeric: tabular-nums;
}
.cm4-capture-step.done { color: var(--ink); }
.cm4-capture-step.done .cm4-capture-mark { border-color: var(--good); }
.cm4-capture-step.current {
  color: var(--ink); font-weight: 600; border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent); background: var(--surface);
}
.cm4-capture-step.current .cm4-capture-mark { border-color: var(--accent); }
.cm4-capture-step.bad { color: var(--ink); font-weight: 600; border-color: var(--critical); }
.cm4-capture-step.bad .cm4-capture-mark { border-color: var(--critical); }
.cm4-capture-now { font-weight: 600; }

.cm4-capture-result {
  display: grid; gap: 12px 16px; align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(0, 240px);
}
.cm4-capture-result.cm4-capture-failed { grid-template-columns: minmax(0, 1fr); }
.cm4-capture-body { min-width: 0; display: grid; gap: 8px; }
.cm4-capture-body .st-row { overflow-wrap: anywhere; }
.cm4-capture-body .form-row { margin: 0; }
.cm4-capture-body .cm4-notice { margin: 0; }
.cm4-capture-rows { font-size: .88rem; }
.cm4-capture-rows dt { color: var(--ink-2); }
.cm4-capture-warn-value { display: flex; gap: 6px; align-items: baseline; }
.cm4-capture-flag { color: var(--serious); font-variant-emoji: text; }
.cm4-capture-verdict {
  display: inline-flex; align-items: center; gap: 6px; color: var(--ink); font-weight: 600;
  padding: 0 8px 0 2px; border: 1px solid var(--border); border-radius: 12px;
}
.cm4-capture-verdict .cm4-capture-mark { width: 1.3em; height: 1.3em; border: none; background: none; }
.cm4-capture-verdict.good { border-color: var(--good); }
.cm4-capture-verdict.warning { border-color: var(--serious); }
.cm4-capture-thumb { margin: 0; min-width: 0; max-width: 100%; }
.cm4-capture-thumb .thumb { border-radius: 6px; overflow: hidden; border: 1px solid var(--border); }
.cm4-capture-thumb figcaption { margin-top: 4px; }
.cm4-capture-thumb .thumb-text { color: var(--ink-2); }
.cm4-capture-view { margin-top: 8px; }

/* "查看大图": the same panel, meta list and image frame as the photo page's
   preview (lib/modal.js + .preview-image / .meta-list above). */
.cm4-photo-modal { display: grid; gap: 12px; min-width: 0; }
.cm4-photo-meta dd code { overflow-wrap: anywhere; }
.cm4-photo-modal .preview-image { min-height: 220px; padding: 12px; }
.cm4-photo-modal .preview-image img {
  max-width: 100%; max-height: min(70vh, 640px); object-fit: contain;
}
.cm4-photo-status { display: grid; gap: 8px; justify-items: center; text-align: center; }
.cm4-photo-status .thumb-text { color: var(--ink-2); padding: 0; }
.cm4-photo-status .cm4-photo-error { color: var(--ink); font-weight: 600; }

@media (max-width: 720px) {
  .cm4-capture-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cm4-capture-result { grid-template-columns: minmax(0, 1fr); }
  .cm4-capture-thumb { max-width: 320px; }
}
@media (max-width: 480px) {
  .cm4-capture-steps { grid-template-columns: minmax(0, 1fr); }
  .cm4-capture-head .meta { flex-basis: 100%; }
  .cm4-capture-actions .btn { flex: 1 1 100%; }
  .cm4-photo-modal .preview-image { min-height: 150px; padding: 8px; }
  .cm4-photo-modal .preview-image img { max-height: 52vh; }
}

/* ------------------------------------------------- camera settings page */
.camera-notice-body { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.camera-model-note { margin: 0; font-size: .88rem; color: var(--ink-2); }
.camera-group h2 { margin-bottom: 4px; }
.camera-param { padding: 10px 0; border-top: 1px solid var(--border); min-width: 0; }
.camera-group h2 + .camera-param { border-top: none; padding-top: 2px; }
.camera-param:last-child { padding-bottom: 0; }
.camera-param .form-row { margin: 0; gap: 6px 12px; }
.camera-param .field { flex-wrap: wrap; gap: 6px 10px; min-width: 0; max-width: 100%; }
.camera-param .field label { min-width: 8.5em; font-size: .9rem; font-weight: 500; color: var(--ink); }
.camera-param select { min-width: 11em; max-width: 100%; }
.camera-param input.num { width: 9em; max-width: 100%; }
/* Disabled: dimmed and dashed, and always paired with a .camera-lock reason. */
.camera-param select:disabled, .camera-param input:disabled { border-style: dashed; }
.camera-lock {
  font-size: .8rem; color: var(--ink-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 0 8px; overflow-wrap: anywhere;
}
/* .meta defaults to --muted, which is under 4.5:1 on the light surface. */
.camera-param .meta { color: var(--ink-2); }
.camera-help { margin-top: 4px; font-size: .84rem; }
.camera-help p { margin: 0; overflow-wrap: anywhere; }
.camera-help-k { font-weight: 600; }
.camera-param .field-error { margin-top: 4px; }
.camera-warn { margin-top: 6px; }
.camera-warn .warn-list { margin: 0; }
.camera-warn .warn-list li { margin-bottom: 4px; font-size: .88rem; overflow-wrap: anywhere; }
.save-result .warn-list { margin: 8px 0 0; }
.save-result .warn-list li { margin-bottom: 4px; font-size: .86rem; overflow-wrap: anywhere; }

/* Narrow screens: cards sit 16px from the viewport edge (content gives 12). */
@media (max-width: 720px) {
  .camera-view { margin: 0 4px; }
}
@media (max-width: 480px) {
  .camera-param .field { flex: 1 1 100%; }
  .camera-param .field label { flex: 1 1 100%; min-width: 0; }
  .camera-param select, .camera-param input.num { flex: 1 1 auto; width: 100%; min-width: 0; }
}
