/* ==========================================================================
   EVAL · settings.css — the inside of the Settings curtain (Look, Feel, Store,
   Objectives, Closing targets, Owners, People, Assistant, Data, Email, About).
   Owner: settings agent.

   The chassis is the engine's: .curtain / .band / .pulltab / .curtain-body
   draw the chrome, the scrim and the dismissal. This file styles only what
   sits inside the body. Tokens only, primitives only — no ad-hoc colors,
   no parallel card.

   Eleven groups do not fit one screen, so the body scrolls (the head and its
   one answer pill are sticky) and the two long lists — the people directory
   and the reports EVAL reads — scroll inside their own cards. A list that
   scrolls in place is how the form stays a ladder of calm groups instead of a
   mile of rows.
   ========================================================================== */

/* ---------- the sticky head: who this is for, and the one answer -------- */
/* The saved pill lives here, so a commit made at the bottom of the list is
   still answered on screen. The ::before covers the body's own padding, where
   a row would otherwise slide past un-covered. */
.set-head {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 6px; background: var(--card);
}
.set-head::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 100%;
  height: 22px; background: var(--card);
}
/* the cut under the head is drawn, not left ragged: a row passing beneath it
   dissolves instead of being sliced through the middle of its letters. The
   band sits in the gap below the head, so nothing is washed when unscrolled. */
.set-head::after {
  content: ''; position: absolute; left: 0; right: 0; top: 100%;
  height: 14px; pointer-events: none;
  background: linear-gradient(to bottom, var(--card), transparent);
}
.set-head + .setsec { margin-top: 14px; }
/* the pane switcher rides with the head: the answer pill and the way through the
   window are one sticky block, so neither scrolls out from under the GM */
.setnav { position: sticky; top: 40px; z-index: 3; margin-top: 10px; }
.setnav + .setsec { margin-top: 16px; }
.setnav button { padding: 0 4px; }
.set-head h2 {
  font-family: var(--font-head); font-size: var(--fs-h1); font-weight: 800;
  letter-spacing: var(--ls-tight); line-height: var(--lh-tight); color: var(--ink);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.set-head .sp { flex: 1; min-width: 8px; }
.set-head.anon .avatar { display: none; }

/* ---------- one section: its head and its group ------------------------- */
.setsec + .setsec { margin-top: 18px; }
.setgroup { display: flex; flex-direction: column; gap: 8px; margin-top: 9px; }

/* Light / Dark / Auto is one control, not a banner: on the panel it keeps the
   width three words need and lets the group breathe beside it. */
@media (min-width: 1000px) {
  .setgroup.look .seg { max-width: 420px; }
}
/* …the switcher is the width of the window, because it IS the window's spine — and it
   is a DIFFERENT SPECIES from a value switcher. Navigation and a stored value were the
   same control 60px apart: a grey track with the active segment filled by the purple
   gradient, one of them moving the GM between panes and one of them setting the theme.
   A GM taps the wrong one. The pane row is text tabs with an underline on the active
   one; the filled pill stays with the VALUE, where the fill means "this is what is
   set". */
.setnav.seg {
  max-width: none; gap: 2px; padding: 0 0 2px;
  background: none; border: 0; border-bottom: 1px solid var(--line2); border-radius: 0;
}
.setnav.seg button {
  flex: 0 1 auto; min-width: 46px; padding: 0 13px; border-radius: 0;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.setnav.seg button.on {
  background: none; color: var(--purInk); box-shadow: none;
  border-bottom-color: var(--pur);
}
.setnav.seg button.on svg { opacity: 1; }

/* ---------- three-way segmented row (Light / Dark / Auto) --------------- */
.seg {
  display: flex; gap: 2px; padding: 3px; border-radius: var(--r-pill);
  background: var(--surf2); border: 1px solid var(--line2);
}
.seg button {
  flex: 1; min-width: 0; height: 44px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-head); font-size: var(--fs-label); font-weight: 700;
  letter-spacing: -.1px; color: var(--muted); white-space: nowrap;
  transition: color var(--dur-page) var(--ease), background-color var(--dur-page) var(--ease),
    transform var(--dur-liftUp) var(--ease);
}
.seg button svg { opacity: .75; }
.seg button.on { background: var(--grad); color: var(--onGrad); box-shadow: var(--glow); }
.seg button.on svg { opacity: 1; }

/* ---------- a row that is itself the control (the two toggles) ---------- */
.setrow {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  min-height: 56px; padding: 6px 12px 6px 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow); transition: transform var(--dur-liftUp) var(--ease);
}
.setrow .rl {
  flex: 1; min-width: 0; font-family: var(--font-head); font-size: var(--fs-h3);
  font-weight: 700; letter-spacing: -.2px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* the switch: a track + a knob, one look in both themes */
.sw {
  position: relative; flex: 0 0 auto; width: 46px; height: 28px;
  border-radius: var(--r-pill); background: var(--ghost);
  transition: background-color var(--dur-pill) var(--ease);
}
.sw > i {
  position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: var(--r-pill); background: var(--muted2); box-shadow: var(--shadow);
  transition: transform var(--dur-pill) var(--ease), background-color var(--dur-pill) var(--ease);
}
/* ON is the brand gradient, not green. Green in EVAL means a reading — Ahead,
   Verified, a ticked task — and this row already sets its active state in the
   gradient one control to the left (the Look segment), so a green switch beside
   a purple segment was two answers to "which one is on". The knob is the ink
   that sits on the gradient everywhere else in the family. */
.sw.on { background: var(--grad); }
.sw.on > i { background: var(--onGrad); transform: translateX(18px); }
/* only the OFF knob changes with the theme; the ON knob is --onGrad in both,
   because what it sits on is the same gradient in both */
html[data-theme="dark"] .sw:not(.on) > i { background: var(--muted); }

/* ---------- a fact, not a control (Reduced motion) ---------------------- */
/* Reduced motion is the system's switch (laws §3). It wears the quiet card and
   the kv primitive — no switch, no chevron, no shadow — so it can never be
   mistaken for the two toggles beside it. */
.set-fact { padding: 4px 14px; }
.set-fact .kv { min-height: 46px; }
.set-fact .kv .k { font-weight: 600; color: var(--ink2); }

/* ---------- fields ------------------------------------------------------ */
.fldgrid { display: grid; gap: 8px; grid-template-columns: 1fr; }
.fldgrid.g2 { grid-template-columns: repeat(2, 1fr); }
.fldgrid.g4 { grid-template-columns: repeat(4, 1fr); }
/* four roles: two up on the phone, four across on the panel. The row gap is
   wider than the 5px a label keeps from its own field, so a label always reads
   as belonging to the box under it, never to the box above. */
.fldgrid.gsplit { grid-template-columns: repeat(2, 1fr); row-gap: 15px; }
@media (min-width: 1000px) { .fldgrid.gsplit { grid-template-columns: repeat(4, 1fr); } }

.fld { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.fld .fl {
  font-size: var(--fs-pill); font-weight: 700; color: var(--muted);
  letter-spacing: .2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fi {
  width: 100%; height: 44px; padding: 0 12px; border-radius: var(--r-sm);
  background: var(--surf); border: 1px solid var(--line); outline: none;
  font-family: var(--font-head); font-size: var(--fs-h3); font-weight: 700;
  letter-spacing: -.2px; color: var(--ink); min-width: 0;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease);
}
.fi.n { text-align: center; padding: 0 6px; font-size: var(--fs-h2); font-weight: 800; letter-spacing: -.5px; }
.fi:focus { border-color: var(--pur); background: var(--card); }
.fi::placeholder { color: var(--muted2); font-weight: 600; }

/* ---------- a list that scrolls inside its own card -------------------- */
/* One screen of form, lists scrolling in place. overscroll-behavior keeps a
   flick inside the list from dragging the curtain body with it. */
.set-scroll {
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.set-scroll .row { min-height: 40px; padding: 5px 0; }
/* "there is more below", said the way the assistant's thread says it: the last
   row dissolves instead of being sliced. The flag is set only while the list
   really is scrolled short of its end (settings.js), so nothing is dimmed that
   the GM has already reached. The mask reads alpha, so the token in it is doing
   the job of opaque, not the job of a colour. */
/* …the mask itself is the family's, on [data-more="1"] in components.css since
   round 2.1, so the people directory and Home's follow-ups dissolve identically. */

/* ---------- People: the directory --------------------------------------
   The cap is the PANEL's, not a number. A fixed 300/236px showed 2 of 11 people
   on the phone and 3 of 11 on the iPad while up to 500px of the same panel sat
   empty below "Add person" — and this is the one list a GM has to fill in to
   delegate anything, so it gets the window's slack. Both curtain heights are
   known (iPad: 100vh − 40px of inset − the 40px band; phone: 92vh − the band),
   and everything above and below this list in the People pane is fixed, so the
   list takes what is left and stops ~15px short of the floor. */
.set-people {
  max-height: calc(92vh - 290px);
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px; border-radius: var(--r-md);
  background: var(--surf); border: 1px solid var(--line2);
}
@media (min-width: 1000px) { .set-people { max-height: calc(100vh - 336px); } }

/* A directory row's three cells carry a pixel of headroom over the 44px law.
   Inside a transformed surface (the curtain is a translated layer) a box laid
   out at exactly 44 can measure back as 43.99994 — one part in 16384 of Chrome's
   layout float — and thirty-three cells is thirty-three chances to land on that
   fraction. The pixel is real geometry, not a declared `data-hit` crutch. */
.set-people .fi { height: 45px; }

.prow {
  display: grid; gap: 8px; align-items: center; min-width: 0;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  grid-template-areas:
    'pn pn rm'
    'rl em em';
}
.prow + .prow { border-top: 1px solid var(--line2); padding-top: 8px; }
/* the mark and the name are one thing: whose row this is */
.prow .pn { grid-area: pn; display: flex; align-items: center; gap: 8px; min-width: 0; }
.prow .fi[data-k$="_role"] { grid-area: rl; }
.prow .fi[data-k$="_email"] { grid-area: em; }
.prow .pill { grid-area: rm; justify-self: end; }

@media (min-width: 1000px) {
  .prow {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, .8fr) minmax(0, 1.3fr) auto;
    grid-template-areas: 'pn rl em rm';
  }
}

/* ---------- Assistant -------------------------------------------------- */
.set-assist { gap: 9px; padding: 13px 14px; }
.set-assist .al { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.set-assist .al .sp { flex: 1; min-width: 8px; }
.set-assist .av {
  min-width: 0; font-family: var(--font-head); font-size: var(--fs-h3); font-weight: 700;
  letter-spacing: -.2px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* the reports a test answer actually read — the same receipt the assistant
   prints under an answer, in the app's own type, never mono */
.set-src {
  font-size: var(--fs-sub); font-weight: 500; color: var(--muted);
  line-height: 1.35; overflow: hidden; text-overflow: ellipsis;
}
.set-src .lb { font-weight: 700; color: var(--muted2); }

/* ---------- the data row ------------------------------------------------ */
.setdata { gap: 10px; }
.setdata .dl { display: flex; align-items: center; gap: 10px; min-width: 0; }
.setdata .dt {
  flex: 1; min-width: 0; font-family: var(--font-head); font-size: var(--fs-h3);
  font-weight: 700; letter-spacing: -.2px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* phone: the action fills the card under the reading. iPad: it sits beside it. */
.setdata .btn { align-self: stretch; }
@media (min-width: 1000px) {
  .setdata { flex-direction: row; align-items: center; }
  .setdata .dl { flex: 1; }
  .setdata .btn { align-self: auto; }
}

/* the server the figures came from: a long URL ends in an ellipsis rather than
   pushing its own card past the edge of the panel */
.set-srv, .set-mail, .set-about { padding: 4px 14px; }
.set-srv .kv .v, .set-mail .kv .v {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--fs-row); font-weight: 700;
}
.set-srv .kv, .set-mail .kv { min-height: 46px; }

/* ---------- About: the reports EVAL reads ------------------------------ */
/* The pixel guess is gone. `calc(92vh − 500px)` / `calc(100vh − 511px)` was an
   arithmetic of everything that happens to sit above this list, which is a number
   no stylesheet can know and which drifts the moment a row above it changes: it
   drew 7 of 15 reports and left 214px (iPad) / 246px (phone) of empty panel under
   a list that was still scrolling — the same void the People directory was given
   the panel's height to close, measured by 45-fit-and-voids.
   Now the pane ASKS (settings.js marks the About section `.grow` and paintPane
   turns the body into the family's `.curtain-body.fill` column for it), and this
   is the chain that carries the slack from the panel down to the scroller: the
   section, the group, the card and the list each pass it on, every one of them
   `min-height: 0` so a flex item cannot refuse to shrink below its content. The
   list is the only thing that grows; the Dataset row above it does not stretch. */
.curtain-body.fill > .setsec.grow { display: flex; flex-direction: column; }
.curtain-body.fill > .setsec.grow > .setgroup { flex: 1 1 auto; min-height: 0; }
.curtain-body.fill > .setsec.grow .set-about { flex: 1 1 auto; min-height: 0; }
.curtain-body.fill > .setsec.grow .set-about > .kv { flex: 0 0 auto; }
.curtain-body.fill > .setsec.grow .set-about > .set-scroll { flex: 1 1 auto; }
/* …and when the dataset has not landed, the designed empty holds the pane rather
   than sitting in the top inch of it (laws §16: an empty state is designed). */
.curtain-body.fill > .setsec.grow > .setgroup > .empty { flex: 1 1 auto; min-height: 0; }

.set-about .set-scroll {
  min-height: 0; margin-top: 2px;
  border-top: 1px solid var(--line2);
}
.set-about .row .tt { font-weight: 700; }
.set-about .row .who { font-family: var(--font-head); font-weight: 700; color: var(--ink); }

/* ---------- the remove pop-up ------------------------------------------ */
.set-rm { display: flex; align-items: center; gap: 11px; min-width: 0; padding: 2px 0 6px; }
.set-rm .rn {
  flex: 1; min-width: 0; font-family: var(--font-head); font-size: var(--fs-h2);
  font-weight: 800; letter-spacing: var(--ls-head); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---------- the saved pill, riding the sticky head ---------------------- */
.setsaved {
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-pill) var(--ease);
}
.setsaved.on { opacity: 1; }
