/* RULE SETS — the family-level object a parent actually edits.
 *
 * THE SYMPTOM THIS STYLESHEET IS PART OF THE ANSWER TO, in the owner's words:
 * "you start making rules but then find sometimes theres a family rule level
 * but you click them and wind up on the kids page and dont know whats
 * happening".
 *
 * So the loudest thing on every screen here is not a control. It is
 * `.rs-level` — a banner that says WHICH LEVEL this is and WHO it reaches,
 * pinned to the top of both the list and the editor and repeated above every
 * tab panel's own scroll. Colour alone never carries that: each banner leads
 * with a word ("Family level" / "Rule set"), then the names.
 *
 * Vocabulary and tokens are app.css's; nothing here invents a colour. The
 * three states a row can be in reuse the product's meanings from
 * UI-DIRECTION-2026-08-22 §3 — cyan/blue trusted+primary, mint healthy/
 * applied, amber attention, coral destructive/paused.
 */

/* ---------------------------------------------------------------- the level
 *
 * ALWAYS VISIBLE, NEVER COLLAPSED, AND IT NAMES BOTH HALVES. A parent must be
 * able to answer "what am I editing" and "who does this reach" without
 * scrolling and without clicking anything.
 */
.rs-level {
  display: grid;
  gap: 6px;
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--glow);
  border-radius: var(--radius);
  background: var(--dusk2);
}

.rs-level-kicker {
  color: var(--glow);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.rs-level-name {
  margin: 0;
  color: var(--cloud);
  font-size: 19px;
  font-weight: 750;
  line-height: 1.25;
}

/* WHO IT REACHES. Never rendered empty: a set with no children says so in
 * words, because a blank line reads as "everyone" to the parent who is
 * worried it might be. */
.rs-level-who {
  margin: 0;
  color: var(--haze);
  font-size: 13px;
  line-height: 1.5;
}

.rs-level-who b {
  color: var(--cloud);
  font-weight: 700;
}

/* The one place this page raises its voice: a set nobody uses changes nothing
 * on any device, and a parent who has just spent ten minutes editing one is
 * entitled to know that before they close the tab. */
.rs-level.rs-level-unused {
  border-left-color: var(--amber);
}

.rs-level.rs-level-unused .rs-level-kicker {
  color: var(--waiting-text);
}

/* ------------------------------------------------------------------ the list */

.rs-list {
  display: grid;
  gap: 12px;
  margin: 16px 0 0;
}

.rs-card {
  display: grid;
  gap: 10px;
  padding: 16px;
}

.rs-card-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-width: 0;
}

.rs-card-name {
  margin: 0;
  color: var(--cloud);
  font-size: 17px;
  font-weight: 750;
  line-height: 1.3;
  min-width: 0;
  overflow-wrap: anywhere;
}

.rs-card-who {
  margin: 0;
  color: var(--haze);
  font-size: 13px;
  line-height: 1.5;
}

/* WHERE A COPY CAME FROM. rule_sets carries origin_set_id/origin_name/
 * origin_copied_at precisely so this sentence can be true about the moment of
 * copying even after the origin is renamed or deleted. */
.rs-card-origin {
  margin: 0;
  color: var(--haze);
  font-size: 12px;
  font-style: italic;
  line-height: 1.5;
}

.rs-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rs-count {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--haze);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.rs-count.rs-count-none {
  border-color: var(--amber);
  color: var(--waiting-text);
}

/* --------------------------------------------------------------- the editor */

.rs-back {
  margin: 0 0 12px;
}

.rs-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 18px 0 14px;
}

.rs-panel {
  display: grid;
  gap: 14px;
}

.rs-panel-lead {
  margin: 0;
  color: var(--haze);
  font-size: 13px;
  line-height: 1.55;
}

/* THE PRECEDENCE SENTENCE, and it is on every content panel rather than in one
 * place a parent may never scroll to. Owner-stated and true server-side:
 * store-postgres.js documents rung 1 as "parent rules — always wins", and a
 * rule set's app decisions are stamped `disposition_by = 'parent'` for exactly
 * that reason. */
.rs-precedence {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--mint);
  border-radius: 12px;
  background: var(--dusk2);
  color: var(--haze);
  font-size: 12px;
  line-height: 1.55;
}

.rs-rows {
  display: grid;
  gap: 8px;
}

.rs-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--dusk);
  min-width: 0;
}

.rs-row-main {
  display: grid;
  gap: 3px;
  min-width: 0;
}

/* THE FRIENDLY NAME IS THE PRIMARY LABEL, ALWAYS. UI-DIRECTION-2026-08-22 §4
 * rule 2: a parent is never asked to read a developer identifier to know what
 * an app is. */
.rs-row-name {
  color: var(--cloud);
  font-size: 14px;
  font-weight: 650;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

/* …AND THE IDENTIFIER IS MUTED SECONDARY DETAIL, which is the narrow amendment
 * PARITY-DECISIONS-2026-08-29 §9 makes for the Processes surface, where the
 * filename IS the identifying detail a parent is looking for. */
.rs-row-id {
  color: var(--haze);
  font-size: 12px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.rs-row-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ------------------------------------------------- the shared state segments
 *
 * ALLOW / BLOCK HERE IS THE SAME CONTROL IT IS EVERYWHERE ELSE, so it wears
 * css/policy-workspace.css's `.pw-state-control` / `.pw-state-option` and
 * inherits that file's 44px touch floor, its wrap-before-ellipsis label rule
 * and — the part that matters most — its MEASURED light-theme colours. Only
 * the two differences a rule set actually has are declared here.
 *
 * THE FIRST VERSION OF THIS FILE GOT THAT WRONG AND IT IS WORTH RECORDING:
 * it painted the selected segment as a solid `var(--mint)` / `var(--coral)`
 * fill with `var(--ink)` text. In dark mode that reads (bright fill, near-black
 * text). In LIGHT mode --mint is #13815C and --ink is #0A1020, which is about
 * 1.4:1 — dark green under near-black — on the control that decides whether a
 * child can open an app. The shared rules use a 13% tint with coloured text and
 * a darkened light-mode value for exactly that reason. */

/* TWO SEGMENTS, NOT THREE. The shared grid is three fixed tracks because every
 * surface using it offers Allow / Temporary / Block. A rule set has NO
 * Temporary — grants sit ABOVE the rule set and are per child — so its app,
 * program and category rows carry two segments; only its website rows, which
 * have a real third state (Ask), carry three. */
.rs-row .pw-state-control {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.rs-row .pw-state-control.rs-state-three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* ASK, IN THE AMBER THAT ALREADY MEANS ATTENTION (UI-DIRECTION §3), declared
 * beside its siblings' values rather than reusing `.pw-state-temporary` — that
 * class is the same colour and a different promise, and putting the word
 * "temporary" in the DOM for a rule that means "ask a parent" would make the
 * markup lie. The light-mode value is #7A4F00, the one policy-workspace.css
 * measured for amber text on this page's pale grounds. */
.pw-state-option.is-selected.pw-state-ask {
  border-color: var(--amber);
  background: color-mix(in srgb, var(--amber) 13%, transparent);
  color: var(--waiting-text);
}

:root[data-theme="light"] .pw-state-option.is-selected.pw-state-ask,
:root:not([data-theme]) .pw-state-option.is-selected.pw-state-ask {
  color: #7A4F00;
}

.rs-empty {
  margin: 0;
  padding: 18px 16px;
  border: 1px dashed var(--line);
  border-radius: 14px;
  color: var(--haze);
  font-size: 13px;
  line-height: 1.55;
  text-align: center;
}

/* ------------------------------------------------------------------- forms */

.rs-form {
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--dusk2);
}

.rs-form-title {
  margin: 0;
  color: var(--cloud);
  font-size: 13px;
  font-weight: 750;
  letter-spacing: .03em;
  text-transform: uppercase;
}

.rs-field {
  display: grid;
  gap: 5px;
  min-width: 0;
}

.rs-field-label {
  color: var(--haze);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.rs-field-note {
  color: var(--haze);
  font-size: 12px;
  line-height: 1.45;
}

.rs-form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  align-items: end;
}

.rs-form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rs-select {
  min-height: 40px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--dusk);
  color: var(--cloud);
  font-family: var(--ui);
  font-size: 14px;
  min-width: 0;
  width: 100%;
}

/* ------------------------------------------------------- children / members */

.rs-member {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--dusk);
}

.rs-member-name {
  color: var(--cloud);
  font-size: 14px;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.rs-member-note {
  color: var(--haze);
  font-size: 12px;
  line-height: 1.45;
}

/* MOVING IS THE ONLY WAY OUT, AND THE SCREEN SAYS SO BEFORE IT IS TRIED.
 * rule_set_members' PRIMARY KEY (profile_id) makes "one child, one rule set"
 * unrepresentable to break, and setRuleSetMembers REFUSES to drop a child
 * rather than leave them ruleless. That is a promise, not an error, so it is
 * stated up front in the same tone as the rest of the panel. */
.rs-move-note {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--amber);
  border-radius: 12px;
  color: var(--haze);
  font-size: 12px;
  line-height: 1.55;
}

/* ------------------------------------------------------------------ the band
 *
 * The doorway on the Kids screen. It is the family level offered ABOVE the
 * children, in that order, because the object is above them in the model too. */
.rs-band {
  display: grid;
  gap: 8px;
  margin: 0 0 18px;
  padding: 16px;
}

.rs-band-title {
  margin: 0;
  color: var(--cloud);
  font-size: 15px;
  font-weight: 750;
}

.rs-band-sub {
  margin: 0;
  color: var(--haze);
  font-size: 13px;
  line-height: 1.55;
}

.rs-band-action {
  justify-self: start;
}

/* ------------------------------------------------------------------- phones
 *
 * 320px is the floor this product designs to (iphone-se-floor.test.js). Every
 * two-column row above becomes a stack rather than being squeezed, and no
 * control drops below the 44px touch target. */
@media (max-width: 560px) {
  .rs-row,
  .rs-member {
    grid-template-columns: minmax(0, 1fr);
  }

  .rs-row-actions {
    justify-content: flex-start;
  }

  .rs-card-actions > .btn-rs,
  .rs-form-actions > .btn-rs {
    flex: 1 1 auto;
    min-height: 44px;
  }
}

/* A shared minimum for every button this surface builds, so the phone rule
 * above has one selector to reach and a desktop control is never smaller than
 * the text it holds. */
.btn-rs {
  min-height: 38px;
}
