/* Pattern detail (V4) and the preview stage.
 *
 * The preview stage is the reason this file exists. A curator judging
 * orchestration from JSON is judging the wrong artefact, so the rendered
 * pattern gets the most space and the first tab.
 */

/* ---- pattern: entity-detail-tabbed --------------------------------------- */

.detail-head {
  display: flex; align-items: flex-start; gap: 14px;
  padding-bottom: 14px; margin-bottom: 0;
  border-bottom: 1px solid var(--border);
}
.detail-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.detail-meta {
  display: flex; gap: 7px; flex-wrap: wrap; align-items: center;
  margin-top: 5px; font-size: 12.5px; color: var(--text-faint);
}
.detail-actions { margin-inline-start: auto; display: flex; gap: 7px; flex: none; }

.back-link {
  display: inline-flex; align-items: center; gap: 5px;
  margin-bottom: 12px; padding: 0;
  font: inherit; font-size: 13px; color: var(--text-dim);
  background: none; border: none; cursor: pointer;
}
.back-link:hover { color: var(--accent); }

.tablist {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
  overflow-x: auto;
}
.tab {
  padding: 9px 13px;
  font: inherit; font-size: 13px; font-weight: 540;
  color: var(--text-dim);
  background: none; border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); }

/* ---- pattern: pattern-preview-stage -------------------------------------- */

.stage-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius) var(--radius) 0 0;
  border-bottom: none;
}
.stage-group {
  display: flex; align-items: center; gap: 1px;
  padding: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.stage-group-label {
  font-size: 10.5px; font-weight: 640; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-faint);
  margin-inline-end: 2px;
}
.stage-opt {
  padding: 3px 9px;
  font: inherit; font-size: 12px; font-weight: 520;
  color: var(--text-dim);
  background: none; border: none; border-radius: 3px;
  cursor: pointer; white-space: nowrap;
}
.stage-opt:hover { color: var(--text); background: var(--surface-2); }
.stage-opt[aria-pressed="true"] { background: var(--accent); color: var(--accent-text); }

/* The preview renders in its OWN theme context. Without this the host
   application's CSS silently makes every pattern look correct — the exact
   failure the stage exists to prevent. */
.stage-frame {
  min-height: 300px;
  padding: 26px;
  border: 1px solid var(--border);
  border-radius: 0 0 var(--radius) var(--radius);
  overflow-x: auto;

  --p-bg: #ffffff;
  --p-surface: #f7f8fa;
  --p-border: #e3e5ea;
  --p-text: #1a1d24;
  --p-dim: #666d7e;
  --p-accent: #3b5bdb;
  background: var(--p-bg);
  color: var(--p-text);
}
.stage-frame[data-preview-theme="dark"] {
  --p-bg: #14161c;
  --p-surface: #1e212a;
  --p-border: #2f3441;
  --p-text: #e8eaf0;
  --p-dim: #98a0b2;
  --p-accent: #7391ff;
}

.stage-note {
  display: flex; align-items: flex-start; gap: 7px;
  margin-top: 10px; padding: 9px 12px;
  font-size: 12.5px; color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

/* Miniature renderings of the seed patterns, drawn with preview-scoped tokens
   so they respond to the stage's theme rather than the application's. */
.pv { font-family: var(--sans); font-size: 13px; }
.pv-row { display: flex; gap: 8px; align-items: center; }
.pv-box {
  background: var(--p-surface);
  border: 1px solid var(--p-border);
  border-radius: 6px;
}
.pv-bar { height: 9px; border-radius: 3px; background: var(--p-border); }
.pv-shell { display: grid; grid-template-columns: 118px 1fr; gap: 10px; height: 200px; }
.pv-side { padding: 11px; display: flex; flex-direction: column; gap: 7px; }
.pv-main { display: flex; flex-direction: column; gap: 10px; }
.pv-head { height: 34px; display: flex; align-items: center; padding: 0 11px; gap: 8px; }
.pv-body { flex: 1; padding: 12px; }
.pv-nav-item { height: 8px; border-radius: 3px; background: var(--p-border); }
.pv-nav-item.on { background: var(--p-accent); }
.pv-th { display: flex; gap: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--p-border); }
.pv-td { display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--p-border); }
.pv-empty { display: grid; place-items: center; gap: 6px; padding: 34px 16px; text-align: center; }
.pv-dim { color: var(--p-dim); font-size: 12px; }
.pv-btn {
  padding: 5px 11px; font-size: 12px; font-weight: 550; border-radius: 5px;
  background: var(--p-accent); color: #fff; border: none;
}
.pv-btn.ghost { background: transparent; color: var(--p-dim); border: 1px solid var(--p-border); }
.pv-dialog {
  max-width: 350px; margin: 22px auto; padding: 18px;
  background: var(--p-bg); border: 1px solid var(--p-border);
  border-radius: 9px; box-shadow: 0 12px 34px rgb(0 0 0 / 22%);
}
/* expandable-row-table: fixed tracks, so the columns land on one x-position
   whatever the row holds — the claim the preview exists to demonstrate. */
.pv-erow {
  display: grid; align-items: center; gap: 8px;
  grid-template-columns: 12px 150px minmax(0, 1fr) 52px 30px;
  padding: 7px 11px; font-size: 11.5px;
}
/* Same affordance as the real thing: one glyph that turns, large enough to
   read as a control. A preview that understates the caret misrepresents the
   pattern it exists to demonstrate. */
.pv-caret {
  display: inline-flex; align-items: center; justify-content: center;
  width: 12px; height: 12px; color: var(--p-dim);
}
.pv-caret svg {
  width: 11px; height: 11px;
  transform-origin: 50% 50%;
  transition: transform 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
.pv-caret.on { color: var(--p-accent); }
/* Two SEPARATE transforms, not one wholesale flip. The resting glyph mirrors
   with direction so it points toward the inline end; the open-state rotation
   does NOT, so "open" always reads as pointing down. Composing them into a
   single direction-negated rotate — or a scaleX(-1) over the whole thing —
   makes an opened row in RTL point upward, which reads as "collapse". */
[dir="rtl"] .pv-caret svg { transform: scaleX(-1); }
.pv-caret.on svg { transform: rotate(90deg); }
[dir="rtl"] .pv-caret.on svg { transform: scaleX(-1) rotate(-90deg); }

/* dir="ltr" on the CELL, never the row: on the row it would un-mirror the
   identifier column and contradict "column order mirrors wholly". The physical
   text-align is deliberate — inside a dir="ltr" cell it resolves the same as
   `end` today, and survives a refactor that drops the dir attribute where
   `end` would silently flip. */
.pv-num { font-size: 10px; text-align: right; font-variant-numeric: tabular-nums; }
.pv-eslug {
  font-family: var(--mono); font-size: 10.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pv-estate {
  color: var(--p-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Indents to the statement column (11 padding + 12 caret + 8 gap + 150 slug
   + 8 gap), so the open row reads as a continuation rather than a new block. */
/* Logical, not `padding: 0 11px 10px 189px` — the indent has to follow the
   text column, and a physically-left indent leaves the panel detached from its
   row in RTL. This is exactly the defect the direction control exists to
   surface, so the preview must not have it. */
.pv-edetail {
  padding-block: 0 10px;
  padding-inline: 189px 11px;
}

.pv-tabs { display: flex; gap: 14px; border-bottom: 1px solid var(--p-border); margin-bottom: 12px; }
.pv-tab { padding-bottom: 7px; font-size: 12px; color: var(--p-dim); }
.pv-tab.on { color: var(--p-accent); border-bottom: 2px solid var(--p-accent); margin-bottom: -1px; }

/* ---- field lists --------------------------------------------------------- */

.field-grid { display: grid; gap: 15px; }
.field-label {
  font-size: 11px; font-weight: 640; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-faint);
  margin-bottom: 4px;
}
.field-value { color: var(--text); max-width: 78ch; }
.field-value.empty-value { color: var(--text-faint); font-style: italic; }

.pill-list { display: flex; flex-wrap: wrap; gap: 5px; }
.pill {
  padding: 2px 8px; font-size: 12px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 5px; color: var(--text-dim);
}

.force-item {
  padding: 10px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.force-item + .force-item { margin-top: 7px; }
.force-trade { font-weight: 570; }
.force-when { color: var(--text-dim); font-size: 12.5px; margin-top: 2px; }

pre.code {
  margin: 0; padding: 12px;
  font-family: var(--mono); font-size: 12px; line-height: 1.55;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow-x: auto;
  color: var(--text-dim);
}

/* ---- adherence ----------------------------------------------------------- */

.adh-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.adh-row:last-child { border-bottom: none; }
.adh-info { flex: 1; min-width: 0; }
.adh-statement { font-size: 12.5px; color: var(--text-dim); margin-top: 2px; }
.adh-controls { display: flex; gap: 1px; padding: 2px; flex: none;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.adh-opt {
  padding: 3px 10px; font: inherit; font-size: 12px;
  color: var(--text-dim); background: none; border: none; border-radius: 3px; cursor: pointer;
}
.adh-opt:hover { background: var(--surface); color: var(--text); }
.adh-opt[aria-pressed="true"] { background: var(--accent); color: var(--accent-text); font-weight: 560; }

/* ---- coverage ------------------------------------------------------------ */

.cov-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}
.cov-card { padding: 15px; }
.cov-card h3 { margin-bottom: 3px; }
.cov-hint { font-size: 12px; color: var(--text-faint); margin-bottom: 11px; }
.cov-stat { display: flex; align-items: baseline; gap: 7px; padding: 6px 0; }
.cov-num {
  font-size: 21px; font-weight: 640;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.cov-bar { height: 5px; border-radius: 3px; background: var(--surface-2); overflow: hidden; margin-top: 5px; }
.cov-fill { height: 100%; background: var(--accent); border-radius: 3px; }

.toast {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
  padding: 9px 16px;
  font-size: 13px;
  background: var(--text); color: var(--bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  z-index: 200;
}

/* Navigation rows in previews — real labels, so a reviewer can judge
   orchestration rather than staring at grey rectangles. */
.pv-navrow {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; margin-bottom: 1px;
  font-size: 12.5px; color: var(--p-dim);
  border-radius: 5px;
}
.pv-navrow.on {
  background: color-mix(in oklab, var(--p-accent), transparent 88%);
  color: var(--p-accent); font-weight: 570;
}
/* Logical, like the rest of the preview: the stage's direction toggle sets
   dir on the frame, so a count pinned with `margin-left` would stay on the
   left in RTL and collide with the label it is supposed to trail. */
.pv-count {
  margin-inline-start: auto; font-size: 11px;
  font-variant-numeric: tabular-nums; opacity: 0.7;
}

/* Who a panel is written for. Stated because a curator cannot otherwise tell
   an agent instruction from user-visible copy — the confusion behind the
   comment that prompted this. */
.audience-note {
  margin-bottom: 14px; padding: 9px 12px;
  font-size: 12px; line-height: 1.5; color: var(--text-dim);
  background: var(--surface-2);
  border-inline-start: 2px solid var(--accent);
  /* Logical corners too — the square end belongs against the accent bar, and
     a physical radius would round the wrong pair when the bar moves. */
  border-start-start-radius: 0; border-end-start-radius: 0;
  border-start-end-radius: var(--radius-sm);
  border-end-end-radius: var(--radius-sm);
}
.audience-note strong { color: var(--text); font-weight: 600; }

/* ---- contracts ----------------------------------------------------------- */

/* The contract fields are prose keyed by facet or state, not code — they were
   previously dumped as JSON into a non-wrapping <pre>. A description list is
   the honest element: these ARE term/definition pairs, and it gives screen
   readers the pairing the JSON braces only implied visually. */

.contract-block + .contract-block {
  margin-top: 20px; padding-top: 18px;
  border-top: 1px solid var(--border);
}
.contract-count {
  font-variant-numeric: tabular-nums; opacity: 0.65;
  /* Sits with the label; no margin-left, which would not follow the label
     when the block mirrors. */
  margin-inline-start: 2px;
}

.contract-list { margin: 0; display: grid; gap: 11px; }
/* Two columns once there is room for the term to sit beside its prose, one
   below the other when there is not. The term column is sized in ch so it
   holds a translated label — `Announcements` is 13ch, its Arabic and German
   equivalents are longer, and a px width would clip them. */
@media (min-width: 760px) {
  .contract-list { grid-template-columns: minmax(0, 15ch) minmax(0, 1fr); gap: 11px 18px; }
  .contract-list dt { grid-column: 1; }
  .contract-list dd { grid-column: 2; }
}
.contract-list dt {
  font-size: 12px; font-weight: 600; color: var(--text);
  /* start, not left: the term hugs the reading edge in both directions. */
  text-align: start;
  /* Optical alignment with the first line of the prose beside it, which sits
     at 13px/1.6. */
  padding-top: 1px;
}
.contract-list dd {
  margin: 0; max-width: 78ch;
  font-size: 13px; line-height: 1.6; color: var(--text-dim);
}
.contract-list + .contract-closed { margin-top: 12px; }

/* Slot and property names are machine keys — an agent matches on them
   literally, so they stay in the source casing and take a mono face to say
   "this exact string" rather than being title-cased into English prose. */
.slot-key, .prop-key {
  display: inline-block;
  padding: 1px 6px;
  font-family: var(--mono); font-size: 11.5px; font-weight: 500;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  /* Keys are ASCII identifiers even in an RTL page; without this an entry
     like `error` beside Arabic prose can reorder at the boundary. */
  direction: ltr; unicode-bidi: isolate;
}

/* Chips keep the schema's enum order in both directions.
   An enum array is authored, not incidental — `ellipsis, wrap` leads with the
   recommended value and `caret, chevron, none` runs strongest to weakest, and
   the description beneath names them in that order ("ellipsis holds the row
   height constant... wrap only where..."). Letting the row inherit RTL flips
   the sequence and the prose then refers to the list backwards. The chips
   themselves are ASCII enum values, already isolated below, so holding the row
   LTR does not strand any Arabic text. */
.allow-row {
  display: flex; flex-wrap: wrap; gap: 5px; align-items: baseline;
  direction: ltr;
}
/* ...but the row as a whole still belongs against the reading edge. */
[dir="rtl"] .allow-row { justify-content: flex-end; }
.allow {
  padding: 1px 7px;
  font-family: var(--mono); font-size: 11.5px;
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  direction: ltr; unicode-bidi: isolate;
}
/* The chosen-unless-overridden value. Marked because "what happens if I set
   nothing" is the first question asked of an allowance. */
.allow.is-default {
  color: var(--text); border-color: var(--accent);
  font-weight: 560;
}
/* A single-value enum is not a menu. Rendering it like the multi-value case
   would invite an implementer to look for the other options. */
.allow.fixed { color: var(--text-faint); font-style: italic; }
.allow.type { color: var(--text-faint); }

.allow-why {
  margin: 6px 0 0; max-width: 74ch;
  font-size: 12.5px; line-height: 1.55; color: var(--text-dim);
}
.contract-closed {
  margin: 0; font-size: 12px; color: var(--text-faint);
}

/* ---- comments ------------------------------------------------------------ */

.comment-box {
  width: 100%;
  padding: 10px 12px;
  font: inherit; font-size: 13px; line-height: 1.55;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  resize: vertical;
}
.comment-box::placeholder { color: var(--text-faint); }
.comment-box:focus { border-color: var(--accent); outline-offset: 1px; }

/* ---- principles overview (density-matches-task) --------------------------- */

/* Key values first: an overview earns its space by answering "what is here"
   before the reader touches a single row. */
.stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; margin-bottom: 16px;
}
.stat {
  padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius);
}
.stat-value {
  font-size: 26px; font-weight: 600; line-height: 1.1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.stat-value.warn { color: var(--warn); }
.stat-label {
  margin-top: 3px; font-size: 12px; font-weight: 560; color: var(--text);
}
.stat-hint { margin-top: 2px; font-size: 11.5px; color: var(--text-faint); line-height: 1.4; }

.pr-table {
  padding: 0; overflow: hidden;
  /* Where the statement column begins: 14 row padding + 16 caret + 10 gap
     + 216 slug + 10 gap, less the card's 1px border. Named because the
     expanded detail indents to the same line. */
  --pr-statement-x: 265px;
}
.pr-row + .pr-row { border-top: 1px solid var(--border); }
.pr-row.open { background: var(--surface-2); }

/* One row = one principle, scannable at a glance. Grid rather than flex so the
   slug and coverage columns line up down the list — comparability is the whole
   job of an overview. */
/* Every track is a FIXED width, not auto. A content-sized column re-measures
   per row, so the statement started at a different x on every line and the
   list stopped reading as columns — which is most of what makes a survey
   scannable. Alignment beats snugness here: a table the eye can run down
   beats one that fits each row perfectly and lines up nowhere.
   Each sub-column is separately aligned so importance, tier, bar, and figure
   each occupy one x-position for the whole list. */
.pr-main {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns:
    16px                      /* caret       */
    216px                     /* slug        */
    minmax(0, 1fr)            /* statement   */
    78px                      /* importance  */
    46px                      /* tier        */
    54px                      /* bar         */
    38px;                     /* percentage  */
  width: 100%; padding: 9px 14px;
  font: inherit; text-align: start; color: var(--text);
  background: none; border: none; cursor: pointer;
}
.pr-main:hover { background: var(--surface-2); }
/* One glyph that ROTATES, rather than two glyphs swapped: a swap cannot be
   animated, and the turn is what tells the reader the row moved rather than
   the page changing under them.
   Sized at 15px, not 10 — the caret is the only thing marking a row as
   expandable, so it has to be legible as an affordance rather than as
   punctuation. Uses --text-dim over --text-faint for the same reason. */
.pr-caret {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px;
  color: var(--text-dim);
  transition: color 140ms ease;
}
/* The SVG carries the rotation, not the wrapper: the path is drawn centred in
   its 24-unit viewBox, so 50%/50% is genuinely the mark's own centre and it
   turns in place. A text glyph cannot do this — its ink sits off-centre in the
   layout box, so the same transform swings it around a point outside itself. */
.pr-caret svg {
  width: 14px; height: 14px;
  transform-origin: 50% 50%;
  transition: transform 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
.pr-row.open .pr-caret { color: var(--accent); }
.pr-row.open .pr-caret svg { transform: rotate(90deg); }
.pr-main:hover .pr-caret { color: var(--text); }
.pr-slug {
  font-size: 12.5px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pr-statement {
  font-size: 13px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Cells start at their track's left edge — a right-aligned cell would drift
   with content width and undo the alignment the fixed tracks just bought. */
.pr-cell { display: flex; align-items: center; min-width: 0; }
.pr-bar {
  display: block; width: 100%; height: 5px; border-radius: 3px;
  background: var(--surface-2); overflow: hidden;
}
.pr-bar-fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
/* Thin adherence is the "needs refining" signal — it must survive a glance. */
.pr-bar-fill.thin { background: var(--warn); }
/* tabular-nums so 89% and 33% occupy identical width — a figure column that
   shifts by a digit is not a column. */
.pr-num {
  font-size: 11.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums; text-align: end;
}
.pr-num.thin { color: var(--warn); }

/* Depth lives here rather than in a detail route, which does not exist: an
   overview may relocate detail, never discard it. */
/* Expanded prose starts where the statement above it starts, so opening a row
   reads as that row continuing rather than as a new block. */
.pr-detail {
  display: grid; gap: 12px;
  padding: 2px 14px 14px var(--pr-statement-x);
}
@media (max-width: 900px) {
  .pr-detail { padding-inline-start: 38px; }
}
.pr-list { margin: 4px 0 0; padding-inline-start: 17px; color: var(--text-dim); font-size: 13px; }
.pr-list li + li { margin-top: 2px; }
.pr-anti { color: var(--text-dim); font-size: 13px; }
.pr-meta { font-size: 11.5px; color: var(--text-faint); }

@media (max-width: 900px) {
  /* The statement is the first thing to go: the slug still identifies the row,
     and the reader can open it. */
  .pr-main {
    grid-template-columns: 16px minmax(0, 1fr) 78px 46px 54px 38px;
  }
  .pr-statement { display: none; }
}

/* app-header: the identity corner and its menu. */
.pv-avatar {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--p-accent); color: #fff;
  font-size: 9px; font-weight: 650; letter-spacing: .02em;
}
/* inset-inline-end, not right: the flyout aligns to the avatar's inline-end
   edge, which is the behaviour the direction contract requires — it opens
   leftward in LTR and rightward in RTL with no second rule. */
.pv-menu {
  position: absolute; inset-inline-end: 0; top: 48px;
  min-width: 132px; padding: 4px;
  background: var(--p-bg);
  border: 1px solid var(--p-border); border-radius: 7px;
  box-shadow: 0 8px 22px rgb(0 0 0 / 18%);
}
.pv-menu-id { padding: 5px 8px 6px; border-bottom: 1px solid var(--p-border); margin-bottom: 3px; }
.pv-menu-item {
  padding: 5px 8px; border-radius: 4px;
  font-size: 11.5px; color: var(--p-text);
}
.pv-menu-item:first-of-type { background: var(--p-surface); }
.pv-menu-sep { height: 1px; background: var(--p-border); margin: 3px 0; }

/* ---- proposed changes ----------------------------------------------------- */

.prop { padding: 13px 0; border-bottom: 1px solid var(--border); }
.prop:last-child { border-bottom: none; }
.prop.stale { opacity: 0.72; }
.prop-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.prop-why { margin: 7px 0 9px; font-size: 13px; }
/* Before and after side by side: a stacked diff makes the reader hold the old
   value in memory while reading the new one. */
.prop-diff { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.prop-diff pre.code { max-height: 190px; overflow: auto; white-space: pre-wrap; }
.prop-new { border-color: var(--accent); }
@media (max-width: 780px) { .prop-diff { grid-template-columns: 1fr; } }

.badge.warn-badge { background: var(--warn-soft); color: var(--warn); border-color: transparent; }
.badge.gate-badge { background: var(--crit-soft); color: var(--crit); border-color: transparent; }

/* A verdict is an opinion attached to the diff, not a decision — coloured to
   be read at a glance, but never replacing the confirm button. */
.prop-review {
  margin: 0 0 9px; padding: 8px 11px;
  font-size: 12.5px; line-height: 1.5; color: var(--text-dim);
  background: var(--surface-2);
  border-inline-start: 2px solid var(--border);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.prop-review strong { display: block; color: var(--text); font-weight: 600; }
.prop-review.v-sound   { border-inline-start-color: var(--ok, #2f9e44); }
.prop-review.v-concern { border-inline-start-color: var(--warn); }
.prop-review.v-wrong,
.prop-review.v-stale   { border-inline-start-color: var(--crit); }

/* Theme is a toggle pushed to the trailing edge, not a group: two options the
   reader is only ever in one of, so a pair of buttons and a group label spent
   width to say what one icon says. */
.stage-spacer { flex: 1; }
.stage-theme { flex: none; }
.stage-theme svg { width: 15px; height: 15px; }
.stage-theme[aria-pressed="true"] { color: var(--accent); }

/* ---- settings: target capabilities ---------------------------------------- */

.cap {
  display: inline-block; padding: 2px 8px;
  font-size: 11.5px; font-weight: 550;
  border-radius: 5px;
  background: var(--surface-2); color: var(--text-dim);
  border: 1px solid var(--border);
}
.cap-ok   { background: var(--ok-soft, var(--surface-2)); color: var(--ok, #2f9e44); border-color: transparent; }
.cap-warn { background: var(--warn-soft); color: var(--warn); border-color: transparent; }
.cap-crit { background: var(--crit-soft); color: var(--crit); border-color: transparent; }
.cap-notes {
  padding: 0 0 12px !important;
  font-size: 12.5px; line-height: 1.55; color: var(--text-dim);
}

/* The frame states which direction it is asserting. Without a marker, an RTL
   render of a symmetric pattern is indistinguishable from an LTR one, and the
   curator cannot tell "mirrors correctly" from "control did nothing". */
.stage-frame[data-preview-direction="rtl"],
.stage-frame[data-preview-direction="ltr"] { position: relative; }
.stage-frame[data-preview-direction="rtl"]::after,
.stage-frame[data-preview-direction="ltr"]::after {
  content: attr(data-preview-direction);
  position: absolute; top: 0; inset-inline-end: 0;
  padding: 2px 7px;
  font: 600 10px/1.4 var(--mono);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent-text); background: var(--accent);
  border-radius: 0 0 0 var(--radius-sm);
  /* Sits outside the artefact's own flow so it cannot be mistaken for part of
     the pattern being judged. */
  pointer-events: none;
}

/* Direction sits immediately before the theme toggle: both are conditions of
   how the artefact renders rather than what it shows, so they group at the
   trailing edge away from the state sweep. */
.stage-dir { flex: none; }
.stage-dir svg { width: 15px; height: 15px; }
.stage-dir[aria-pressed="true"] { color: var(--accent); }
