/* app.css — page-level composition shared by pulse.html, churn.html and scorecard.html (18 Oct 2026).
   Loads after kit.css, kit-ext.css and kit-ext2.css. Kit tokens only; nothing here redefines a token.
   Rhythm 8 / 24 / 48: 8 inside a unit, 24 between units, 48 between regions. */

[hidden]{display:none!important}

/* ---------- header: brand · product switch · meta · Gates · Glossary · role · reveal names · avatar ---------- */
.app-header{gap:var(--space-2)}
.app-nav{margin-left:var(--space-1)}
.header-meta{flex:none;line-height:1.3}
.header-meta>span{display:block;white-space:nowrap}
.hdr-link{appearance:none;-webkit-appearance:none;border:0;background:none;margin:0;font:inherit;font-size:var(--fs-small);font-weight:600;color:var(--color-text-secondary);text-decoration:none;padding:0 var(--space-2);min-height:34px;display:inline-flex;align-items:center;gap:0;border-radius:var(--radius-s);cursor:pointer;white-space:nowrap}
.hdr-link:hover{background:var(--color-canvas);color:var(--color-text)}
.hdr-link[aria-current=page]{background:var(--color-selected);color:var(--color-text);box-shadow:inset 0 -2px 0 var(--color-action)}
.hdr-link:disabled{color:var(--color-text-muted);font-weight:400;cursor:default}
.hdr-link:disabled:hover{background:none}
.hdr-link .word{font-size:inherit}
.role-select{min-width:0;min-height:30px;padding:3px 26px 3px 8px;font-size:var(--fs-small);border-color:var(--color-rule)}
.reveal{font-size:var(--fs-small);color:var(--color-text-secondary);white-space:nowrap;min-height:30px}
.reveal input{width:16px;height:16px}
.reveal[hidden]{display:none}
@media (max-width:1100px){.app-header .me{display:none}}
@media (max-width:700px){.app-header{position:static}}
@media (max-width:900px){
  .app-header{height:auto;min-height:var(--header-h);flex-wrap:wrap;row-gap:var(--space-1);padding-top:var(--space-2);padding-bottom:var(--space-2)}
  .app-nav{margin-right:0}
}

/* ---------- band: tile, title, facts, scope ---------- */
.band .scope .select{min-width:132px}
.band .facts{gap:2px var(--space-2)}
.band .facts .mi+.mi::before{margin-right:var(--space-2)}

/* ---------- the answer: the consequence sentence opens every view; tools sit on its line ---------- */
.lead{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-3) var(--space-5);flex-wrap:wrap;padding:var(--space-1) 0 0}
.lead>.sx-sentence{flex:1 1 36ch}
.lead>.seg{margin-top:4px}

/* ---------- workspace: main column 24 between units; rail ---------- */
.ws>.main{gap:var(--space-5)}
.ws.expanded{grid-template-columns:minmax(0,1fr)}
@media (min-width:901px){.ws.expanded>.rail{display:none}}
/* the kit's source order lets the base .rail rule win over its own ≤ 900 px override: the rail stays sticky with a viewport-high
   cap when stacked. Put the rail back in the flow below the main column. */
@media (max-width:900px){
  .ws>.rail{position:static;top:auto;max-height:none;overflow:visible;margin-top:var(--space-5)}
}
.rail-idle{color:var(--color-text-muted);font-size:var(--fs-small);padding:var(--space-4) 0}
.rail .say{font-size:var(--fs-small);color:var(--color-text-secondary);line-height:1.5;margin-top:var(--space-3)}
.rail .err{color:var(--ink-danger);font-size:var(--fs-small)}   /* 5.23:1 on white, 4.65:1 on the canvas the rail sits on (was --color-danger: 4.34 and 3.86; lens fe-5) */

/* ---------- tables: phrase headers wrap (the kit's nowrap was written for one-word headers) ---------- */
.table thead th{white-space:normal;line-height:1.25;vertical-align:bottom}
.table thead th button{white-space:normal;text-align:left}
.table .id .t.nowrap{white-space:nowrap}

/* ---------- folds: a collapsed section is a phrase heading and one summary line; the reader (or the hash, app.fold) opens it ----------
   One fold = one unit: 16 above and below its two lines, 24 below the opened body; rules are the quiet 1 px soft line. No chevron: the word
   "show" / "hide" at the end of the heading line is the whole affordance. */
.sx-folds{display:flex;flex-direction:column}
.sx-fold{border-top:1px solid var(--color-rule-soft);scroll-margin-top:calc(var(--header-h) + var(--space-4))}
.sx-fold>summary{list-style:none;cursor:pointer;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--space-4);row-gap:2px;align-items:baseline;padding:var(--space-4) 0;border-radius:var(--radius-s)}
.sx-fold>summary::-webkit-details-marker{display:none}
.sx-fold>summary::after{content:'show';grid-column:2;grid-row:1;font-size:var(--fs-micro);color:var(--color-text-muted)}
.sx-fold[open]>summary::after{content:'hide'}
.sx-fold>summary:hover::after,.sx-fold>summary:focus-visible::after{color:var(--color-link);text-decoration:underline}
.sx-fold>summary:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}
.sx-fold-h{grid-column:1;font-size:var(--fs-reading);font-weight:700;line-height:1.35;color:var(--color-text)}
.sx-fold-s{grid-column:1;font-size:var(--fs-small);line-height:1.4;color:var(--color-text-secondary)}
.sx-fold-s .word{font-size:inherit}
.sx-fold-body{display:flex;flex-direction:column;gap:var(--space-4);padding:0 0 var(--space-5);min-width:0}

/* ---------- Denied keeps the page: value figures read "restricted" and the notice names the role ---------- */
body[data-state=denied] .ws{display:grid}
body[data-state=denied] .ptabs,body[data-state=denied] .band .scope{display:flex}
body[data-state=denied] .band .facts>*:not(:first-child){display:inline-flex}
@media (max-width:900px){body[data-state=denied] .ws{display:block}}
.restricted{color:var(--color-text-muted);font-style:italic}

/* ---------- Pulse expanded page: back bar ---------- */
.backbar{display:flex;align-items:center;gap:var(--space-3);font-size:var(--fs-small);color:var(--color-text-muted)}

/* ---------- glossary dialog ---------- */
.gloss-panel{width:min(720px,100vw - 32px)}
.gloss-find{margin-top:var(--space-4)}
.gloss{margin:var(--space-4) 0 0;display:grid;grid-template-columns:minmax(120px,max-content) minmax(0,1fr);gap:0 var(--space-4);font-size:var(--fs-body)}
.gloss dt{font-weight:700;padding:var(--space-2) 0;border-top:1px solid var(--color-rule-soft)}
.gloss dd{margin:0;padding:var(--space-2) 0;border-top:1px solid var(--color-rule-soft);color:var(--color-text-secondary);line-height:1.45}
.gloss dd .m{color:var(--color-text-muted);font-size:var(--fs-small)}
.gloss dt:first-of-type,.gloss dt:first-of-type+dd{border-top:0}
@media (max-width:700px){.gloss{grid-template-columns:minmax(0,1fr)}.gloss dt{padding-bottom:0}.gloss dd{border-top:0;padding-top:2px}}

/* ---------- scorecard ---------- */
.gate-group{display:flex;flex-direction:column;gap:var(--space-4)}
.gate-group .sec-head h2{display:flex;align-items:baseline;gap:var(--space-3);flex-wrap:wrap}
.gate-group .sec-head .word{font-size:var(--fs-small)}
.sx-gate.sx-selected{box-shadow:inset 3px 0 0 var(--color-action)}
.gate-sub{display:flex;flex-direction:column;gap:var(--space-3)}
.gate-sub+.gate-sub{margin-top:var(--space-4)}
.gate-sub-h{margin:0;font-size:var(--fs-body);font-weight:700;line-height:1.35}
.gate-sub-h .word{font-size:var(--fs-small);margin-left:var(--space-2)}
.sx-words .gate-id{color:var(--color-text-muted);font-size:var(--fs-micro);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.sx-words tr.sx-selected td{background:var(--color-selected)}
.sx-words tr[tabindex]{cursor:pointer}
.gate-links{display:flex;gap:var(--space-4);flex-wrap:wrap;font-size:var(--fs-body)}
.rail .gate-id{font-size:var(--fs-small);color:var(--color-text-muted);font-variant-numeric:tabular-nums;word-break:break-all}
.rail .gate-detail{font-size:var(--fs-small);color:var(--color-text-secondary);line-height:1.5;margin-top:var(--space-2);overflow-wrap:anywhere}
/* a gate's value and threshold are sentences for some checks: let them wrap inside the tile (the kit keeps .num on one line) */
.sx-gate-vals{min-width:0}
.sx-gate-v{min-width:0;max-width:100%}
.sx-gate-v .num{white-space:normal;overflow-wrap:anywhere}
