/* app/set-prefs.css — page-local styles for Preferences + Profile.
   ============================================================================================
   Prefix every selector `.e8-set-prefs-`. Shared grammar lives in app/set-core.css and must not
   be duplicated here; if a page needs a new shared primitive, that is a core change, not a
   local override. Tokens only — no hex, no raw font sizes.

   WHAT IS AND IS NOT IN THIS FILE. Nothing here is a row, a card, a divider or a control: those
   are set-core's, and a page that redefines one is exactly how 20 pages drift apart. Everything
   below is the INSIDE of one control cell (the accent grid, the avatar chip) or a full-width
   strip that sits in a card as its own child (the readout, the MFA pairing block) and
   therefore inherits set-core's inset divider for free.

   Two measurements are deliberately borrowed rather than restated: `--set-card-pad-x` and
   `--set-row-pad-y` are declared on `.e8-set` and inherit down here, so the strips line up with
   the rows above them and keep lining up if core changes the rhythm. Tints reuse `--set-tint`
   for the same reason — a second, nearly-identical mix is how one card ends up a shade off its
   neighbour.

   CASCADE ORDER. Every conditional at-rule is at the BOTTOM, after the unconditional rules it
   narrows. A @media above its own base rule adds no specificity and can never win; that has
   shipped in this repo three times. Note also that `scripts/check-cascade.mjs` and
   `check-hardcoded-colors.mjs` only read `app/app.css` — they do NOT cover this file — so both
   rules are held by hand here rather than by a gate.
   ============================================================================================ */

/* ---------- visually hidden, but spoken -----------------------------------------------------
   Two callers now: the icon-only pencil on Profile, and the word the currency readout's arrow
   stands for. Kept here rather than beside either of them because it belongs to neither. */
.e8-set-prefs-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
  border: 0;
  clip-path: inset(50%);
}

/* ---------- accent swatch grid ----------------------------------------------------------------
   The selected ring is NEUTRAL, not accent: the selected swatch already IS the accent colour, so
   an accent ring around it is invisible at exactly the moment it has to be read. */
.e8-set-prefs-accents {
  display: inline-flex;
  align-items: center;
  gap: var(--ui-space-3);
}
.e8-set-prefs-accent-name {
  flex: none;
  min-width: 62px;
  text-align: right;
  font-size: var(--ui-text-base);
  color: var(--ui-text-secondary);
}
.e8-set-prefs-accent-row {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.e8-set-prefs-accent {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--ui-radius-pill);
  background: transparent;
  cursor: pointer;
}
.e8-set-prefs-accent:hover { border-color: var(--ui-border-strong); }
.e8-set-prefs-accent.is-on { border-color: color-mix(in srgb, var(--ui-text) 55%, transparent); }
/* set-core's one focus rule rounds every ring to 6px, which reads as a square on a 26px circle. */
.e8-set-prefs-accent:focus-visible { border-radius: var(--ui-radius-pill); }
.e8-set-prefs-accent-dot {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  /* The swatch paints an arbitrary brand colour, including near-white ones in a light theme, so
     it carries its own hairline rather than trusting contrast against the card. */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-text) 16%, transparent);
  transition: width 120ms ease, height 120ms ease;
}
.e8-set-prefs-accent.is-on .e8-set-prefs-accent-dot {
  width: 14px;
  height: 14px;
}

/* ---------- the readout strip -------------------------------------------------------------------
   THE page's only "here is what this setting does" device, used three times: the currency example
   on General, the timestamp preview on Time Display, the loaded record counts on Workspace and
   Data. It replaced a second grammar for the same job — a left-ruled example block that lived
   inside `.e8-set-row-desc` — because two devices 400px apart is what makes a surface read as
   several authors, and this is the stronger of the two: it is a card-level primitive rather than a
   decoration on one row's prose.

   A card CHILD, not a row: it gets set-core's inset hairline above it automatically, and it is
   tinted so it reads as an OUTPUT of the rows above rather than one more setting. It borrows
   `--set-card-pad-x` and `--set-tint` from `.e8-set` rather than restating either, so it stays
   aligned with the rows and the same shade as every other tinted strip on the surface. */
.e8-set-prefs-readout {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ui-space-2) var(--ui-space-4);
  padding: 13px var(--set-card-pad-x);
  background: var(--set-tint);
}
.e8-set-prefs-readout-cap {
  flex: none;
  font-size: var(--ui-text-sm);
  font-weight: 500;
  color: var(--ui-text-tertiary);
}
/* Monospaced with tabular figures on purpose: every one of the three re-renders as you change the
   control above it, and proportional digits make the line jitter while you scrub a select. */
.e8-set-prefs-readout-line {
  flex: 1;
  min-width: 0;
  font-family: var(--ui-font-mono);
  font-size: var(--ui-text-base);
  font-variant-numeric: tabular-nums;
  color: var(--ui-text);
}
.e8-set-prefs-sep,
.e8-set-prefs-arrow {
  padding: 0 6px;
  color: var(--ui-text-tertiary);
}
.e8-set-prefs-week {
  flex: none;
  display: inline-flex;
  gap: 3px;
}
.e8-set-prefs-week > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 20px;
  border-radius: var(--ui-radius-sm);
  background: var(--ui-fill);
  font-size: var(--ui-text-xs);
  font-weight: 500;
  color: var(--ui-text-secondary);
}
.e8-set-prefs-week > span.is-first {
  background: color-mix(in srgb, var(--ui-accent) 16%, transparent);
  color: var(--ui-accent);
}

/* ---------- profile picture cell ---------------------------------------------------------------- */
.e8-set-prefs-avatarwrap {
  display: inline-flex;
  align-items: center;
  gap: var(--ui-space-3);
}
.e8-set-prefs-avatar {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  overflow: hidden;
  border-radius: var(--ui-radius-pill);
  border: 1px solid color-mix(in srgb, var(--ui-accent) 24%, transparent);
  background: color-mix(in srgb, var(--ui-accent) 12%, transparent);
  font-size: var(--ui-text-md);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ui-accent);
}
.e8-set-prefs-avatar-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* The pencil is the only `is-secondary` button in this cell (Remove is `is-quiet`), so this
   narrows the icon-only button to a square without touching the labelled one beside it. */
.e8-set-prefs-avatarwrap .e8-set-btn.is-secondary { padding: 0 9px; }
/* `display:none` is safe here: a programmatic .click() still opens the picker, and it keeps the
   input out of the tab order and the accessibility tree in every browser. */
.e8-set-prefs-file { display: none; }

/* ---------- authenticator pairing block ---------------------------------------------------------
   Another card child, tinted the same way as the preview strip so the two read as one grammar. */
.e8-set-prefs-mfa {
  padding: var(--set-row-pad-y) var(--set-card-pad-x);
  background: var(--set-tint);
}
.e8-set-prefs-mfa-t {
  font-size: var(--ui-text-md);
  font-weight: 500;
  color: var(--ui-text);
}
.e8-set-prefs-mfa-steps {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: var(--ui-text-base);
  line-height: 1.5;
  color: var(--ui-text-secondary);
}
.e8-set-prefs-key {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--ui-space-2);
  margin-top: var(--ui-space-3);
  padding: 7px 8px 7px 12px;
  border: 1px dashed var(--ui-border-strong);
  border-radius: var(--ui-radius-md);
  background: var(--ui-surface);
}
.e8-set-prefs-key code {
  flex: 1;
  min-width: 0;
  font-family: var(--ui-font-mono);
  font-size: var(--ui-text-base);
  letter-spacing: 0.1em;
  word-break: break-word;
  color: var(--ui-text);
}
.e8-set-prefs-mfa-act {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--ui-space-2);
  margin-top: var(--ui-space-3);
}
.e8-set-prefs-mfa-act .e8-set-input input {
  font-family: var(--ui-font-mono);
  letter-spacing: 0.18em;
}
.e8-set-prefs-err {
  margin-top: var(--ui-space-2);
  font-size: var(--ui-text-base);
  color: var(--ui-danger-text);
}

/* ---------- narrow -----------------------------------------------------------------------------
   AFTER every rule above, for the reason in the header. Breakpoints are 840 and 640 only; nothing
   here needs 840, because at 840 the content column is still wide enough for every cell to keep
   its desktop shape — it is 640, where set-core stacks the control under the label and gives it
   `width: 100%`, that these cells stop being right-aligned and have to re-flow. */
@media (max-width: 640px) {
  .e8-set-prefs-accents {
    flex-wrap: wrap;
    gap: var(--ui-space-2);
  }
  .e8-set-prefs-accent-name {
    min-width: 0;
    text-align: left;
  }
  .e8-set-prefs-avatarwrap { flex-wrap: wrap; }
  .e8-set-prefs-readout { align-items: flex-start; }
  .e8-set-prefs-readout-line {
    flex: none;
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .e8-set-prefs-accent-dot { transition: none; }
}

/* The parenthetical beside "Table row shading". A wink, not a state: tertiary ink at the label's own
   size so it never competes with the setting name it trails. */
.e8-set-prefs-wink { font-weight: 400; color: var(--ui-text-tertiary); letter-spacing: 0.01em; }
