/* Systems — the engine room (renderer/systems/systems.js).
 *
 * Direction: THE ENGINE ROOM. The house's own machinery behind one door: walnut
 * and brass, the hand the Storage ledger, the Automations gauge wall and the
 * Keeper's register already share, now mounted on one wall. The masthead is a
 * brass instrument panel — concentric rings turning slowly behind an ember —
 * and the room switcher is an instrument cluster: four dials, each a live
 * reading (the arc) and the door to its room (the button). Titles in the Iowan
 * serif the rooms use; everything else in the app's own face.
 *
 * WHAT THIS FILE OWNS. The shell: masthead, search capsule, dials, the room
 * swap, scroll reveals for every room's furniture, the finder's scope chip and
 * the "nothing matches" line. Each room keeps its own stylesheet for its own
 * furniture (storage.css, automations.css, admin.css, server-setup.css); the
 * tokens below are the same values those files declare, restated here so the
 * shell never reaches into a room's variables.
 *
 * MOTION. Every reveal sits behind html.sys-motion, which systems.js sets only
 * when the page is NOT asking for reduced motion and IntersectionObserver
 * exists — so with JS off, with reduced motion on, or in a screenshot before
 * the observer fires, every plank, plate and dial is simply there.
 */

.sys {
  --sys-wood:      #171219;
  --sys-wood-2:    #1d1720;
  --sys-plate:     #221b24;
  --sys-plate-2:   #2a2029;
  --sys-brass:     #c9a24a;
  --sys-brass-hi:  #e8c681;
  --sys-brass-dim: #8a6f33;
  --sys-brass-rgb: 201, 162, 74;
  --sys-ember:     #ff9a3c;
  --sys-ember-hi:  #ffc77a;
  --sys-ember-rgb: 255, 154, 60;
  --sys-ink:       var(--text);
  --sys-ink-dim:   var(--text-dim);
  --sys-ink-mute:  var(--text-mute);
  --sys-line:      rgba(255, 206, 160, .10);
  --sys-line-hi:   rgba(255, 190, 130, .28);
  --sys-bad:       #e0543f;
  --sys-good:      #cf9a3f;
  --sys-serif:     'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --sys-ease:      cubic-bezier(.16, 1, .3, 1);
  --sys-gutter:    clamp(16px, 3vw, 40px);
}

/* The shell scroller: one column, the rooms' own gap between its furniture. */
.sys .sys-scroll {
  padding: 0 var(--sys-gutter) 64px;
  gap: 22px;
  scroll-padding-top: 16px;
}
.sys .sys-scroll.is-modal-open { overflow: hidden; }

/* ── the masthead ────────────────────────────────────────────────────────── */

.sys-mast {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(300px, .8fr);
  align-items: end;
  gap: 18px 32px;
  margin: 0 calc(-1 * var(--sys-gutter));
  padding: clamp(22px, 3.4vh, 34px) var(--sys-gutter) 22px;
  /* A flex item with overflow:hidden has NO automatic minimum height: the rooms
     below (flex: 1 0 auto) would squash the whole masthead to its eyebrow. */
  flex: none;
  overflow: hidden;
  border-bottom: 1px solid var(--sys-line-hi);
  background:
    radial-gradient(900px 300px at 0% 0%, rgba(var(--sys-ember-rgb), .10), transparent 65%),
    linear-gradient(180deg, rgba(255, 244, 222, .035), rgba(0, 0, 0, .18));
}
.sys-mast-art { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
/* Three brass rings turning at three speeds, a notch of ember on each, like
   the bezels of a wall of gauges seen edge-on. Pure CSS: no image to fetch. */
.sys-ring {
  position: absolute;
  top: 50%; right: 8%;
  width: 360px; height: 360px;
  margin: -180px -180px 0 0;
  border-radius: 50%;
  border: 1px solid rgba(var(--sys-brass-rgb), .18);
  box-shadow: inset 0 0 0 1px rgba(var(--sys-brass-rgb), .05);
}
.sys-ring::before {
  content: '';
  position: absolute;
  top: -2px; left: 50%;
  width: 46px; height: 3px;
  margin-left: -23px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(var(--sys-ember-rgb), .9), transparent);
  filter: blur(.4px);
}
.sys-ring.r2 { width: 520px; height: 520px; margin: -260px -260px 0 0; border-color: rgba(var(--sys-brass-rgb), .12); }
.sys-ring.r3 { width: 700px; height: 700px; margin: -350px -350px 0 0; border-color: rgba(var(--sys-brass-rgb), .08); border-style: dashed; }
.sys-ember {
  position: absolute;
  top: 50%; right: 8%;
  width: 180px; height: 180px;
  margin: -90px -90px 0 0;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--sys-ember-rgb), .22), rgba(var(--sys-ember-rgb), .06) 45%, transparent 70%);
}
.sys-grain {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(97deg, rgba(0, 0, 0, .10) 0 2px, rgba(255, 255, 255, .008) 2px 5px);
  mix-blend-mode: multiply;
  opacity: .7;
}
html.sys-motion .sys-ring    { animation: sys-turn 90s linear infinite; }
html.sys-motion .sys-ring.r2 { animation-duration: 150s; animation-direction: reverse; }
html.sys-motion .sys-ring.r3 { animation-duration: 240s; }
html.sys-motion .sys-ember   { animation: sys-breathe 6s ease-in-out infinite; }
@keyframes sys-turn { to { transform: rotate(360deg); } }
@keyframes sys-breathe { 0%, 100% { opacity: .8; transform: scale(1); } 50% { opacity: 1; transform: scale(1.08); } }

.sys-brand { display: flex; align-items: center; gap: 18px; min-width: 0; }
.sys-mark {
  flex: none;
  width: 64px; height: 64px;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .55)) drop-shadow(0 0 16px rgba(var(--sys-ember-rgb), .28));
}
.sys-brand-text { min-width: 0; }
.sys-eyebrow {
  margin: 0 0 2px;
  font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--sys-brass);
}
.sys-title {
  margin: 0;
  font-family: var(--sys-serif);
  font-size: clamp(32px, 3.8vw, 46px);
  line-height: 1.02;
  font-weight: 700;
  letter-spacing: -.005em;
  color: #f6ecd8;
  text-shadow: 0 2px 20px rgba(var(--sys-ember-rgb), .18);
}
/* One sentence every room feeds: the drive, the jobs, the people, the server. */
.sys-verdict {
  margin: 8px 0 0;
  max-width: 62ch;
  font-size: clamp(13.5px, 1.2vw, 15px);
  line-height: 1.5;
  color: var(--sys-ink-dim);
  text-wrap: pretty;
}
.sys-verdict b { color: #f3e9d6; font-weight: 600; }
.sys-verdict .is-bad { color: #ff9b86; font-weight: 600; }

/* ── the search capsule ──────────────────────────────────────────────────── */

.sys-find { min-width: 0; display: grid; gap: 6px; }
.sys-find-box {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 50px;
  padding: 0 8px 0 14px;
  border-radius: 14px;
  border: 1px solid rgba(var(--sys-brass-rgb), .34);
  background:
    linear-gradient(180deg, rgba(255, 236, 202, .05), transparent),
    rgba(10, 7, 10, .55);
  box-shadow: inset 0 1px 0 rgba(255, 233, 196, .08), 0 14px 30px -18px rgba(0, 0, 0, .9);
  cursor: text;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.sys-find-box:focus-within {
  border-color: rgba(var(--sys-ember-rgb), .7);
  box-shadow: inset 0 1px 0 rgba(255, 233, 196, .08), 0 0 0 3px rgba(var(--sys-ember-rgb), .16), 0 14px 30px -18px rgba(0, 0, 0, .9);
}
.sys-find-ico { flex: none; width: 22px; height: 22px; opacity: .9; }
.sys-find-box input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--sys-ink);
  font: 500 16px/1.3 inherit;   /* 16px: iOS does not zoom the page on focus */
  outline: none;
}
.sys-find-box input::placeholder { color: rgba(148, 137, 124, .9); }
.sys-find-box input::-webkit-search-cancel-button,
.sys-find-box input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.sys-find-clear {
  flex: none;
  width: 36px; height: 36px;
  border: 0; border-radius: 9px;
  background: rgba(255, 255, 255, .05);
  color: var(--sys-ink-dim);
  font: 600 20px/1 inherit;
  cursor: pointer;
}
.sys-find-clear:hover { background: rgba(var(--sys-brass-rgb), .18); color: var(--sys-ink); }
.sys-find-clear[hidden] { display: none; }
.sys-find-key {
  flex: none;
  border: 0; background: none; padding: 0;
  cursor: pointer;
}
.sys-find-key kbd {
  display: inline-block;
  padding: 5px 9px;
  border-radius: 8px;
  border: 1px solid rgba(var(--sys-brass-rgb), .36);
  background: linear-gradient(180deg, rgba(var(--sys-brass-rgb), .16), rgba(0, 0, 0, .25));
  box-shadow: inset 0 1px 0 rgba(255, 233, 196, .14);
  color: #f0dfbc;
  font: 700 11px/1 inherit;
  font-family: inherit;   /* a <kbd> defaults to monospace; this is a chip, not code */
  letter-spacing: .08em;
}
.sys-find-key:hover kbd { border-color: rgba(var(--sys-ember-rgb), .6); color: var(--sys-ember-hi); }
.sys-find-hint {
  margin: 0;
  min-height: 1.2em;
  font-size: 12.5px;
  color: var(--sys-ink-mute);
  font-variant-numeric: tabular-nums;
}
.sys-find-hint b { color: var(--sys-ink-dim); font-weight: 600; }
.sys-find-hint.is-none { color: #ff9b86; }

/* ── the instrument cluster ──────────────────────────────────────────────── */

.sys-dials {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
  flex: none;
}
.sys-dial {
  --pct: 0;
  --tone: var(--sys-brass);
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 92px;
  padding: 10px 14px 10px 10px;
  border-radius: 16px;
  border: 1px solid var(--sys-line);
  background: linear-gradient(180deg, var(--sys-plate-2), var(--sys-plate));
  box-shadow: inset 0 1px 0 rgba(255, 238, 205, .05), 0 10px 26px rgba(0, 0, 0, .28);
  color: var(--sys-ink-dim);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .18s ease, transform .22s var(--sys-ease), box-shadow .22s ease, background .18s ease;
}
.sys-dial:hover { border-color: var(--sys-brass-dim); color: var(--sys-ink); transform: translateY(-2px); }
.sys-dial:focus-visible { outline: 2px solid var(--sys-ember); outline-offset: 3px; }
.sys-dial.active,
.sys-dial[aria-selected="true"] {
  color: var(--sys-ink);
  border-color: rgba(var(--sys-ember-rgb), .55);
  background:
    radial-gradient(260px 70px at 10% 0%, rgba(var(--sys-ember-rgb), .18), transparent 70%),
    linear-gradient(180deg, #3a2517, #2a1a12);
  box-shadow: inset 0 1px 0 rgba(255, 220, 180, .12), 0 0 26px rgba(var(--sys-ember-rgb), .16), 0 10px 26px rgba(0, 0, 0, .28);
}
.sys-dial[data-tone="bad"] { --tone: var(--sys-bad); }
.sys-dial[data-tone="off"] { --tone: #6b6152; }
.sys-dial[data-tone="good"] { --tone: var(--sys-good); }

.sys-dial-face {
  position: relative;
  flex: none;
  width: 72px; height: 72px;
  display: grid;
  place-items: center;
}
.sys-dial-arc { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sys-dial-track,
.sys-dial-fill {
  fill: none;
  stroke-width: 6;
  stroke-linecap: round;
}
.sys-dial-track { stroke: rgba(0, 0, 0, .55); }
.sys-dial-track { filter: drop-shadow(0 1px 0 rgba(var(--sys-brass-rgb), .14)); }
.sys-dial-fill {
  stroke: var(--tone);
  stroke-dasharray: 100;
  stroke-dashoffset: calc(100 - var(--pct));
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--tone) 55%, transparent));
  transition: stroke-dashoffset 1.1s var(--sys-ease), stroke .3s ease;
}
/* No reading yet: the arc is bare and the track says "instrument", not "zero". */
.sys-dial[data-tone="none"] .sys-dial-fill { opacity: 0; }
.sys-dial-ico {
  width: 44px; height: 44px;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .55));
  transition: transform .35s cubic-bezier(.3, 1.6, .5, 1);
}
.sys-dial:hover .sys-dial-ico { transform: scale(1.1) rotate(-5deg); }
.sys-dial.active .sys-dial-ico { filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .55)) drop-shadow(0 0 10px rgba(var(--sys-ember-rgb), .35)); }
.sys-dial-text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sys-dial-name {
  font-family: var(--sys-serif);
  font-size: 17px; font-weight: 600; line-height: 1.2;
  color: #f3e9d6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sys-dial-read {
  font-size: 12px; line-height: 1.35;
  color: var(--sys-ink-mute);
  font-variant-numeric: tabular-nums;
  text-wrap: pretty;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sys-dial.active .sys-dial-read { color: var(--sys-ember-hi); }
.sys-dial[data-tone="bad"] .sys-dial-read { color: #ff9b86; }
/* The dial that matches the search gets a count stamped on its face. */
.sys-dial-hits {
  position: absolute;
  top: -7px; right: 10px;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid rgba(var(--sys-ember-rgb), .6);
  background: #2a1a12;
  color: var(--sys-ember-hi);
  font: 700 10.5px/1 inherit;
  letter-spacing: .04em;
}
.sys-dial-hits[hidden] { display: none; }

/* ── the rooms ───────────────────────────────────────────────────────────── */

.sys-rooms { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; }
.sys-room {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-width: 0;
}
.sys-room[hidden] { display: none; }
html.sys-motion .sys-room.is-entering { animation: sys-room-in .46s var(--sys-ease) both; }
@keyframes sys-room-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
/* The People room pads itself (admin.css); the shell's gap is its margin. */
#ustore-pane-people.sys-room { gap: 0; }
/* The room heads: one title size for every room, one brass rule under each. */
.sys .ustore-title,
.sys .autoh-title {
  font-family: var(--sys-serif);
  font-size: clamp(24px, 2.6vw, 32px);
}
.sys .ustore-head,
.sys .autoh-head { margin-bottom: 0; }

/* "Nothing matches" — one line, the same in every room. */
.sys-nomatch {
  margin: 0;
  padding: 26px 18px;
  border-radius: 14px;
  border: 1px dashed rgba(var(--sys-brass-rgb), .3);
  text-align: center;
  color: var(--sys-ink-dim);
  font-size: 14px;
  line-height: 1.5;
}
.sys-nomatch b { color: #f3e9d6; }
.sys-nomatch.hidden { display: none; }

/* A storage row that matches by what is INSIDE it says how many — the row's
   own words may not contain the search at all. */
.sys-match-n {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid rgba(var(--sys-ember-rgb), .5);
  background: rgba(var(--sys-ember-rgb), .12);
  color: var(--sys-ember-hi);
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  vertical-align: middle;
}
/* The words the search hit, lit in ember wherever a room marks them. */
.sys-hit-word {
  background: rgba(var(--sys-ember-rgb), .22);
  color: #ffe2bf;
  border-radius: 3px;
  padding: 0 1px;
}

/* Landing on something from the palette: a ring of ember that fades. */
html.sys-motion .sys-hit { animation: sys-hit 1.8s ease-out both; }
.sys-hit:not(html.sys-motion *) { box-shadow: 0 0 0 2px var(--sys-ember); }
@keyframes sys-hit {
  0%   { box-shadow: 0 0 0 0 rgba(var(--sys-ember-rgb), .95), 0 0 36px rgba(var(--sys-ember-rgb), .5); }
  40%  { box-shadow: 0 0 0 3px rgba(var(--sys-ember-rgb), .9), 0 0 28px rgba(var(--sys-ember-rgb), .35); }
  100% { box-shadow: 0 0 0 0 rgba(var(--sys-ember-rgb), 0), 0 0 0 rgba(var(--sys-ember-rgb), 0); }
}

/* ── scroll reveals: each room's furniture arrives in its own way ────────── */
/* Only under html.sys-motion. Everything below is a *starting* state that the
   observer lifts by adding .is-seen; without the class the furniture stays put. */

/* Storage: planks slide in from the shelf's left edge, and each plank's bar
   grows to its length once the plank is on the wall. */
html.sys-motion .ustore-rows > li { transition: opacity .5s ease, transform .6s var(--sys-ease); transition-delay: calc(var(--i, 0) * 40ms); }
html.sys-motion .ustore-rows > li:not(.is-seen) { opacity: 0; transform: translateX(-22px); }
html.sys-motion .ustore-bar-fill { transition: width .9s var(--sys-ease); transition-delay: calc(var(--i, 0) * 40ms + .12s); }
html.sys-motion .ustore-rows > li:not(.is-seen) .ustore-bar-fill { width: 0 !important; }
/* The drive gauge fills in from the left, its figures count in a beat later. */
html.sys-motion .ustore-seg { transition: flex-basis 1s var(--sys-ease); }
html.sys-motion .ustore-drive:not(.is-seen) .ustore-seg { flex-basis: 0 !important; }
html.sys-motion .ustore-drive:not(.is-seen) .ustore-seg:last-child { flex-basis: 100% !important; }
html.sys-motion .ustore-fig { transition: opacity .5s ease, transform .6s var(--sys-ease); transition-delay: calc(var(--i, 0) * 90ms); }
html.sys-motion .ustore-drive:not(.is-seen) .ustore-fig { opacity: 0; transform: translateY(10px); }
html.sys-motion .ustore-sweep { transition: opacity .5s ease, transform .6s var(--sys-ease); }
html.sys-motion .ustore-sweep:not(.is-seen) { opacity: 0; transform: translateY(16px); }
/* Automations: plates rise onto the wall, a beat apart. */
html.sys-motion .autoh-card { transition: opacity .45s ease, transform .6s var(--sys-ease); transition-delay: calc(var(--i, 0) * 55ms); }
html.sys-motion .autoh-card:not(.is-seen) { opacity: 0; transform: translateY(18px) scale(.985); }
html.sys-motion .autoh-rail-fill { transition: width .9s var(--sys-ease); transition-delay: calc(var(--i, 0) * 55ms + .15s); }
html.sys-motion .autoh-card:not(.is-seen) .autoh-rail-fill { width: 0 !important; }
html.sys-motion .autoh-alarm { transition: opacity .5s ease, transform .6s var(--sys-ease); }
html.sys-motion .autoh-alarm:not(.is-seen):not(.hidden) { opacity: 0; transform: translateY(-10px); }
/* People: plates settle in from slightly larger, the hero band first. */
html.sys-motion .pp-plate { transition: opacity .45s ease, transform .55s var(--sys-ease); transition-delay: calc(var(--i, 0) * 45ms); transform-origin: 50% 100%; }
html.sys-motion .pp-plate:not(.is-seen) { opacity: 0; transform: scale(.96) translateY(8px); }
html.sys-motion .pp-hero { transition: opacity .5s ease, transform .6s var(--sys-ease); }
html.sys-motion .pp-hero:not(.is-seen) { opacity: 0; transform: translateY(-8px); }
/* Server setup: connection folders slide in from the right, one after another. */
html.sys-motion .setup-connection { transition: opacity .45s ease, transform .55s var(--sys-ease); transition-delay: calc(var(--i, 0) * 45ms); }
html.sys-motion .setup-connection:not(.is-seen) { opacity: 0; transform: translateX(18px); }
html.sys-motion .setup-folder { transition: opacity .45s ease, transform .55s var(--sys-ease); transition-delay: calc(var(--i, 0) * 45ms); }
html.sys-motion .setup-folder:not(.is-seen) { opacity: 0; transform: translateX(-14px); }

/* A room that has already made its entrance repaints at rest: systems.js
   marks the new nodes seen and holds their transitions off for two frames, so
   a search keystroke or a library opened never replays the slide-in. */
html.sys-motion .sys-still,
html.sys-motion .sys-still * { transition: none !important; }

/* ── the finder's scope chip (the palette itself is media/dock.css .hqp-*) ── */
.sys-finder .hqp-scope { color: #fde7c0; }
.sys-finder .hqp-row .hdock-ico { width: 22px; height: 22px; }
.sys-finder .hqp-face img { border-radius: 50%; }

/* ── phone ───────────────────────────────────────────────────────────────── */

@media (max-width: 980px) {
  .sys-mast { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .sys-ring, .sys-ember { right: -10%; }
  .sys-dials { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .sys .sys-scroll { padding: 0 16px 56px; gap: 18px; }
  .sys-mast { padding: 20px 16px 16px; gap: 14px; margin: 0 -16px; }
  .sys-brand { gap: 12px; }
  .sys-mark { width: 48px; height: 48px; }
  .sys-ring { width: 240px; height: 240px; margin: -120px -120px 0 0; top: 20%; }
  .sys-ring.r2 { width: 340px; height: 340px; margin: -170px -170px 0 0; }
  .sys-ring.r3 { width: 460px; height: 460px; margin: -230px -230px 0 0; }
  .sys-ember { width: 140px; height: 140px; margin: -70px -70px 0 0; top: 20%; }
  .sys-find-key { display: none; }   /* no keyboard: the box itself is the finder */
  .sys-dials { gap: 8px; }
  .sys-dial { min-height: 76px; padding: 8px 10px 8px 8px; gap: 9px; border-radius: 13px; }
  .sys-dial-face { width: 56px; height: 56px; }
  .sys-dial-ico { width: 34px; height: 34px; }
  /* Two lines rather than "People & s…": the name is the whole label here. */
  .sys-dial-name { font-size: 15px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .sys-dial-read { font-size: 11.5px; -webkit-line-clamp: 2; }
  .sys-dial-hits { right: 6px; }
}
@media (max-width: 380px) {
  .sys-dial-read { display: none; }
  .sys-dial { min-height: 64px; }
}

@media (prefers-reduced-motion: reduce) {
  .sys-dial, .sys-dial-ico, .sys-dial-fill, .sys-find-box { transition: none; }
  .sys-ring, .sys-ember { animation: none; }
}
