  .btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;font-size:14px;
    font-weight:500;border:none;cursor:default;background:var(--sel);color:var(--text);white-space:nowrap;}
  .btn .icon{width:13px;height:13px;}
  .btn-primary{background:var(--red);color:#fff;padding:8px 12px;}
  /* Closing a conversation is the one destructive-ish action; it carries the
     deeper red so it doesn't read as just another "new thing" button. */
  .btn-primary.btn-deep{background:var(--red-deep);}
  .btn-clickable{cursor:pointer;}
  .btn-clickable:hover{filter:brightness(0.96);}
  .btn-primary.btn-clickable:hover{filter:brightness(1.1);}
  .btn.active{background:var(--sel);}

  /* Bands inside the card are transparent; the card is the only white surface. */
  .filter-row{display:flex;align-items:center;gap:8px;padding:8px 24px 14px;background:transparent;flex:0 0 auto;}
  .filter-row.bordered{border-bottom:none;}
  .filter-spacer{flex:1;}
  .filter-meta{font-size:13px;color:var(--muted);}
  /* Filter/search chips are lighter than action pills so the two don't compete. */
  .filter-row .btn{background:var(--pill);}
  .filter-row .btn.btn-primary{background:var(--red);}

  /* Search field: a real <input> dressed as the same pill the rest of the
     filter row uses, so it doesn't stand out as the one different control. */
  .search-field{padding:8px 12px;cursor:text;}
  .search-field input{border:none;background:transparent;outline:none;font:inherit;color:var(--text);
    width:150px;padding:0;}
  .search-field input::placeholder{color:var(--muted);}

  .scroll-body{padding:24px;display:flex;flex-direction:column;gap:20px;flex:1;overflow-y:auto;}
  /* overflow:hidden on .card gives it an automatic flex min-size of 0, so
     without this a tall card can get silently compressed (and its excess
     content clipped) instead of the scroll-body simply scrolling. */
  .scroll-body>*{flex-shrink:0;}

  /* Skeleton loading state — a stand-in for wherever a real fetch would sit,
     briefly shown between page navigations (see showPage in app.js). Sized
     inline per-instance; the pulse itself is the only shared rule. */
  @keyframes skeletonPulse{0%,100%{opacity:1;}50%{opacity:.5;}}
  .skeleton{background:var(--surface-nested);animation:skeletonPulse 1.4s ease-in-out infinite;
    border-radius:8px;flex-shrink:0;}
  @media (prefers-reduced-motion:reduce){
    .skeleton{animation:none;}
  }

  /* Tables keep a white body with a hairline frame; chart wells take the nested
     tone (see .chart-card). Either way it's a frame on the card, not a second
     elevation — no shadow at this level. */
  .card{background:#fff;border:1px solid var(--border);border-radius:12px;overflow:hidden;}
  .card-soft-border{border:.5px solid var(--border-soft);}
  .card-header{padding:16px;font-size:14px;font-weight:600;letter-spacing:-.02em;}
  .card-header.bordered{border-bottom:.5px solid var(--border-soft);}

  table{width:100%;border-collapse:collapse;}
  thead th{text-align:left;background:var(--bg);color:var(--muted);font-size:12px;font-weight:500;
    padding:10px 16px;white-space:nowrap;}
  tbody td{padding:12px 16px;font-size:14px;color:var(--muted);border-top:1px solid var(--border);white-space:nowrap;}
  tbody td.strong{color:var(--text);font-weight:500;}
  tbody tr.row-flag{background:var(--amber-bg);}
  tbody tr.clickable{cursor:pointer;}
  tbody tr.clickable:hover td{background:var(--surface-nested);}

  .pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:500;white-space:nowrap;}
  .pill-outline{background:#fff;border:1px solid var(--amber);color:var(--amber);}
  .pill-escalated{background:var(--red-bg);color:var(--red-text);}
  .pill-cleared{background:var(--green-bg);color:var(--green-text);}

  /* Fixed height (not just vertical padding) so a badge sitting next to a
     26px icon-btn-square — e.g. the chat header's role + LMS badges — lines
     up exactly rather than being a few px shorter. */
  .badge{display:inline-flex;align-items:center;height:26px;padding:0 7px;border-radius:4px;font-size:12px;font-weight:500;white-space:nowrap;}
  .badge-admin{background:var(--amber-badge-bg);color:var(--amber-badge-text);}
  .badge-student{background:var(--orange-bg);color:var(--orange-badge-text);}
  .badge-instructor{background:var(--blue-bg);color:var(--blue-text);}

  .avatar-circle{width:28px;height:28px;border-radius:999px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
    font-size:11px;font-weight:600;color:#fff;}

  /* Tiles are now discrete cards with their own gaps rather than cells divided by
     rules inside one box — so a single tile can be highlighted independently. */
  .stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;background:transparent;
    border:none;border-radius:0;overflow:visible;}
  .stat-grid.cols-3{grid-template-columns:repeat(3,1fr);}
  .stat-grid.cols-2{grid-template-columns:repeat(2,1fr);}
  .stat-tile{padding:16px 20px;border:none;border-radius:12px;
    background:var(--surface-nested);}
  .stat-tile.highlight{background:var(--pink-hi);}
  .stat-label{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--muted);margin-bottom:14px;}
  .stat-label .icon{width:14px;height:14px;}
  .stat-value-row{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;}
  .stat-value{font-size:28px;font-weight:600;letter-spacing:-.02em;}
  .stat-delta{font-size:13px;color:var(--muted);display:inline-flex;align-items:center;gap:2px;}
  .stat-delta .icon{width:12px;height:12px;}
  .stat-delta.up{color:var(--green-text);}
  .stat-delta.down{color:var(--red-text);}
  .stat-delta.warn{color:var(--amber);}
  .stat-caption{font-size:12px;color:var(--muted);margin-top:10px;}
  .footnote{display:flex;gap:6px;padding:10px 0 0;font-size:12px;color:var(--muted);border-top:1px solid var(--border);margin-top:0;}
  .footnote .f{font-style:italic;flex:0 0 auto;}

  .chart-card{padding:20px;background:var(--surface-nested);border:none;}
  .chart-card h3{font-size:16px;font-weight:600;letter-spacing:-.02em;margin-bottom:14px;}
  .chart-wrap{display:flex;gap:8px;}
  .chart-yaxis{display:flex;flex-direction:column;justify-content:space-between;font-size:12px;color:var(--muted);
    padding:2px 0;text-align:right;}
  .chart-plot{flex:1;min-width:0;position:relative;}

  /* Grid: a light dashed rule rather than a solid hairline, shared by every
     chart type (line/multi-line/bar) so the visual language stays one thing. */
  .chart-grid{stroke:var(--border);stroke-width:1;stroke-dasharray:3 5;}

  /* Charts draw themselves in on mount rather than appearing fully formed —
     line first, then the fill, then the latest-value dot settles in and starts
     a slow live pulse (same idea as the mic-recording pulse, just for data). */
  @keyframes chartDraw{from{stroke-dashoffset:100;}to{stroke-dashoffset:0;}}
  .chart-line{stroke-dasharray:100;stroke-dashoffset:100;animation:chartDraw 1s cubic-bezier(.4,0,.2,1) forwards;
    animation-delay:var(--delay,0s);filter:drop-shadow(0 1px 2px rgba(0,0,0,.08));}
  @keyframes chartFade{to{opacity:1;}}
  .chart-area{opacity:0;animation:chartFade .7s ease forwards;animation-delay:calc(var(--delay,0s) + .35s);}
  @keyframes chartDotPop{0%{transform:scale(0);opacity:0;}70%{transform:scale(1.35);opacity:1;}100%{transform:scale(1);opacity:1;}}
  .chart-dot{transform-box:fill-box;transform-origin:center;opacity:0;stroke:#fff;stroke-width:2;
    filter:drop-shadow(0 1px 2px rgba(0,0,0,.18));
    animation:chartDotPop .35s ease-out forwards;animation-delay:calc(var(--delay,0s) + .9s);}
  @keyframes chartPing{0%{transform:scale(.7);opacity:.5;}100%{transform:scale(2.4);opacity:0;}}
  .chart-dot-ping{transform-box:fill-box;transform-origin:center;opacity:0;
    animation:chartPing 1.8s cubic-bezier(.2,.6,.4,1) calc(var(--delay,0s) + 1.05s) infinite;}
  @keyframes barGrow{from{transform:scaleY(0);}to{transform:scaleY(1);}}
  .chart-bar{transform-box:fill-box;transform-origin:bottom;animation:barGrow .55s cubic-bezier(.4,0,.2,1) both;
    animation-delay:var(--delay,0s);filter:drop-shadow(0 1px 1px rgba(0,0,0,.05));}
  /* Donut segment: position (dashoffset) is static and correct from the
     start — only the dash *length* grows in, via --seg-len/--seg-gap set
     per-segment in JS, so each ring slice draws in place rather than
     sliding into position. */
  @keyframes donutDraw{from{stroke-dasharray:0 100;}to{stroke-dasharray:var(--seg-len) var(--seg-gap);}}
  .chart-seg{stroke-dasharray:0 100;animation:donutDraw .8s cubic-bezier(.4,0,.2,1) forwards;
    animation-delay:var(--delay,0s);filter:drop-shadow(0 1px 1px rgba(0,0,0,.08));}
  @media (prefers-reduced-motion:reduce){
    .chart-line,.chart-area,.chart-dot,.chart-bar{animation:none;stroke-dashoffset:0;opacity:1;transform:none;}
    .chart-dot-ping{display:none;}
    .chart-seg{animation:none;stroke-dasharray:var(--seg-len) var(--seg-gap);}
  }

  /* Hover: an invisible per-index hit column drives a crosshair + tooltip via
     the delegated handler in app.js (initChartTooltip). */
  .chart-hit{cursor:crosshair;}
  .chart-crosshair{stroke:var(--border-soft);stroke-width:1;stroke-dasharray:3 3;opacity:0;pointer-events:none;}
  .chart-crosshair.show{opacity:1;}
  .chart-hover-dot{opacity:0;pointer-events:none;stroke:#fff;stroke-width:1.5;
    filter:drop-shadow(0 1px 2px rgba(0,0,0,.2));}
  .chart-hover-dot.show{opacity:1;}
  .chart-tooltip{position:fixed;z-index:60;background:#fff;border:1px solid var(--border);border-radius:10px;
    box-shadow:0 12px 32px rgba(0,0,0,.14);padding:10px 12px;font-size:12px;pointer-events:none;
    opacity:0;transform:translateY(4px);transition:opacity .1s ease,transform .1s ease;min-width:130px;}
  .chart-tooltip.show{opacity:1;transform:translateY(0);}
  .chart-tip-label{font-weight:600;color:var(--text);margin-bottom:6px;}
  .chart-tip-row{display:flex;align-items:center;gap:6px;padding:2px 0;}
  .chart-tip-dot{width:7px;height:7px;border-radius:999px;flex:0 0 auto;}
  .chart-tip-name{color:var(--muted);flex:1;white-space:nowrap;}
  .chart-tip-value{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums;margin-left:10px;white-space:nowrap;}
  .chart-xaxis{display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-top:8px;padding:0 2px;}
  .chart-legend{display:flex;gap:20px;margin-top:14px;flex-wrap:wrap;}
  .legend-item{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--muted);}
  .legend-dot{width:8px;height:8px;border-radius:999px;flex:0 0 auto;}

  .settings-grid{display:flex;flex-wrap:wrap;gap:16px;}
  .settings-card{background:var(--surface-nested);border:1px solid var(--border);border-radius:12px;padding:16px 18px;
    display:flex;flex-direction:column;gap:12px;width:374px;cursor:default;}
  .settings-card.clickable{cursor:pointer;}
  .settings-card.clickable:hover{border-color:var(--border-soft);}
  .settings-icon-bg{width:40px;height:40px;border-radius:10px 10px 10px 2px;display:flex;align-items:center;justify-content:center;}
  .settings-card h4{font-size:16px;font-weight:600;letter-spacing:-.02em;margin-bottom:4px;}
  .settings-card p{font-size:13px;color:var(--muted);}
  .section-block{background:var(--surface-nested);border-radius:8px;padding:16px;display:flex;flex-direction:column;gap:14px;}
  .section-block h3{font-size:16px;font-weight:600;letter-spacing:-.02em;}

  .field-group{background:var(--surface-nested);border-radius:12px;padding:24px;display:flex;gap:40px;}
  .field-group .field-label{width:340px;flex:0 0 340px;display:flex;flex-direction:column;gap:8px;}
  .field-group .field-label h4{font-size:16px;font-weight:600;letter-spacing:-.02em;}
  .field-group .field-label p{font-size:14px;color:var(--muted);}
  .field-group .field-body{flex:1;display:flex;flex-direction:column;gap:16px;min-width:0;}
  .form-field label{display:block;font-size:14px;font-weight:500;margin-bottom:6px;}
  .form-input{width:100%;background:#fff;border:1px solid var(--border);border-radius:8px;padding:9px 12px;
    font-size:14px;font-family:inherit;color:var(--text);outline:none;}
  .form-input:focus{border-color:var(--muted3);}
  .form-input[readonly]{background:var(--surface-nested);color:var(--muted);cursor:default;}
  .toggle-row{display:flex;gap:12px;align-items:flex-start;}
  .toggle{width:36px;height:20px;border-radius:999px;flex:0 0 auto;position:relative;margin-top:0;
    transition:background .15s ease;}
  .toggle.clickable{cursor:pointer;}
  .toggle.on{background:#d96626;}
  .toggle.off{background:#778ba6;}
  .toggle-knob{position:absolute;top:2px;width:16px;height:16px;border-radius:999px;background:#fff;
    transition:left .15s ease;}
  .toggle.on .toggle-knob{left:18px;}
  .toggle.off .toggle-knob{left:2px;}
  .toggle-text strong{display:block;font-size:14px;font-weight:500;}
  .toggle-text span{display:block;font-size:13px;color:var(--muted);margin-top:2px;}
  .link-line{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:500;color:var(--brand-link);margin-top:2px;}
  .link-line .icon{width:14px;height:14px;}

  .promo-banner{background:var(--surface-nested);border-radius:12px;padding:24px 28px;display:flex;gap:24px;justify-content:space-between;}
  .promo-links{display:flex;flex-direction:column;gap:6px;margin-top:6px;}
  .promo-links .link-line{margin-top:0;}

  .source-card{border-radius:12px;overflow:hidden;width:300px;background:var(--bg);}
  .source-thumb{height:120px;display:flex;align-items:center;justify-content:center;}
  .source-body{padding:16px;}
  .source-title-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;}
  .source-title-row strong{font-size:16px;font-weight:600;letter-spacing:-.02em;}
  .status-pill{padding:2px 8px;border-radius:999px;font-size:12px;font-weight:500;}
  .status-live{background:var(--green-bg);color:var(--green-text);}
  .status-notlive{background:var(--bg);color:var(--muted);}
  .source-desc{font-size:13px;color:var(--muted);margin-bottom:12px;}
  .source-row{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;}
  .source-left{display:flex;align-items:center;gap:10px;}
  .source-status-dot{width:16px;height:16px;border-radius:999px;flex:0 0 auto;}
  .service-mark{width:24px;height:24px;border-radius:6px;display:flex;align-items:center;justify-content:center;
    font-size:10px;font-weight:700;color:#fff;flex:0 0 auto;}
  /* Text wordmark standing in for a source's own logo (e.g. this org's help
     center) — same idiom as the sidenav's "EH" mark, just inline-sized. */
  .wordmark{font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted3);white-space:nowrap;}
  /* Bordered list of source rows — a step lighter/tighter than .card, which
     is why it's its own class rather than .card + an override. */
  .source-list{background:#fff;border:.5px solid var(--border-soft);border-radius:8px;overflow:hidden;}

  .tabs-row{display:flex;gap:0;padding:0 24px;background:#fff;border-bottom:1px solid var(--border);}
  .tab{padding:16px 12px;font-size:14px;font-weight:500;color:var(--muted);border-bottom:2px solid transparent;
    cursor:default;}
  /* Black underline, not red — matches the same Segmented Tab used for the
     context panel's User/History/Resources (.side-tab.active) per spec. */
  .tab.active{color:var(--text);border-color:var(--text);font-weight:600;}
  .tab.clickable{cursor:pointer;}
  .tab.clickable:hover{color:var(--text);}

  .segment-row{display:flex;gap:4px;background:var(--pill);border-radius:999px;padding:2px;width:fit-content;}
  .segment-pill{padding:6px 12px;border-radius:999px;font-size:14px;font-weight:500;color:var(--muted);cursor:default;}
  .segment-pill.active{background:#fff;color:var(--text);box-shadow:0 1px 2px rgba(0,0,0,.06);}
  .segment-pill.clickable{cursor:pointer;}
  .segment-pill.clickable:hover{filter:brightness(.97);}

  /* Topic example panels: one visible at a time, toggled by selectTopicTab(). */
  .topic-examples{display:none;gap:12px;flex-wrap:wrap;margin-top:16px;}
  .topic-examples.active{display:flex;}
  /* Flat, not floating — this sits inside an already-elevated .card, so it
     matches .stat-tile's nested-surface treatment rather than adding a
     second shadow (see README's "one elevation" rule). */
  .example-card{background:var(--surface-nested);border-radius:12px;padding:14px 16px;
    display:flex;flex-direction:column;gap:8px;flex:1;min-width:260px;}
  .example-card-title{font-weight:600;font-size:14px;letter-spacing:-.02em;}
  .example-card-quote{font-size:13px;color:var(--muted);background:var(--pill);
    border-radius:8px;padding:10px 12px;}

