  /* ============================== ANALYZE (dashboard) ============================== */
  #analyzeView{z-index:145;}
  .an-body{max-width:1060px; margin:0 auto; padding:20px 24px 80px;}
  /* KPI strip (Drawing Set §5) — one ruled strip, four cells divided by hairlines, like a
     title block's row; no decorative icon badges. Figures are proportional (standalone). */
  .kpi-row{display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:0; margin-bottom:16px; background:var(--surface-default);
    border:1px solid var(--border-strong); border-radius:var(--r-card); overflow:hidden;}
  .stat-tile{padding:12px 16px; position:relative; min-width:0;}
  .stat-tile + .stat-tile{border-left:1px solid var(--border-default);}
  .stat-tile .st-label{font-size:11px; line-height:13px; font-weight:600; font-stretch:var(--stretch-label); letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); margin-bottom:6px;}
  .stat-tile .st-value{font-size:24px; line-height:28px; font-weight:600; font-variant-numeric:proportional-nums; color:var(--text-primary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .stat-tile .st-sub{font-size:11.5px; line-height:16px; color:var(--text-muted); margin-top:2px;}
  /* One filter row above everything it scopes (never per-chart filters) */
  .an-filterbar{background:var(--panel); border:1px solid var(--border-strong); border-radius:var(--r-card); padding:10px 14px; margin-bottom:14px;}
  .an-filterbar .fb-head{display:flex; align-items:center; gap:10px; font-size:12px; color:var(--muted); flex-wrap:wrap;}
  .an-filterbar .fb-head b{color:var(--text);}
  /* Each filter row is a shared .nf-rule (public/js/builder/rule-editor.js, public/css/18-rule-editor.css) —
     no bar-specific select styling here any more (that's what produced the 230px question-picker
     truncation the typed-rules spec §5 called out; the shared editor's own 320px max-width and JS
     ellipsis fix it by construction). Just the vertical rhythm above the first row. */
  .an-filterbar .nf-rule{margin-top:8px;}
  /* Tabs (spec §5) — 13.5px muted sentence case; active ink 600 on a 2px brand-600 rule. */
  .an-tabbar{display:flex; gap:4px; margin-bottom:14px; border-bottom:1px solid var(--border-strong); padding-bottom:0;}
  .an-tab{background:transparent; border:none; border-bottom:2px solid transparent; border-radius:0; padding:10px 15px; margin-bottom:-1px; font-size:13.5px; font-weight:500; color:var(--text-muted);}
  .an-tab:hover{color:var(--text-primary); border-color:transparent; background:transparent;}
  .an-tab.active{color:var(--text-primary); border-bottom-color:var(--brand-600); font-weight:600;}
  .an-tab:disabled, .an-tab:disabled:hover{background:transparent; border-color:transparent; color:var(--text-muted);}
  .q-card{background:var(--panel); border:1px solid var(--border-strong); border-radius:var(--r-card); padding:16px 18px; margin-bottom:14px;}
  .q-card .qc-head{display:flex; align-items:baseline; gap:10px; margin-bottom:12px; flex-wrap:wrap;}
  .q-card .qc-title{font-size:14px; line-height:20px; font-weight:600; flex:1; min-width:200px;}
  .q-card .qc-sub{font-size:11.5px; color:var(--text-muted); white-space:nowrap;}
  /* Detail caption (spec §5) — the chart card is captioned like a drawing detail:
     DETAIL k · type on the left, n = … in mono on the right, plus the "new" mark. */
  .qc-caption{display:flex; align-items:baseline; gap:12px; margin:14px -18px -16px; padding:8px 18px; border-top:1px solid var(--border-default);}
  .qc-caption .qc-detail{flex:1; min-width:0; font-size:11px; line-height:13px; font-weight:600; font-stretch:var(--stretch-label); letter-spacing:.08em;
    text-transform:uppercase; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .qc-caption .qc-block{font-size:11.5px; font-stretch:100%; letter-spacing:0; text-transform:none; font-weight:400;} /* a block name is user-authored — never narrow uppercase */
  .qc-caption .qc-n{flex:none; font-family:var(--font-mono); font-size:11.5px; font-weight:500; color:var(--text-secondary); white-space:nowrap;}
  .qc-caption .qc-new{flex:none;}
  .q-card svg{display:block;}
  .q-card svg text{font-family:inherit;}
  .hbar-label .nf-i{display:inline-block; vertical-align:-2px;}
  .hbar-label .nf-i svg{display:inline;}
  .chart-legend{display:flex; gap:12px; flex-wrap:wrap; margin-bottom:10px;}
  .chart-legend .lg-item{display:flex; align-items:center; gap:5px; font-size:11.5px; color:var(--text-muted);}
  .chart-legend .lg-swatch{width:10px; height:10px; border-radius:var(--r-stamp); flex:none;}
  .text-answers{display:flex; flex-direction:column; gap:6px; max-height:260px; overflow-y:auto;}
  .text-answer{background:var(--panel2); border:1px solid var(--border-default); border-radius:var(--r-control); padding:7px 10px; font-size:12.5px;}
  /* File upload answers (spec file-upload §3) */
  .file-answers{max-height:320px;}
  .fa-main{display:flex; align-items:center; gap:8px; min-width:0; margin-top:4px; color:var(--text-secondary);}
  .fa-main > .nf-i{flex:none;}
  .fa-name{flex:1 1 0; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12.5px; color:var(--text-primary);}
  .fa-tail{display:flex; align-items:center; gap:10px; flex:none; min-height:32px;} /* every row as tall as a Download row */
  .fa-size{font-size:12px; color:var(--text-secondary); font-variant-numeric:tabular-nums; white-space:nowrap;}
  .fa-note{font-size:11.5px; color:var(--text-muted); white-space:nowrap;}
  button.fa-dl{height:32px; padding:0 10px; font-size:12px;}
  .fa-ind .fa-main{margin-top:0;}
  .fa-ind .fa-main + .fa-main{margin-top:6px;}
  @media (max-width:600px){
    .fa-main{flex-wrap:wrap;}
    .fa-name{flex-basis:calc(100% - 24px);}
    .fa-tail{flex-basis:100%; justify-content:space-between; padding-left:24px;}
  }
  .text-answer .ta-when{display:flex; align-items:center; gap:8px; font-size:11.5px; color:var(--text-muted); margin-top:3px;}
  .elab-list{margin-top:10px; border-top:1px solid var(--border); padding-top:8px;}
  .elab-list .el-hd{font-size:11.5px; color:var(--muted); margin-bottom:5px;}
  #vizTip{
    position:fixed; z-index:300; background:var(--surface-default); color:var(--text-secondary); border:1px solid var(--border-strong); border-radius:var(--r-control); padding:6px 10px;
    font-size:11.5px; pointer-events:none; display:none; box-shadow:var(--shadow-2); line-height:1.5; max-width:260px;
  }
  /* Chart marks — per the dataviz spec: thin bars (≤24px), 4px rounded data-end + square
     baseline end, hairline recessive axes, 2px surface gaps between stacked segments,
     values in text tokens (never colored text). Single series brand-600 #2563EB and the blue ordinal
     ramp are palette-validated on the white card surface. */
  .hbar-row{display:flex; align-items:center; gap:10px; margin-bottom:7px;}
  .hbar-label{width:170px; flex:none; text-align:right; font-size:11.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .hbar-label img{width:22px; height:16px; object-fit:cover; border-radius:var(--r-chip); vertical-align:-3px; margin-right:5px;}
  .hbar-track{flex:1; height:16px; border-left:1px solid var(--border-strong); position:relative;}
  .hbar-fill{height:100%; background:var(--brand-600); border-radius:0 var(--r-mark) var(--r-mark) 0;}
  .hbar-val{font-size:11.5px; color:var(--text); width:86px; flex:none; font-variant-numeric:tabular-nums;}
  .hist{position:relative; display:flex; gap:6px; align-items:flex-end; padding-bottom:20px;}
  .hist-base{position:absolute; left:0; right:0; bottom:20px; height:1px; background:var(--border-strong);}
  .hist-col{flex:1; max-width:46px; display:flex; flex-direction:column; align-items:center; position:relative;}
  .hist-barwrap{height:110px; display:flex; align-items:flex-end; width:100%; justify-content:center;}
  .hist-fill{width:100%; max-width:24px; background:var(--brand-600); border-radius:var(--r-mark) var(--r-mark) 0 0;}
  .hist-x{position:absolute; top:114px; font-size:11.5px; color:var(--muted); white-space:nowrap;}
  .stack-track{flex:1; display:flex; gap:2px; height:16px;}
  .stack-seg{height:100%;}
  .stack-seg:first-child{border-radius:var(--r-mark) 0 0 var(--r-mark);}
  .stack-seg:last-child{border-radius:0 var(--r-mark) var(--r-mark) 0;}
  .stack-seg:only-child{border-radius:var(--r-mark);}
  .chart-note{font-size:11.5px; color:var(--text-muted); margin-top:8px;} /* defect 5: was 10.5px */
  /* All-answers table — the WCAG-clean twin of every chart */
  /* Tables (spec §5) — sunken header 12/600 secondary, sentence case (headers are question
     labels: never narrow uppercase); rows 12.5px with hairline dividers; tabular numbers. */
  .an-table-wrap{overflow-x:auto; background:var(--panel); border:1px solid var(--border-strong); border-radius:var(--r-card);}
  .an-table{border-collapse:collapse; width:100%; font-size:12.5px;}
  .an-table th{position:sticky; top:0; background:var(--surface-sunken); text-align:left; padding:8px 10px; font-size:12px; font-weight:600; color:var(--text-secondary); white-space:nowrap; max-width:180px; overflow:hidden; text-overflow:ellipsis;}
  .an-table td{padding:7px 10px; border-top:1px solid var(--border-default); max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-variant-numeric:tabular-nums;}
  .an-table tbody tr{cursor:pointer;}
  .an-table tbody tr:hover td{background:var(--surface-subtle);}
  /* .xtab: the cross-tab table twin of .an-table — its rows aren't clickable (there's no
     "individual response" to jump to from a cell), so the hover affordance is switched off. */
  .an-table.xtab tbody tr{cursor:default;}
  .an-table.xtab tbody tr:hover td{background:inherit;}
  /* Export menu — canonical popover pattern (wrapper relative / panel absolute), reused
     by any future dropdown menu in Analyze. */
  .export-menu-wrap{position:relative; display:inline-flex;}
  .export-menu{position:absolute; right:0; top:calc(100% + 6px); min-width:264px; background:var(--surface-default);
    border:1px solid var(--border-strong); border-radius:var(--r-card); box-shadow:var(--shadow-2); padding:6px; z-index:60;}
  .export-menu-scope{font-size:11.5px; color:var(--text-muted); padding:8px 10px 6px;}
  .export-menu-scope b{color:var(--text-primary);}
  .export-menu .export-menu-item{display:block; width:100%; text-align:left; border:none; background:transparent;
    padding:8px 10px; border-radius:var(--r-control); font:inherit; cursor:pointer;}
  .export-menu .export-menu-item:hover{background:var(--brand-50);}
  .export-menu-item .emi-l1{font-size:13px; color:var(--text-primary);}
  .export-menu-item .emi-l2{font-size:11.5px; color:var(--text-muted); margin-top:1px;}
  /* Cross-tab controls + segmented mode switch (canonical pattern — attach point for any
     future segmented control elsewhere in Analyze; see A10). */
  .xtab-controls{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:12px;}
  .xtab-controls label{font-size:12px; color:var(--text-muted);}
  .xtab-controls select{background:var(--surface-default); border:1px solid var(--border-control); color:var(--text);
    border-radius:var(--r-control); padding:5px 7px; font-size:12px; font:inherit; max-width:280px;}
  .xtab-controls .spacer{flex:1;}
  .xtab-swap-btn{width:28px; height:28px; flex:none; display:inline-flex; align-items:center; justify-content:center;
    background:transparent; border:1px solid var(--border-control); border-radius:var(--r-control); color:var(--text-muted); padding:0; cursor:pointer;}
  .xtab-swap-btn:hover{background:var(--brand-50); border-color:var(--border-control); color:var(--text-primary);}
  .xtab-seg{display:flex; background:var(--surface-sunken); border:1px solid var(--border-control); border-radius:var(--r-control); padding:2px; gap:2px;}
  .xtab-seg button{border:1px solid transparent; background:transparent; font-size:12px; padding:5px 10px; border-radius:var(--r-control); color:var(--text-muted);}
  .xtab-seg button.active{background:var(--surface-default); border-color:var(--border-control); color:var(--text-primary); font-weight:600;} /* spec §3 — a 1px ink border instead of a shadow */
  .xtab-hint{font-size:12px; color:var(--text-muted); padding:24px 0; text-align:center;}
  /* Funnel — pages reached / where respondents finished */
  .funnel .hbar-label{width:260px; text-align:left;}
  .funnel-chip{background:var(--logic-bg); color:var(--logic-fg-strong); border-radius:var(--r-chip); padding:1px 5px; font-size:11px; font-weight:600; margin-right:5px; display:inline-block; vertical-align:1px;}
  /* Individual response browser */
  .ind-nav{display:flex; align-items:center; gap:10px; margin-bottom:14px;}
  .ind-nav .ind-pos{font-size:12.5px; color:var(--muted); font-variant-numeric:tabular-nums;}
  .ind-meta{font-size:11.5px; color:var(--muted); margin-bottom:14px; line-height:1.7;}
  .ind-q{background:var(--panel); border:1px solid var(--border-strong); border-radius:var(--r-card); padding:12px 16px; margin-bottom:10px;}
  .ind-q .iq-label{font-size:12px; color:var(--muted); margin-bottom:5px;}
  .ind-q .iq-answer{font-size:13.5px;}
  .ind-q .iq-elab{font-size:12px; color:var(--muted); margin-top:6px; font-style:italic;}


  /* ---- "New since last seen" (Drawing Set §5) — redline marks only ever carry the word
     "new"; never a bare red dot, never a row tint or a thick border. ---- */
  .new-chip{height:24px; display:inline-flex; align-items:center; gap:6px; padding:0 8px; border-radius:var(--r-chip);
    background:var(--redline-bg); color:var(--redline); font-size:12px; font-weight:600; white-space:nowrap; flex:none;}
  .new-sq{display:inline-block; width:6px; height:6px; background:var(--redline); flex:none;}
  .new-mark{display:inline-flex; align-items:center; gap:4px; font-size:11px; line-height:13px; font-weight:600; font-stretch:var(--stretch-label);
    letter-spacing:.08em; text-transform:uppercase; color:var(--redline); white-space:nowrap; vertical-align:1px;}
  .new-count{display:inline-flex; align-items:center; gap:5px; font-size:11.5px; font-weight:600; color:var(--redline); white-space:nowrap;}
  .an-table td .new-mark{margin-left:6px;}
  /* Analyze header: the same title block as the builder, the "new" chip beside it. */
  #analyzeView > .fullview-bar{padding-top:8px; padding-bottom:8px;}

  /* ============================== NARROW ANALYZE — spec docs/specs/narrow-layouts.md §5 ============================== */
  .an-body{width:100%; box-sizing:border-box;}
  .stat-tile .kpi-short{display:none;}
  .star-summary{display:flex; gap:20px; align-items:flex-start;}
  .star-summary-avg{width:110px; flex:none;}
  #analyzeView > .fullview-bar{flex-wrap:wrap; row-gap:8px;}
  #analyzeView > .fullview-bar button{white-space:nowrap;}
  #anTitleBlock{min-width:0;}
  #anTitleBlock .tb-name{min-width:96px;}
  /* Tabs: one row that scrolls inside itself; fades only on a side that really scrolls. */
  .an-tabbar{position:relative; overflow-x:auto; overflow-y:hidden; scrollbar-width:none; flex-wrap:nowrap;}
  .an-tabbar::-webkit-scrollbar{display:none;}
  .an-tab{flex:none; white-space:nowrap; height:40px; padding:0 12px;}
  .an-tabbar.is-scrollable{-webkit-mask-image:linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    mask-image:linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);}
  .an-tabbar.is-scrollable.at-start{-webkit-mask-image:linear-gradient(to right, #000 calc(100% - 24px), transparent 100%); mask-image:linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);}
  .an-tabbar.is-scrollable.at-end{-webkit-mask-image:linear-gradient(to right, transparent 0, #000 24px); mask-image:linear-gradient(to right, transparent 0, #000 24px);}
  .an-tabbar.is-scrollable.at-start.at-end{-webkit-mask-image:none; mask-image:none;}
  /* Captions wrap between "Detail n · type" and "n = …", never inside "n = …". */
  .qc-caption{flex-wrap:wrap; row-gap:4px;}
  .qc-caption .qc-detail{flex:1 1 160px;}
  /* Cross-tab: the first column stays put while the table scrolls. */
  .an-table.xtab th:first-child, .an-table.xtab td:first-child{position:sticky; left:0; z-index:1; background:var(--surface-default); box-shadow:inset -1px 0 0 var(--border-default);}
  .an-table.xtab thead th:first-child{background:var(--surface-sunken); z-index:2;}
  .ind-nav{flex-wrap:wrap; row-gap:8px;}
  .ind-nav-steps{display:flex; align-items:center; gap:10px;}
  .ind-nav .danger{height:34px; white-space:nowrap; margin-left:auto;} /* right-aligned, also when it wraps to its own row */
  .an-filterbar .variant-chip-row{gap:8px;}

  @media (max-width:1023px){
    .stat-tile .kpi-long{display:none;}
    .stat-tile .kpi-short{display:inline;}
  }
  @media (max-width:767px){
    .an-body{padding:16px 16px 64px;}
    #analyzeView > .fullview-bar{padding:8px 12px;}
    #analyzeView > .fullview-bar .sb-menu-btn{order:0;}
    #anTitleBlock{order:1; flex:1 1 calc(100% - 56px); min-width:0;} /* fills row 1 beside the menu button; the actions wrap to row 2 */
    #analyzeView > .fullview-bar .spacer{display:none;}
    #analyzeView #analyzeFreshness, #analyzeView #analyzeRefreshBtn, #analyzeView #exportMenuWrap, #analyzeView #analyzeSampleBtn{order:2;}
    #analyzeView #exportMenuWrap{margin-left:auto;}
    #anNewChip{order:3; flex-basis:100%; width:max-content; flex-grow:0;}
    /* KPI: a 2×2 ruled grid, hairlines between columns and rows, none doubled at the edge */
    .kpi-row{grid-template-columns:repeat(2, minmax(0, 1fr));}
    .stat-tile + .stat-tile{border-left:none;}
    .stat-tile:nth-child(2n){border-left:1px solid var(--border-default);}
    .stat-tile:nth-child(n+3){border-top:1px solid var(--border-default);}
    .stat-tile .st-value{font-size:20px; line-height:24px; overflow:visible; text-overflow:clip;}
    .an-filterbar .fb-hint{display:none;}
    /* bar labels: a 40% column, two lines, then an ellipsis (the full label stays in the tooltip) */
    .hbar-label{width:auto; flex:0 0 40%; max-width:170px; white-space:normal; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; line-height:15px;}
    .hbar-val{width:auto; min-width:56px;}
    .export-menu{max-width:calc(100vw - 16px);}
  }
  @media (max-width:600px){
    #analyzeView #analyzeSampleBtn{width:34px; height:34px; padding:0; justify-content:center; gap:0;}
    #analyzeView #analyzeSampleBtn .an-btn-txt{display:none;}
    /* the title block on two rows: the name across the top, PAGES | STATUS under it */
    #anTitleBlock{display:grid; grid-template-columns:1fr auto; height:auto;}
    #anTitleBlock .tb-name{grid-template-columns:minmax(0, 1fr); justify-content:stretch;}
    #anTitleBlock .tb-name .tb-val{text-align:left;}
    #anTitleBlock .tb-name{grid-column:1 / -1; border-bottom:1px solid var(--border-default); height:44px; box-sizing:border-box;}
    #anTitleBlock .tb-cell{padding:0 14px; height:44px; box-sizing:border-box;}
    #anTitleBlock .tb-cell + .tb-cell{border-left:none;}
    #anTitleBlock #anStatusCell{border-left:1px solid var(--border-default);}
    .star-summary{flex-direction:column; gap:8px;}
    .star-summary-avg{width:auto;}
    .funnel .hbar-row{flex-wrap:wrap; row-gap:4px;}
    .funnel .hbar-label{flex:0 0 100%; max-width:none; text-align:left;}
  }
