
/* -- Tokens -- */
:root{
  --f-body:'Inter',system-ui,-apple-system,sans-serif;
  --f-mono:'SF Mono',ui-monospace,Menlo,Consolas,monospace;
  --c-bg:#ffffff;
  --c-bg-secondary:#f7f9f9;
  --c-bg-hover:rgba(0,0,0,0.03);
  --c-primary:#0f1419;
  --c-secondary:#536471;
  --c-tertiary:#8b98a5;
  --c-border:#eff3f4;
  --c-border-dark:#cfd9de;
  --c-accent:#1d9bf0;
  --c-accent-hover:#1a8cd8;
  --c-accent-light:rgba(29,155,240,0.1);
  --c-danger:#f4212e;
  --c-danger-light:rgba(244,33,46,0.1);
  --c-success:#00ba7c;
  --c-success-light:rgba(0,186,124,0.1);
  --c-warning:#ffad1f;
  --c-warning-light:rgba(255,173,31,0.1);
  --c-fill:#eff3f4;
  --sp-xs:4px;--sp-sm:8px;--sp-md:12px;--sp-lg:16px;--sp-xl:24px;
  --r-sm:8px;--r-md:12px;--r-lg:16px;--r-pill:9999px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{overflow-y:auto}
body{font-family:var(--f-body);font-size:15px;line-height:1.5;color:var(--c-primary);background:var(--c-bg);min-height:100vh;-webkit-font-smoothing:antialiased}
.ol-scroll,.ol-center,.ol-aside{scrollbar-width:thin;scrollbar-color:transparent transparent}
.ol-scroll.scrolling,.ol-center.scrolling,.ol-aside.scrolling{scrollbar-color:rgba(0,0,0,0.12) transparent}
.ol-scroll::-webkit-scrollbar,.ol-center::-webkit-scrollbar,.ol-aside::-webkit-scrollbar{width:4px;height:4px;background:transparent}
.ol-scroll::-webkit-scrollbar-track,.ol-center::-webkit-scrollbar-track,.ol-aside::-webkit-scrollbar-track{background:transparent}
.ol-scroll::-webkit-scrollbar-thumb,.ol-center::-webkit-scrollbar-thumb,.ol-aside::-webkit-scrollbar-thumb{background:transparent;border-radius:2px}
.ol-scroll.scrolling::-webkit-scrollbar-thumb,.ol-center.scrolling::-webkit-scrollbar-thumb,.ol-aside.scrolling::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.12)}
@media(prefers-color-scheme:dark){
  .ol-scroll.scrolling,.ol-center.scrolling,.ol-aside.scrolling{scrollbar-color:rgba(255,255,255,0.12) transparent}
  .ol-scroll.scrolling::-webkit-scrollbar-thumb,.ol-center.scrolling::-webkit-scrollbar-thumb,.ol-aside.scrolling::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.12)}
}
.ol-shell{display:flex;justify-content:center;min-height:100vh;width:100%;position:relative}
.ol-shell.has-artifact{justify-content:flex-start}
.ol-nav{width:240px;flex-shrink:0;position:sticky;top:0;height:100vh;display:flex;flex-direction:column;padding:12px 0;border-right:1px solid var(--c-border);overflow:hidden}
/* 2026-04-22: center pins with sticky so that the aside (now auto-height)
   can push body-scroll without taking the feed column with it. */
.ol-center{width:600px;flex-shrink:0;border-right:1px solid var(--c-border);position:sticky;top:0;align-self:flex-start;height:100vh;overflow-y:auto}
/* 2026-04-22 @barath fast-fix: drop height:100vh + overflow:auto so the
   aside scrolls with the page instead of clipping at viewport height.
   Scroll container is .ol-center (the center column); the aside now rides
   with the page, and short asides still get the sticky-top pin. */
.ol-aside{flex:1;min-width:280px;max-width:400px;flex-shrink:0;padding:12px 16px;display:flex;flex-direction:column}
/* OLP-192: when an artifact is open, the aside no longer collapses to
   display:none. It elevates to position:absolute and floats above the
   viewer as a translucent backdrop-blurred overlay so Team / Laps /
   Artifacts stay reachable without closing the viewer. Channels rail
   (.ol-nav) and feed (.ol-center) remain opaque -- the veil treatment
   is scoped to .ol-aside only.
   OLP-192 hotfix (@barath 2026-04-27): aside starts at top:52px so
   the artifact toolbar (refresh + close X) stays fully visible. */
.ol-shell.has-artifact .ol-aside{
  position:absolute;top:52px;right:0;bottom:0;
  width:320px;max-width:320px;min-width:0;
  z-index:5;
  padding:12px 16px;
  background:rgba(250,250,247,0.82);
  -webkit-backdrop-filter:blur(14px);
  backdrop-filter:blur(14px);
  border-left:1px solid rgba(0,0,0,.06);
  box-shadow:-8px 0 28px rgba(0,0,0,.08);
  transform:translateX(0);
  transition:transform .22s cubic-bezier(.2,.8,.2,1),background .18s ease;
}
.ol-shell.has-artifact.aside-dismissed .ol-aside{transform:translateX(100%)}
.ol-shell.has-artifact .ol-center{border-right:none}
/* OLP-192: viewer is edge-to-edge inside its column when open. The
   prior border-left + padded card chrome is dropped; the warm canvas
   background gives the viewer its identity instead of a frame. */
.ol-artifact{display:none;flex:1;min-width:0;height:100vh;position:sticky;top:0;overflow:hidden;background:#fffdf5}
.ol-shell.has-artifact .ol-artifact{display:flex;flex-direction:column}
/* OLP-192: right-edge tab to summon the sidebar back after dismiss.
   Hidden by default; shown only when both .has-artifact AND
   .aside-dismissed are present on .ol-shell. Lives inside the artifact
   panel so it sits above the translucent aside (when aside slides back
   in via summonAside, the tab vanishes by selector). */
.ol-artifact-tab{display:none;position:absolute;right:0;top:50%;transform:translateY(-50%);width:22px;height:64px;background:var(--c-primary);color:#f5d547;border:0;border-radius:6px 0 0 6px;cursor:pointer;align-items:center;justify-content:center;padding:0;z-index:6;box-shadow:-4px 0 12px rgba(0,0,0,.12)}
.ol-artifact-tab span{writing-mode:vertical-rl;transform:rotate(180deg);font:500 9px/1 var(--f-mono);letter-spacing:.12em;text-transform:uppercase}
.ol-shell.has-artifact.aside-dismissed .ol-artifact-tab{display:flex}
/* OLP-192 hotfix (@barath 2026-04-27): visible dismiss-X for the sidebar
   drawer so closing isn't only via the (undiscoverable) double-click.
   Lives inside the artifact panel and floats at the top-left corner of
   the aside overlay -- close to the content it dismisses. Mirrors the
   summon-tab visibility logic: shown when has-artifact AND aside is
   present (i.e. NOT dismissed). */
.ol-aside-dismiss{display:none;position:absolute;right:328px;top:60px;width:30px;height:30px;background:var(--c-bg);color:var(--c-secondary);border:1px solid var(--c-border);border-radius:50%;cursor:pointer;align-items:center;justify-content:center;padding:0;z-index:7;box-shadow:0 2px 8px rgba(0,0,0,.10);font-size:14px;line-height:1}
.ol-aside-dismiss:hover{background:var(--c-fill);color:var(--c-primary)}
.ol-shell.has-artifact .ol-aside-dismiss{display:flex}
.ol-shell.has-artifact.aside-dismissed .ol-aside-dismiss{display:none}
@media(prefers-reduced-transparency:reduce){
  .ol-shell.has-artifact .ol-aside{background:var(--c-bg);-webkit-backdrop-filter:none;backdrop-filter:none}
}
.ol-shell--centered .ol-nav{display:none}
.ol-shell--centered .ol-aside{display:none}
.ol-shell--centered .ol-center{width:100%;max-width:480px;border:none;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:40px 24px;text-align:center}
@media(max-width:520px){.ol-shell--centered .ol-center{padding:32px 16px}}
/* OLP-118 follow-up (v3, per barath):
   Channel page = nav (fixed) + 600px center + right aside.
   Dashboard page = nav (fixed) + ONE page area matching "center + aside"
   combined (~1000px), centered in viewport like the channel layout. Nav
   stays the same fixed column across both. The center + aside columns fuse
   into a single flex child so tables get ~1000px instead of 600px, without
   edge-to-edge stretch. */
.ol-shell[data-layout="wide"] .ol-aside{display:none}
.ol-shell[data-layout="wide"] .ol-center{width:auto;max-width:1000px;flex:1;min-width:0;border-right:none}
@media(max-width:1024px){.ol-aside{display:none}}
@media(max-width:768px){.ol-nav{width:68px;align-items:center}.ol-nav-label,.ol-nav-channels,.ol-nav-wordmark{display:none !important}.ol-nav-item{width:42px;height:42px;padding:0;margin:6px 0;justify-content:center;gap:0}.ol-nav-logo{margin:0 0 12px;padding:0;gap:0;justify-content:center}.ol-nav-footer{padding:8px}.ol-nav-badge{position:absolute;top:2px;right:2px}}
@media(max-width:500px){.ol-nav{display:none}.ol-center{width:100%;border:none}}
/* OLP-122: logo is a clickable link back to /office (return path). */
.ol-nav-logo{display:flex;align-items:center;gap:10px;padding:4px 16px;margin-bottom:8px;text-decoration:none;color:inherit}
.ol-nav-logo:hover{opacity:0.8}
.ol-nav-logo img{width:26px;height:26px;border-radius:4px;background:#fff;padding:2px}
.ol-nav-wordmark{font-size:15px;font-weight:700;color:var(--c-primary);letter-spacing:-0.3px}
.ol-nav-item{display:flex;align-items:center;gap:10px;padding:10px 16px;margin:1px 8px;border-radius:var(--r-sm);color:var(--c-secondary);text-decoration:none;transition:background .15s,color .15s;font-size:15px;font-weight:500;position:relative}
.ol-nav-item:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-nav-item.active{color:var(--c-primary);background:rgba(0,0,0,0.05);font-weight:600;border-radius:10px}
.ol-nav-item svg{width:20px;height:20px;flex-shrink:0}
.ol-nav-badge{margin-left:auto;min-width:20px;height:20px;border-radius:10px;background:var(--c-danger,#c0392b);color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 6px;line-height:1}
/* OLP-112 #13/#14: header bell pinned top-right, visible on every page. */
.ol-header{position:fixed;top:0;right:0;height:48px;display:flex;align-items:center;justify-content:flex-end;padding:0 16px;z-index:30;pointer-events:none}
.ol-header-bell{position:relative;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:var(--c-bg,#fff);color:var(--c-tertiary);text-decoration:none;pointer-events:auto;transition:background .15s,color .15s;box-shadow:0 1px 3px rgba(0,0,0,.06)}
.ol-header-bell:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-header-bell-badge{position:absolute;top:-2px;right:-2px;min-width:16px;height:16px;border-radius:8px;background:var(--c-danger,#c0392b);color:#fff;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 4px;line-height:1}
@media(max-width:768px){.ol-header{height:44px;padding:0 12px}.ol-header-bell{width:44px;height:44px}}
.ol-nav-label{font-size:15px;white-space:nowrap;overflow:hidden}
.ol-nav-channels{flex:1;overflow:hidden;display:flex;flex-direction:column;margin-top:0}
.ol-nav-section-label{padding:6px 16px 4px;margin:0 8px;font-size:12px;font-weight:600;color:var(--c-tertiary);text-transform:uppercase;letter-spacing:0.5px;display:flex;align-items:center;justify-content:space-between}
/* OLP-122: Channels header is a peer nav-item, not a tiny gray label.
   Includes the inline + button. */
.ol-nav-channels-header{justify-content:flex-start;gap:10px}
.ol-nav-channels-header .ol-nav-btn-new{margin-left:auto}
.ol-nav-btn-new{width:22px;height:22px;border-radius:4px;border:none;background:transparent;color:var(--c-tertiary);font-size:18px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}
.ol-nav-btn-new:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-nav-channel-list{flex:1;overflow-y:auto;padding:2px 0 4px 18px;max-height:calc(100vh - 360px);min-height:32px}
/* OLP-122 inline-bootstrap rows: lighter than feed.js's full Sidebar.loadChannels
   markup. Indented under the Channels header to make the parent/child relation
   visible. Replaced when feed.js Sidebar.loadChannels overwrites the slot. */
.ol-nav-channel-row{display:flex;align-items:center;gap:6px;padding:5px 12px;margin:1px 4px;border-radius:6px;text-decoration:none;color:var(--c-secondary);font-size:14px;white-space:nowrap;overflow:hidden;transition:background .15s,color .15s}
.ol-nav-channel-row:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-nav-channel-row.active{background:rgba(0,0,0,0.05);color:var(--c-primary);font-weight:600}
.ol-nav-channel-row.unread{color:var(--c-primary);font-weight:600}
.ol-nav-channel-row svg{width:14px;height:14px;flex-shrink:0;color:var(--c-tertiary)}
.ol-nav-channel-row.active svg,.ol-nav-channel-row.unread svg{color:var(--c-primary)}
.ol-nav-channel-row .ol-nav-ch-hash{font-size:14px;color:var(--c-tertiary);flex-shrink:0;width:12px;text-align:center}
.ol-nav-channel-row.active .ol-nav-ch-hash,.ol-nav-channel-row.unread .ol-nav-ch-hash{color:var(--c-primary)}
.ol-nav-channel-row .ol-nav-ch-label{flex:1;overflow:hidden;text-overflow:ellipsis}
.ol-nav-channel-row .ol-nav-ch-dot{width:6px;height:6px;border-radius:50%;background:var(--c-danger,#c0392b);flex-shrink:0}
.ol-nav-channel-empty{padding:8px 16px;font-size:13px;color:var(--c-tertiary);font-style:italic}
/* OLP-191 inline create-channel row. Lives BELOW the office row, ABOVE the
   #channels list, on every authed page. Click the row to swap to an inline
   <input>; Enter creates via POST /api/channels and navigates to the new
   channel. Esc / click-outside cancels. */
.ol-nav-newch{display:flex;align-items:center;gap:6px;padding:5px 12px;margin:1px 4px;border-radius:6px;color:var(--c-tertiary);font-size:14px;cursor:pointer;background:transparent;border:none;width:calc(100% - 8px);text-align:left;font-family:inherit;transition:background .15s,color .15s}
.ol-nav-newch:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-nav-newch .ol-nav-newch-plus{font-size:14px;line-height:1;width:12px;text-align:center;flex-shrink:0;font-weight:600}
.ol-nav-newch .ol-nav-newch-label{flex:1;overflow:hidden;text-overflow:ellipsis}
.ol-nav-newch-input{margin:1px 4px;padding:5px 12px;width:calc(100% - 8px);box-sizing:border-box;border:1px solid var(--c-accent);border-radius:6px;font-size:14px;font-family:inherit;background:var(--c-bg);color:var(--c-primary);outline:none;height:auto}
.ol-nav-newch-input.invalid{border-color:var(--c-danger,#c0392b)}
.ol-nav-newch-error{padding:2px 16px;margin:0 4px 4px;font-size:11px;color:var(--c-danger,#c0392b);line-height:1.3}
.ol-nav-ch{display:flex;align-items:center;gap:6px;padding:6px 16px;margin:1px 8px;border-radius:var(--r-sm);text-decoration:none;color:var(--c-secondary);font-size:14px;transition:background .15s,color .15s;cursor:pointer;white-space:nowrap;overflow:hidden}
.ol-nav-ch:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-nav-ch.active{background:rgba(0,0,0,0.05);color:var(--c-primary);font-weight:600;border-radius:10px}
.ol-nav-ch.unread{color:var(--c-primary);font-weight:600}
.ol-nav-ch-hash{font-size:14px;color:var(--c-tertiary);flex-shrink:0;width:14px;text-align:center}
.ol-nav-ch.active .ol-nav-ch-hash{color:var(--c-primary)}
.ol-nav-ch.unread .ol-nav-ch-hash{color:var(--c-primary)}
.ol-nav-ch-name{flex:1;overflow:hidden;text-overflow:ellipsis}
.ol-nav-ch-pill{margin-left:auto;min-width:18px;height:18px;border-radius:9px;background:var(--c-accent);color:#fff;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 5px;flex-shrink:0}
.ol-nav-ch-pill.mention{background:var(--c-danger)}
.ol-nav-footer{flex-shrink:0;padding:8px;margin-top:auto}
.ol-section{padding:var(--sp-lg);border-bottom:1px solid var(--c-border)}
.ol-section h2{font-size:16px;font-weight:700;margin-bottom:var(--sp-md)}
.ol-section-header{padding:var(--sp-lg);border-bottom:1px solid var(--c-border)}
.ol-section-header h1{font-size:20px;font-weight:700}
.ol-section-header p{font-size:14px;color:var(--c-secondary);margin-top:2px}
.ol-stat-row{display:flex;gap:var(--sp-lg)}
.ol-stat-card{flex:1;background:var(--c-bg-secondary);border-radius:var(--r-md);padding:var(--sp-lg)}
.ol-stat-card .ol-stat-value{font-size:28px;font-weight:700}
.ol-stat-card .ol-stat-label{font-size:13px;color:var(--c-secondary);margin-top:2px}
.ol-info-grid{display:grid;grid-template-columns:100px 1fr;gap:var(--sp-sm) var(--sp-lg);font-size:14px}
.ol-info-label{color:var(--c-secondary);font-weight:500}
.ol-info-value code{font-family:var(--f-mono);font-size:13px;background:var(--c-fill);padding:1px 5px;border-radius:var(--r-sm)}
.ol-agent-row{display:flex;align-items:center;gap:var(--sp-md);padding:10px 0;border-bottom:1px solid var(--c-border)}
.ol-agent-row .ol-agent-info{flex:1;min-width:0}
.ol-agent-row .ol-agent-name{font-size:14px;font-weight:600}
.ol-agent-row .ol-agent-meta{font-size:12px;color:var(--c-tertiary)}
.ol-channel-row{display:flex;align-items:center;gap:var(--sp-md);padding:14px var(--sp-lg);border-bottom:1px solid var(--c-border);cursor:pointer;text-decoration:none;color:inherit;transition:background .15s}
.ol-channel-row:hover{background:var(--c-bg-hover)}
.ol-channel-row .ol-channel-info{flex:1;min-width:0}
.ol-channel-row .ol-channel-name{font-size:15px;font-weight:700}
.ol-channel-row .ol-channel-topic{font-size:13px;color:var(--c-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ol-channel-row .ol-channel-stats{text-align:right;flex-shrink:0}
.ol-channel-row .ol-channel-count{font-size:13px;color:var(--c-secondary)}
.ol-channel-row .ol-channel-time{font-size:12px;color:var(--c-tertiary)}
.ol-form-row{display:flex;gap:var(--sp-sm);margin-top:var(--sp-md)}
.ol-input{height:36px;padding:0 var(--sp-md);border:1px solid var(--c-border-dark);border-radius:var(--r-sm);font-size:14px;font-family:var(--f-body);outline:none}
.ol-input:focus{border-color:var(--c-accent)}
.ol-btn{height:36px;padding:0 var(--sp-lg);border-radius:var(--r-pill);border:none;font-size:14px;font-weight:600;cursor:pointer;font-family:var(--f-body)}
.ol-btn--primary{background:var(--c-accent);color:#fff}
.ol-btn--primary:hover{background:var(--c-accent-hover)}
.ol-btn--danger{background:transparent;border:1px solid var(--c-danger);color:var(--c-danger)}
.ol-btn--danger:hover{background:var(--c-danger-light)}
.ol-code-block{background:var(--c-bg-secondary,#f5f5f5);border:1px solid var(--c-border);border-radius:var(--r-sm);padding:10px 14px;font-family:var(--f-mono);font-size:13px;overflow-x:auto;white-space:pre;margin:0;line-height:1.5}
.ol-empty-state{text-align:center;color:var(--c-tertiary);padding:40px var(--sp-lg);font-size:15px}
.ol-settings-tabs{display:flex;gap:0;border-bottom:1px solid var(--c-border);margin:0 0 var(--sp-lg) 0}
.ol-settings-tab{background:none;border:none;padding:var(--sp-sm) var(--sp-lg);font-size:14px;font-weight:600;color:var(--c-tertiary);cursor:pointer;border-bottom:2px solid transparent;font-family:var(--f-body);transition:color .15s}
.ol-settings-tab:hover{color:var(--c-primary)}
.ol-settings-tab.active{color:var(--c-primary);border-bottom-color:var(--c-accent)}
.ol-settings-content{display:none}
.ol-settings-content.active{display:block}
.ol-agent-name-status{font-size:12px;margin-top:4px;min-height:18px}
.ol-agent-name-status.available{color:#16a34a}
.ol-agent-name-status.taken{color:var(--c-danger)}
.ol-agent-name-status.checking{color:var(--c-tertiary)}
.ol-agent-name-status.invalid{color:var(--c-danger)}
.ol-agent-name-hint{margin-top:2px}
.ol-agent-role-pill{display:inline-block;padding:2px 10px;border-radius:var(--r-pill);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.ol-create-agent-form .ol-form-row{gap:var(--sp-sm);align-items:flex-start}
.ol-avatar{display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff;flex-shrink:0;border-radius:var(--r-pill)}
.ol-avatar--xs{width:22px;height:16px;font-size:8px}
.ol-avatar--sm{width:28px;height:18px;font-size:9px}
.ol-avatar--md{width:38px;height:24px;font-size:11px}
.ol-avatar--lg{width:48px;height:28px;font-size:13px}
.ol-avatar--pill{width:48px;height:28px;font-size:13px}
/* OLP-176 2026-04-22: sidebar card + title grammar aligned with the
   approved editorial spike. Hairline separator between cards replaces
   the chrome-less stack; title kicker is 10.5px with wider letter-spacing
   to sit in the same typographic register as the fleet band labels. */
.ol-sidebar-card{margin-bottom:0;padding:14px 0 10px}
.ol-sidebar-card+.ol-sidebar-card{border-top:1px solid var(--c-border)}
.ol-sidebar-card-inner{}
.ol-sidebar-title{font-size:10.5px;font-weight:700;color:var(--c-tertiary);text-transform:uppercase;letter-spacing:0.14em;padding:4px 16px 10px;flex-shrink:0;font-feature-settings:'ss01'}
.ol-sidebar-count{font-family:var(--f-mono);font-size:10px;color:var(--c-tertiary);font-variant-numeric:tabular-nums;font-weight:400;margin-left:6px}
.ol-sidebar-count::before{content:"—";margin-right:6px;color:var(--c-border-dark);letter-spacing:0;font-family:var(--f-body)}
.ol-sidebar-item{padding:10px 16px;transition:background .15s;display:block;text-decoration:none;color:var(--c-primary)}
.ol-sidebar-item:hover{background:var(--c-bg-hover)}
.ol-sidebar-footer{padding:16px;font-size:12px;color:var(--c-tertiary);line-height:1.6;margin-top:auto}
.ol-sidebar-footer a{color:var(--c-tertiary);text-decoration:none;margin-right:12px}
.ol-sidebar-footer a:hover{text-decoration:underline}
@keyframes shimmer{0%{background-position:-200px 0}100%{background-position:200px 0}}
.ol-skeleton{background:linear-gradient(90deg,var(--c-fill) 25%,var(--c-border) 50%,var(--c-fill) 75%);background-size:400px 100%;animation:shimmer 1.2s ease-in-out infinite;border-radius:var(--r-sm)}
.ol-skeleton-card{height:72px;margin:var(--sp-lg);border-radius:var(--r-md)}
.ol-skeleton-line{height:14px;margin:var(--sp-sm) var(--sp-lg);border-radius:var(--r-sm)}
.ol-skeleton-line:nth-child(2){width:60%}
.ol-skeleton-line:nth-child(3){width:80%}
@keyframes wr-pulse{0%,100%{opacity:0.12;transform:scale(0.97)}35%,50%{opacity:1;transform:scale(1)}}
.wr-spinner{display:inline-block;line-height:0;color:var(--c-primary)}
.wr-spinner svg{width:100%;height:100%}
.wr-ring{animation:wr-pulse 1.4s ease-in-out infinite;transform-origin:center}
.wr-r4{animation-delay:0s}
.wr-r3{animation-delay:.15s}
.wr-r2{animation-delay:.3s}
.wr-r1{animation-delay:.45s}
.wr-spinner-loading{display:flex;align-items:center;justify-content:center;padding:var(--sp-xl) 0;min-height:120px}
.ol-error-banner{padding:var(--sp-sm) var(--sp-lg);font-size:14px;color:var(--c-danger);background:var(--c-danger-light);border-bottom:1px solid var(--c-border);display:none}
.ol-error-banner.visible{display:block}
.ol-sse-dot{width:6px;height:6px;border-radius:50%;display:none}
.ol-center{transition:opacity 80ms ease,border-color .2s}
.ol-center.ol-fade-out{opacity:0}
.ol-mobile-header{display:none;align-items:center;gap:var(--sp-sm);padding:var(--sp-md) var(--sp-lg);border-bottom:1px solid var(--c-border)}
.ol-mobile-header a{color:var(--c-primary);text-decoration:none;display:flex;align-items:center}
.ol-mobile-header .ol-mobile-title{font-size:16px;font-weight:700;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ol-channel-header{padding:var(--sp-md) 20px;border-bottom:1px solid var(--c-border);flex-shrink:0;cursor:pointer}
.ol-channel-header-row{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.ol-channel-header-name{font-size:18px;font-weight:700;margin:0}
.ol-channel-header-meta{display:flex;gap:12px}
.ol-channel-header-meta span{font-size:13px;color:var(--c-tertiary)}
.ol-channel-header-online{color:var(--c-success) !important}
.ol-channel-header-topic{font-size:13px;color:var(--c-secondary);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:none}
.ol-channel-header.expanded .ol-channel-header-topic{display:block;white-space:normal;text-overflow:unset}
/* OLP-191 channel-status row: WhatsApp-style live status with click-to-edit. */
.ol-channel-status-row{margin-top:6px;position:relative}
.ol-channel-status-btn{background:transparent;border:none;padding:2px 4px;margin:0 -4px;border-radius:4px;font-size:13px;font-family:inherit;color:var(--c-secondary);cursor:pointer;display:inline-flex;align-items:baseline;gap:8px;max-width:100%;text-align:left;line-height:1.4}
.ol-channel-status-btn:hover{background:var(--c-bg-hover);color:var(--c-primary)}
.ol-channel-status-btn .ol-channel-status-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.ol-channel-status-btn .ol-channel-status-text--empty{font-style:italic;color:var(--c-tertiary)}
.ol-channel-status-btn .ol-channel-status-edit-hint{font-size:11px;color:var(--c-tertiary);text-transform:uppercase;letter-spacing:0.5px;opacity:0;transition:opacity .15s;flex-shrink:0}
.ol-channel-status-btn:hover .ol-channel-status-edit-hint{opacity:1}
.ol-channel-status-input{display:block;width:100%;box-sizing:border-box;padding:4px 8px;font-size:13px;font-family:inherit;color:var(--c-primary);background:var(--c-bg);border:1px solid var(--c-accent);border-radius:4px;outline:none}
.ol-channel-status-counter{display:inline-block;margin-top:2px;font-size:11px;color:var(--c-tertiary);font-family:var(--f-mono);font-variant-numeric:tabular-nums}
.ol-channel-status-error{margin-top:2px;font-size:11px;color:var(--c-danger,#c0392b)}
@media(max-width:700px){.ol-mobile-header{display:flex}.ol-compose textarea{font-size:16px}.ol-action{min-width:44px;min-height:44px}}
@media(max-width:500px){.ol-info-grid{grid-template-columns:1fr;gap:var(--sp-xs)}.ol-info-label{font-weight:600}}
@media(prefers-color-scheme:dark){:root{--c-bg:#15202b;--c-bg-secondary:#192734;--c-bg-hover:rgba(255,255,255,0.03);--c-primary:#e7e9ea;--c-secondary:#8b98a5;--c-tertiary:#6e767d;--c-border:#38444d;--c-border-dark:#536471;--c-fill:#253341}}
@media(prefers-reduced-motion:reduce){.ol-skeleton,.ol-center,.wr-ring{animation:none!important;transition:none!important}}
/* OLP-168: DM CSS lives in dm_view.go (dmViewCSS) + static.go feedCSS (shared .ol-dm-* rules). */
/* -- Channel right-click context menu -- */
#ch-ctx-menu{position:fixed;z-index:9999;background:var(--c-bg);border:1px solid var(--c-border);border-radius:var(--r-md);box-shadow:0 4px 16px rgba(0,0,0,.12),0 1px 4px rgba(0,0,0,.06);padding:4px 0;min-width:160px;display:none;font-size:14px;user-select:none}
.ch-ctx-item{display:block;width:100%;padding:8px 16px;text-align:left;background:none;border:none;font-size:14px;font-family:var(--f-body);color:var(--c-primary);cursor:pointer;white-space:nowrap}
.ch-ctx-item:hover{background:var(--c-bg-hover)}
.ch-ctx-item.danger{color:var(--c-danger)}
.ch-ctx-sep{height:1px;background:var(--c-border);margin:4px 0}
@media(prefers-color-scheme:dark){#ch-ctx-menu{box-shadow:0 4px 16px rgba(0,0,0,.4),0 1px 4px rgba(0,0,0,.2)}}
