/* Grand Line members terminal.
   Home and the shared top bar are drawn with the Grand Line design system (docs/design-system/):
   gl-theme.css for colours, type and spacing, bundle.css for the gl-* components. This file lays
   them out and styles the few pieces the system has no component for. Surfaces are set apart by
   tone (the page, then gl-card, then fills), never outlined; only table rows and headers, tier
   lines and card footers carry a 1px --line hairline. Kyle's admin page, Coverage and the social
   tab further down still read tokens.css until they move over in their own PRs. */

.term-body { background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-sans); margin: 0; }
.term-main { padding-top: var(--space-3); }
/* The terminal and Kyle's admin page use the whole window, like the mockup: no site max-width,
   12px side gutters for the boxes and 18px in the top bar. */
.term-body .wrap { max-width: none; }
.term-body .term-main { padding-top: var(--space-3); padding-left: max(var(--space-3), env(safe-area-inset-left, 0px));
  padding-right: max(var(--space-3), env(safe-area-inset-right, 0px)); }
.term-body .topbar-inner { padding-left: max(18px, env(safe-area-inset-left, 0px)); padding-right: max(18px, env(safe-area-inset-right, 0px)); }

/* ── Top bar: TerminalHome's glass bar over hub.css's layout, and the narrow-window Menu panel (site-header.js) ── */
.term-body .topbar { background: var(--bg-glass); -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px); border-bottom: 0; }
.term-body .theme-toggle { padding: 0; border-left: 0; }
.topbar-end { display: flex; align-items: center; gap: var(--space-3); margin-left: auto; }
#gl-nav { display: flex; align-items: center; gap: var(--space-5); margin-left: var(--space-8); }
#gl-nav a { color: var(--text-secondary); text-decoration: none; font-size: 13px; }
#gl-nav a:hover { color: var(--text-primary); }
#gl-nav .gl-appearance { display: none; }
/* The Menu button. site-header.js finds it by button.gl-menu: bundle.css also uses .gl-menu for its popover
   (the notifications bell's Menu sits in this bar too), so these rules name the button, undo the popover's
   width, fill and shadow, and draw it as a small secondary Button. */
.topbar button.gl-menu { display: none; width: auto; height: var(--control-sm); padding: 0 12px; border: 0; border-radius: var(--radius-pill);
  background: var(--fill-2); box-shadow: none; color: var(--text-primary); font: 500 12px/1 var(--font-sans); cursor: pointer; }
.topbar button.gl-menu:hover { background: var(--fill-3); }
.topbar button.gl-menu:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 860px) {
  #gl-nav { display: none; }
  .topbar .theme-toggle { display: none; }
  .topbar button.gl-menu { display: block; }
  header.is-open #gl-nav { display: flex; flex-direction: column; align-items: flex-start;
    gap: var(--space-4); position: absolute; left: 0; right: 0; top: var(--topbar); z-index: 20;
    margin: 0; padding: var(--space-5) var(--gutter); background: var(--bg-overlay); box-shadow: var(--shadow-popover); }
  header.is-open #gl-nav .gl-appearance { display: flex; align-items: center; gap: var(--space-3);
    color: var(--text-secondary); font-size: 13px; }
}

/* ── Account menu, top right (signed in: Log out; previews: switch test account), in AccountChip's look.
   Open, it is solid accent like the Tools trigger (NavTabs' "Menu open"). It opens on hover or click
   (gl-menu-hover.js, site-header.js). ── */
.term-account { position: relative; }
.term-account-trigger { appearance: none; border: 0; cursor: pointer; display: flex; align-items: center; gap: 8px;
  height: var(--control-md); padding: 0 12px 0 14px; border-radius: var(--radius-pill); background: var(--fill-1); color: var(--text-primary);
  font: 500 13px/1 var(--font-sans); white-space: nowrap; }
.term-account-trigger .gl-caret { color: var(--text-tertiary); }
.term-account-trigger:hover { background: var(--fill-2); }
.term-account-trigger:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.term-account-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 220px;
  padding: var(--space-2); background: var(--bg-overlay); border-radius: var(--radius-xl); box-shadow: var(--shadow-popover); }
.term-account-menu form, .gl-account form { margin: 0; }
.term-account-menu button, .gl-account button { appearance: none; display: block; width: 100%; text-align: left;
  background: none; border: 0; border-radius: var(--radius-md); color: var(--text-secondary); font: 500 13px var(--font-sans); padding: 9px var(--space-3); cursor: pointer; }
.term-account-menu button:hover, .gl-account button:hover { background: var(--fill-2); color: var(--text-primary); }
/* Reported chat messages waiting (admins only): the count sits at the end of Admin, and after the
   name on the trigger and the phone's Menu button. */
.term-account-menu button:has(.gl-badge), .gl-account button:has(.gl-badge) { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* On the phone the bar has no room to spare, so the Menu button gets a blue dot inside its top
   right corner (the number is on Admin, inside the menu). On the open (blue) trigger the count
   turns white so it still reads. */
.topbar button.gl-menu { position: relative; }
.topbar button.gl-menu > .gl-badge, .term-bell-dot { width: 7px; height: 7px; min-width: 0; padding: 0;
  border-radius: 50%; font-size: 0; overflow: hidden; flex: none; }
.topbar button.gl-menu > .gl-badge { position: absolute; top: 4px; right: 6px; }
.term-account-trigger[aria-expanded="true"] .gl-badge--strong { background: var(--text-on-fill); color: var(--accent); }
.term-account-menu form:last-child button { color: var(--neg); }
.term-account-who { margin: 0 0 var(--space-1); padding: 6px var(--space-3); font: 400 11px/1.2 var(--font-sans); color: var(--text-tertiary); }
#gl-nav .gl-account { display: none; }
.topbar-end .gl-tip__bubble { bottom: auto; top: calc(100% + 6px); } /* Give feedback's Tooltip opens below: above is off the window */
.topbar-end .gl-tip:not(:hover) .gl-tip__bubble { opacity: 0; visibility: hidden; transition-delay: 0s, .12s; } /* hover only: focus stays on the button after its Dialog closes */
/* The notifications bell ([PRD] - Member Alerts.md, Part A, UI Req 1): an IconButton with its count in
   the top right corner, opening a Menu of ListItems. It stays in the bar on a phone. */
.term-bell > .gl-iconbtn { position: relative; }
.term-bell-count { position: absolute; top: -4px; right: -4px; pointer-events: none; }
.term-bell > .gl-iconbtn[aria-expanded="true"] .term-bell-count { background: var(--text-on-fill); color: var(--accent); }
/* The Menu's max-width (100%) is measured against the bell button, which would hold the panel at its
   200px minimum, so the bell's panel sets its own width and cap. */
.term-bell > .term-bell-menu { width: min(560px, calc(100vw - 32px)); max-width: none; z-index: 30; }
/* On a phone the bell isn't at the bar's right edge, so the panel sits under the (sticky) bar
   across the screen with the usual 16px each side instead of hanging from the bell. */
@media (max-width: 560px) {
  .term-bell > .term-bell-menu { position: fixed; top: calc(var(--topbar) + 4px); left: 16px; right: 16px; width: auto; }
  .term-bell-menu [data-bell-list].is-paged { min-height: calc(5 * 48px); }
}
.term-bell-menu [data-bell-list].is-paged { min-height: calc(8 * 48px); }
.term-bell-pic.term-trades-logo { width: 28px; height: 28px; margin: 0; }
/* A coin's letter, a mention's "@" or a sender's initials in the main text colour, so they stay
   readable on the grey circle in dark mode. */
.term-bell-pic.gl-coin { width: 28px; height: 28px; font-size: 11px; }
.term-bell-menu .term-bell-pic { color: var(--text-primary); }
.term-bell-pages { display: flex; justify-content: space-between; padding: var(--space-2) 2px 0; }
.term-bell-pages .gl-btn:last-child { margin-left: auto; }
/* An unread notification ends with the same blue dot, after its time; "Mark all as read" sits at
   the right of the menu's head. */
.term-bell-menu .gl-item:not(.is-unread) .term-bell-dot { visibility: hidden; }
.term-bell-menu .gl-menu__head { align-items: center; }
.term-bell-note { margin: 0; padding: var(--space-3); font: 400 13px/1.4 var(--font-sans); color: var(--text-tertiary); }
@media (max-width: 860px) {
  .topbar-end > :is(.term-account, .gl-btn, .gl-tip) { display: none; } /* the bar's own; the Give feedback Dialog's and the bell menu's buttons stay */
  header.is-open #gl-nav .gl-account { display: flex; flex-direction: column; width: 100%; }
  header.is-open #gl-nav .gl-account button { padding-left: 0; }
}

/* ── Tabs: NavTabs' pills on a fill-1 track. Drawn on .term-tab itself, so Kyle's admin tabs in the
   same bar match without their markup changing. ── */
.term-tabs { display: inline-flex; align-items: center; gap: 2px; padding: 3px; border-radius: var(--radius-pill); background: var(--fill-1); }
.term-tab { appearance: none; display: inline-flex; align-items: center; gap: 6px; height: 30px; box-sizing: border-box; padding: 0 14px;
  border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary);
  font: 500 13px/1 var(--font-sans); letter-spacing: -0.01em; text-decoration: none; white-space: nowrap; cursor: pointer; }
.term-tab:hover { color: var(--text-primary); background: var(--fill-1); }
.term-tab:active { background: var(--fill-2); }
.term-tab.is-active, .term-tab[aria-selected="true"], .term-tab[aria-current="page"] { color: var(--text-primary); background: var(--fill-selected); box-shadow: var(--shadow-selected); }
.term-tab:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .term-tab, .term-account-trigger { transition: background-color .12s ease-out, color .12s ease-out; }
}
/* In the top bar, right of the logo, with no row of its own under the bar. */
.topbar.has-tabs .brand { margin-right: 0; }
.topbar .term-tabs { flex: none; margin: 0 auto 0 var(--space-6); }
/* Tools: a drop-down of the research tools, opened on hover or click (gl-menu-hover.js, site-header.js); the label itself goes nowhere.
   Open, the trigger is solid accent and its caret turns (above, with the Account menu's). */
.term-tools { position: relative; display: flex; }
/* Either drop-down open: the trigger is solid accent, and its caret turns. After the tabs' own rules,
   so their hover colour (the pointer is on the trigger while hover keeps it open) never wins. */
:is(.term-tools-trigger, .term-account-trigger)[aria-expanded="true"] { color: var(--text-on-fill); background: var(--accent); }
:is(.term-tools-trigger, .term-account-trigger)[aria-expanded="true"]:hover { background: var(--accent-hover); }
:is(.term-tools-trigger, .term-account-trigger)[aria-expanded="true"] .gl-caret { color: inherit; transform: rotate(180deg); }
.term-tools-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 50; min-width: 240px; padding: var(--space-2);
  background: var(--bg-overlay); border-radius: var(--radius-xl); box-shadow: var(--shadow-popover); }
.term-tools-menu a { display: block; padding: 10px; border-radius: var(--radius-md); color: var(--text-primary);
  font: 500 13.5px/1.2 var(--font-sans); letter-spacing: -0.01em; text-decoration: none; white-space: nowrap; }
.term-tools-menu a:hover { background: var(--fill-2); }
.term-tools-menu a[aria-current="page"] { background: var(--accent-tint); }
.term-tools-menu a:active { background: var(--fill-3); }
.term-tools-menu a:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
/* At 680px and below four tabs push the Menu button off the bar, so the tools move into the Menu panel. */
#gl-nav .gl-tools-group { display: none; }
@media (max-width: 680px) {
  .topbar .term-tools { display: none; }
  header.is-open #gl-nav .gl-tools-group { display: flex; flex-direction: column; gap: var(--space-3); }
  #gl-nav .gl-tools-group p { margin: 0; color: var(--text-tertiary); font: 400 11px/1.2 var(--font-sans); }
}
/* hub.css wraps the bar onto two rows at 560px and below. The terminal keeps one row
   (logo, tabs, Menu) to save height, with tighter tabs and, on the narrowest phones, a
   smaller logo. */
@media (max-width: 560px) {
  .topbar.has-tabs { height: var(--topbar); }
  .topbar.has-tabs .topbar-inner { height: 100%; flex-wrap: nowrap; align-items: center; padding: 0 var(--gutter); }
  .topbar.has-tabs .brand { order: 0; height: auto; padding: 0; }
  .topbar .term-tabs { margin-left: var(--space-3); }
  .topbar .term-tab { padding: 0 10px; }
}
@media (max-width: 440px) {
  .topbar.has-tabs .brand img { height: 17px; }
  .topbar .term-tabs { margin-left: var(--space-2); }
  .topbar .term-tabs { padding: 2px; gap: 0; }
  .topbar .term-tab { padding: 0 7px; font-size: 12px; }
  .topbar.has-tabs button.gl-menu { padding: 0 10px; }
}
@media (max-width: 380px) {
  .topbar.has-tabs .topbar-inner { padding: 0 var(--space-3); }
  .topbar.has-tabs .brand img { height: 15px; }
  .topbar .term-tabs { margin-left: var(--space-2); }
  .topbar .term-tab { padding: 0 5px; }
  .topbar.has-tabs button.gl-menu { padding: 0 8px; }
}
/* On a phone the bell and the Menu button are small icon buttons (IconButton's small size, 30px)
   side by side, so the bar keeps one row with the bell in it. */
.term-menu-icon { display: none; }
@media (max-width: 560px) {
  .topbar.has-tabs .topbar-end { gap: var(--space-1); }
  .topbar.has-tabs button.gl-menu, .term-bell > .gl-iconbtn { width: 30px; height: 30px; padding: 0; border-radius: var(--radius-sm); }
  .topbar.has-tabs button.gl-menu { display: grid; place-items: center; }
  .topbar.has-tabs button.gl-menu [data-menu-label] { display: none; }
  .topbar.has-tabs .term-menu-icon { display: block; }
  .term-bell > .gl-iconbtn svg { width: 16px; height: 16px; }
}

/* ── The zeroxkyle tab: a 12-column grid (one column on a phone) ────────────
   Terminal Feed Revamp PRD, UI Req 1. Top left, 8 columns: Analyst Trades. Right, 4 columns
   down both rows: the X feed. Bottom row: the tier list, then the Summary.
   The boxes are in phone order in the page, so a phone only stacks them. */
.term-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--space-3); }
.term-grid > [data-terminal-block="trades"] { grid-column: 1 / 9; grid-row: 1; }
.term-grid > [data-terminal-block="subscriber-feed"] { grid-column: 9 / 13; grid-row: 1 / 3; }
.term-grid > [data-terminal-block="tier-list"] { grid-column: 1 / 5; grid-row: 2; }
.term-grid > [data-terminal-block="summary-24h"] { grid-column: 5 / 9; grid-row: 2; }
/* The posts box is as tall as the two rows beside it; its own length doesn't stretch them. */
.term-grid > [data-terminal-block="subscriber-feed"] { contain: size; }
.term-grid > [data-terminal-block="subscriber-feed"] .term-card-body { flex: 1 1 0; min-height: 0; max-height: none; }
@media (max-width: 1100px) {
  .term-grid { grid-template-columns: minmax(0, 1fr); }
  .term-grid > [data-terminal-block] { grid-column: 1; grid-row: auto; }
  .term-grid > [data-terminal-block="subscriber-feed"] { contain: none; }
  .term-grid > [data-terminal-block="subscriber-feed"] .term-card-body { flex: none; max-height: 520px; }
}

/* Scroll bars inside boxes stay hidden until the area scrolls, fade in over 0.15s, and fade
   out over 0.35s once scrolling has stopped for 0.7s (terminal-trades.js sets .is-scrolling). */
@property --term-thumb { syntax: "<color>"; inherits: true; initial-value: transparent; }
.term-scroll, .term-card-body { --term-thumb: transparent; scrollbar-width: thin;
  scrollbar-color: var(--term-thumb) transparent; transition: --term-thumb .35s ease; }
.term-scroll.is-scrolling, .term-card-body.is-scrolling { --term-thumb: var(--fill-4); transition-duration: .15s; }
@media (prefers-reduced-motion: reduce) { .term-scroll, .term-card-body { transition: none; } }

/* ── Boxes: gl-card (bundle.css) gives the fill, corners, 46px header and title; these size the parts ── */
.term-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.term-card-head .term-seg, .term-trades-ctrls { margin-left: auto; }
/* The trade filter and the chart range sit side by side at the top right of the trades box. */
.term-trades-ctrls { display: flex; align-items: center; gap: var(--space-2); }
/* Under the trades box's title row: the analyst's chip and the Sample data label at the left,
   the trade filter and the chart range at the right. */
.term-trades-bar { display: flex; align-items: center; gap: var(--space-3); padding: 0 16px 12px; }
.term-trades-avatar { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; display: block; }
.term-trades-ctrls .term-seg { margin-left: 0; }
.term-card-body { overflow: auto; flex: 1; }
/* The bottom bar: "Updated 2 days ago", "Updated 2h ago from 4 posts". */
.term-card-foot { margin: auto -16px -16px; padding: 10px 16px; border-top: 1px solid var(--line); color: var(--text-tertiary); font: 400 12px/1.3 var(--font-sans); }
.term-card--table .term-card-body { padding: 0; display: flex; flex-direction: column; }
.term-card--table .term-card-foot { margin: auto 0 0; }
.term-card-head .term-card-foot { margin: 0; padding: 0; border: 0; } /* the tier list's "Updated …", beside its title */
.term-card--half .term-card-body { min-height: 0; }
.term-card--feed .term-card-body { max-height: 520px; padding-inline: 6px; }
/* The X feed keeps the same gap on the right as on the left: where the scroll bar takes room of
   its own (a mouse, or "always show scroll bars"), that room comes out of the padding.
   terminal-feed.js measures it into --term-sb; overlay scroll bars measure 0. */
.term-card--feed .term-card-body { scrollbar-gutter: stable; padding-right: max(0px, calc(6px - var(--term-sb, 0px))); }
/* A box whose title is hidden has no header row, so its body brings its own top gap: 9px, the
   same as the 28px Segmented controls centred in the 46px header beside it, so their tops line up. */
.term-card > .term-visually-hidden + .term-card-body { padding-top: calc((46px - 28px) / 2); }

.term-line { margin: 0; color: var(--text-2); font-size: 14px; line-height: 1.5; }
/* The small line under a box's content that says where the content comes from. */
.term-empty { color: var(--text-3); font-size: 13px; font-style: italic; }
.term-grid .term-empty { color: var(--text-tertiary); }
.term-foot { margin: var(--space-4) 0; color: var(--text-tertiary); font-size: 12px; text-align: center; } .term-foot a { color: inherit; }
.term-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: var(--space-2); }
/* The Summary box's bullets: a plain list, the posts' text size, each ending with its post's time. */
.term-list li { color: var(--text-primary); font-size: 13px; line-height: 1.5; }
.term-summary-time { color: var(--text-tertiary); text-decoration: none; white-space: nowrap; }
.term-summary-time:hover { color: var(--text-primary); }
/* A post a Summary time was clicked for: tinted, fading out over 2 seconds (terminal-feed.js). */
.term-post--flash { animation: term-flash 2s ease-out; }
@keyframes term-flash { from { background: var(--accent-tint-strong); } }
@media (prefers-reduced-motion: reduce) {
  .term-post--flash { animation: none; background: var(--accent-tint-strong); }
}

/* Kyle's subscriber-only posts: one PostCard each (gl-post), with any pictures under the text. */
.term-feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.term-post { cursor: pointer; }
.term-post-head { margin: 0; min-width: 0; }
.term-post-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.term-post-time { margin-left: auto; font: 400 11.5px/1 var(--font-sans); color: var(--text-tertiary); white-space: nowrap; }
.term-post-body { white-space: pre-wrap; }
.term-post-media { margin: 0 0 8px 38px; display: grid; gap: var(--space-2); }
.term-post-img { width: 100%; height: auto; display: block; border-radius: var(--radius-sm); }
.term-post-meta { margin: 0 0 0 38px; }
/* A card's bottom row: the logos of the coins it mentions at the left, overlapping, and
   "Read More" with a chevron, which opens the post, at the right. */
.term-post-foot { justify-content: space-between; min-height: 20px; }
.term-post-coins { display: flex; padding-left: 2px; }
.term-post-coins .term-trades-logo { width: 16px; height: 16px; margin: 0 0 0 -4px; vertical-align: 0; box-shadow: 0 0 0 1.5px var(--bg-raised); }
.term-post-coins .term-trades-logo:first-child { margin-left: 0; }
.term-post-open { appearance: none; display: inline-flex; align-items: center; gap: 2px; margin-left: auto; padding: 0; border: 0; background: none; font-size: 11.5px; }
.term-post-open svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.term-post:hover .term-post-open { color: var(--text-primary); }
/* A short post with no pictures doesn't open, so it isn't drawn as clickable. */
.term-post--short { cursor: default; }
.term-post--short:hover { background: none; }
/* An opened post fills the panel; the panel's own scroll bar takes over for a long one. */
.term-card-body.is-reading > :not(.term-feed-reader) { display: none; }
.term-feed-reader { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
/* Back is a BackLink drawn on a button (the reader has no address of its own), so the button's own frame goes. */
.term-feed-back { appearance: none; border: 0; background: none; }
.term-feed-open { align-self: stretch; cursor: default; }
.term-feed-open:hover { background: none; }
.term-feed-open .term-post-body { color: var(--text-primary); }
/* "Show 3 posts": a full-width primary Button above the feed. */
.term-feed-new { margin: 0 0 var(--space-2); }
/* "Last updated 3h ago" — only shown when the pull hasn't worked for over an hour. */
.term-stale { margin: 0 0 var(--space-3); color: var(--text-tertiary); font-size: 12px; }
.term-more { margin: var(--space-4) 0 0; text-align: center; }
.term-quiet { margin: 0 0 var(--space-3); }

/* Tier list: gl-tier rows and tiles (bundle.css). The .term-tier-badge rules are for Kyle's admin page. */
.term-tier-cell { width: 44px; }
.term-tier-item { white-space: nowrap; } /* the "With notes" Asset cell: logo and ticker (e.g. HYPEUS) on one line */
.term-tier-badge { flex: none; width: 22px; height: 22px; border-radius: 4px; display: inline-grid; place-items: center;
  font: 700 11px/1 var(--font-ui); color: var(--ink); background: var(--text-3); }
.term-tier-S { background: var(--market); }
.term-tier-A { background: var(--asset); }
.term-tier-B, .term-tier-C { background: color-mix(in srgb, var(--text) 14%, transparent); color: var(--text-2); }
.term-tier-note { color: var(--text-tertiary); white-space: normal; overflow-wrap: anywhere; }
.term-tiers .term-empty { font-size: 12.5px; }
/* The Timeframe column: header and badge centred, every badge five characters wide (fits "Swing") so Short, Swing and Long match. */
.term-tiers :is(th, td):nth-child(3) { text-align: center; }
.term-tiers td:nth-child(3) .gl-badge { box-sizing: content-box; min-width: 5ch; justify-content: center; }
/* Both views draw the tier letter at 24px in the same 44px Tier column (.term-tier-cell), so it stays in place when the view is switched. */
:is(.term-tiers, .term-tier-grid) .gl-tier__letter { width: 24px; height: 24px; font-size: 12px; border-radius: var(--radius-xs); }
/* A note: two lines, then "…", as a quiet TextLink that opens the whole note in the box like an
   X feed post (terminal-feed.js), which gets the X feed's side gap since this box has none, and
   room above Back for its focus ring. */
.term-tier-note-open { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  appearance: none; padding: 0; border: 0; background: none; font: inherit; text-align: left; overflow-wrap: anywhere; }
.term-card--table .term-feed-reader { padding: var(--space-1) 6px 16px; }

/* Shared dense table: the admin page's posted trades. Home's tables are DataTables (gl-table). */
.term-table { width: 100%; border-collapse: separate; border-spacing: 0; font-variant-numeric: tabular-nums; }
.term-table th { position: sticky; top: 0; background: var(--ink-2); height: 32px; padding: 0 var(--space-2);
  text-align: left; white-space: nowrap; font: 500 11px var(--font-ui); letter-spacing: .03em; text-transform: uppercase;
  color: var(--text-3); border-bottom: 1px solid var(--rule); }
.term-table td { height: 30px; padding: 0 var(--space-2); font-size: 12.5px; color: var(--text);
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 60%, transparent); }
.term-table :is(th, td):first-child { padding-left: var(--space-3); }
.term-table :is(th, td).r { text-align: right; }
/* Home's tables line their first column up with the card title. */
.term-grid .gl-table :is(th, td):first-child { padding-left: 16px; }

/* ── Kyle's trades: the log beside the chart ─────────────────────────────────── */
.term-trades-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: var(--space-4);
  padding: 0 var(--space-4) var(--space-4) 0; }
.term-trades-log { max-height: 320px; overflow: auto; }
.term-trades-log tbody tr { cursor: pointer; }
.term-trades-log tbody tr:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
/* The selected row is a DataTable's selected row (accent-tint), and every cell in it takes the main text colour. */
.term-trades-date { color: var(--text-tertiary); }
.term-trades-coin { font-weight: 500; }
/* A white circle behind every logo, so a dark one on a clear background (NEAR's) still shows on navy. */
/* Logos in 22px circles. Crypto logos are drawn round and fill the circle. Stock logos are marks
   drawn to a square's edges, or wide, so they sit inside it with room around them (16px), not
   cut off; their address names the room. */
.term-trades-logo { box-sizing: border-box; width: 22px; height: 22px; border-radius: 50%; vertical-align: -6px; margin-right: 7px; object-fit: cover; background: #fff; }
.term-trades-logo[src*="/coin-logo/stock-"] { padding: 3px; object-fit: contain; }
/* coin-logo.js: a logo drawn white on a clear background gets a dark circle. */
.term-trades-logo.is-light { background: #1b2333; }
.term-trades-detail { text-align: right; color: var(--text-secondary); }
.term-trades-detail.is-new { color: var(--pos); }
.term-trades-detail.is-exit { color: var(--text-tertiary); }
.term-trades-log tbody tr[aria-selected="true"] td:is(*, .term-trades-detail, .term-trades-date) { color: var(--text-primary); }
.term-trades-log .term-empty { padding: var(--space-3) var(--space-4); margin: 0; }
.term-trades > .term-card-body > .term-empty, .term-trades > .term-empty { padding: 0 var(--space-4) var(--space-4); }

.term-trades-chart { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.term-trades-tool { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* The coin chip above the chart, and the tier list's chips: a ticker chip's fill-1 pill, not clickable. */
.term-trades-chip { display: inline-flex; align-items: center; gap: 6px; height: var(--control-sm); box-sizing: border-box; padding: 0 10px 0 3px;
  border-radius: var(--radius-pill); background: var(--fill-1); color: var(--text-primary); font: 500 12px/1 var(--font-sans); white-space: nowrap; }
.term-trades-chip:not(:has(img)) { padding-left: 10px; }
.term-trades-chip .term-trades-logo { margin-right: 0; vertical-align: 0; }
.term-trades-chip:empty { display: none; }
.term-trades-pos { color: var(--text-tertiary); font-size: 12px; }
/* The chart is an AreaChart: gl-chart__line, gl-chart__grid and the area stops come from bundle.css. */
.term-trades-svg { display: block; width: 100%; height: 232px; overflow: visible; }
.term-trades-svg text { font: 400 10px var(--font-mono); fill: var(--text-tertiary); }
.term-trades-svg .tag { fill: var(--brand-electric); }
.term-trades-svg text.tag-text { fill: var(--text-on-fill); }
/* A bubble per trade, floating just above the line: no outline, the bright green or red in
   both themes so the black letter stays readable. */
.term-trades-svg .mk circle { fill: #3CC48A; }
.term-trades-svg .mk.sell circle { fill: #E2685F; }
.term-trades-svg .mk text { font: 500 9.5px var(--font-sans); fill: #000; text-anchor: middle; dominant-baseline: central; }
.term-trades-note { margin: 0; overflow-wrap: anywhere; } /* a long unbroken note wraps instead of widening Home */
.term-trades-note:empty { display: none; }
@media (max-width: 760px) {
  .term-trades-body { grid-template-columns: minmax(0, 1fr); padding-left: var(--space-4); }
  /* No scroll inside the box on a phone: the page scrolls, and the log shows 8 rows at a time
     with "Show more" under them (terminal-trades.js). */
  .term-trades-log { margin-left: calc(-1 * var(--space-4)); max-height: none; overflow: visible; }
  .term-trades-log tbody tr.is-later { display: none; }
  /* The row under the title on two lines: the analyst's chip, then the filter and the chart range. */
  .term-trades-bar { flex-wrap: wrap; row-gap: var(--space-2); }
  .term-trades-ctrls { flex-basis: 100%; margin-left: 0; }
}
.term-trades-more { margin: var(--space-2) 0 0 var(--space-4); }

/* ── Social tab: the members chat, inside the terminal ─────────────────────────
   Two layouts live here, both on the Grand Line design system (docs/design-system/,
   loaded as gl-theme.css + bundle.css by the terminal's head), so light mode follows
   with no extra rules.

   1. A signed-in member gets the real chat. That is styled by chat.css, which this
      page loads only in that case; the rules below just hand the shell the whole panel.
   2. A signed-out visitor (staging and PR previews) gets the frame: the same three
      columns and the same 56px room header, under the log-in strip and filled with grey
      shapes. Its pieces are the same design-system components as the chat's (Cards,
      ListItems, a primary Button), drawn by bundle.css; chat.css is not loaded for them,
      so the layout below mirrors chat.css's so the two look the same. */
/* The tab's own wrapper and the two shells inside it both just take all the room the
   panel gives them; the panel is what the full-page rules below size. */
.term-social { display: flex; min-width: 0; min-height: 0; font-variant-numeric: tabular-nums; }
.term-social .chat-shell.is-embedded { flex: 1; width: 100%; height: 100%; min-height: 0; }

/* ── Full-page social tab ──────────────────────────────────────────────────────
   Kyle, 17 Oct 2026: "it should look like that gambit - full page". While the social
   tab is the open one the page carries .is-social (set on the server for ?tab=social,
   toggled by terminal.js on a click) and the chat fills every pixel under the site top
   bar and the tab strip: no card, no border, no wrap padding, and no page scroll —
   only the message stream and the side lists scroll, inside the shell.

   It is a plain flex chain (the tabs live in the top bar), so there are no pixel offsets
   to go stale when the top bar changes height:
     body  100dvh flex column → topbar flex:none → main flex:1 → panel flex:1 →
     .term-social flex:1 → the chat shell height:100%.
   The zeroxkyle tab is untouched: without .is-social none of this applies. */
.term-body.is-social { height: 100dvh; display: flex; flex-direction: column;
  overflow: hidden; }
.term-body.is-social .topbar { flex: none; }
/* main stops being a centred, padded wrap and becomes the full-bleed column. */
.term-body.is-social .term-main { flex: 1; min-height: 0; display: flex;
  flex-direction: column; max-width: none; margin: 0; padding: 0; }
.term-body.is-social .term-panel { min-width: 0; }
.term-body.is-social .term-panel[data-terminal-panel="social"]:not([hidden]) {
  flex: 1; min-height: 0; display: flex; }
.term-body.is-social .term-social { flex: 1; }

/* The logged-out frame. Same shape, sizing and surfaces as the real chat in this tab,
   because it has to look like the thing it stands in for. */
.term-social-frame { display: grid; grid-template-columns: 248px minmax(0, 1fr) 300px;
  flex: 1; height: 100%; min-width: 0; min-height: 0;
  background: var(--bg-surface); color: var(--text-primary); font: 14px/1.5 var(--font-sans); }
.term-social-frame { box-sizing: border-box; grid-template-rows: auto minmax(0, 1fr); }
.term-social-frame > .term-strip { grid-column: 1 / -1; margin: var(--space-3) var(--space-3) var(--space-1); }
.term-social-rooms, .term-social-pane, .term-social-pulse { margin: var(--space-2); min-height: 0; }
.term-social-pane { margin-left: 0; margin-right: 0; }
.term-social-rooms { padding: var(--space-4) var(--space-3); }
.term-social-rooms, .term-social-pulse { overflow-y: auto; }

.term-social-label { display: block; margin: 0 0 var(--space-2); padding: 0 var(--space-2); }
.term-social-roomlist { margin: 0; padding: 0; }
.term-social-room-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.term-social-head { height: 56px; border-bottom: 1px solid var(--line); }
.term-social-room-title { margin: 0; font: 500 18px/1.2 var(--font-sans); letter-spacing: -0.015em; }

/* Six grey messages at the bottom of the box, under a day tag; any that don't fit are cut off at the top. */
.term-social-stream { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column;
  justify-content: flex-end; gap: var(--space-4); padding: var(--space-4); }
.term-social-day { align-self: center; border-radius: var(--radius-tag); }
.term-social-msg { display: flex; gap: var(--space-3); }
.term-social-msg-body { flex: 1; min-width: 0; }
.term-social-msg-body p { margin: 0 0 6px; }

/* A composer that is only there to complete the picture: no form, nothing to type in.
   The box is a --fill-1 field and Send the primary Button, as in the real chat. */
.term-social-composer { flex: none; display: flex; align-items: flex-end; height: 96px;
  margin: var(--space-3) var(--space-4); padding: var(--space-2); border-radius: var(--radius-md);
  background: var(--fill-1); opacity: .5; }
.term-social-composer-box { flex: 1; min-width: 0; }
.term-social-pulse .term-social-label { padding: 0; }
.term-social-block { margin: 0 0 var(--space-4); }
.term-social-chips { display: flex; flex-wrap: wrap; gap: 6px; }

/* The frame narrows like the chat does: the pulse column goes first, then, on a phone, the
   room list, leaving the strip and the pane the full width. Nothing slides over,
   because this state has no JavaScript of its own — there is nothing to toggle. */
@media (max-width: 1200px) {
  .term-social-frame { grid-template-columns: 248px minmax(0, 1fr); }
  .term-social-pulse { display: none; }
}
@media (max-width: 760px) {
  .term-social-frame { grid-template-columns: 240px minmax(0, 1fr); }
  .term-social-head { padding: 0 var(--space-3); }
  .term-social-composer { margin-left: var(--space-3); margin-right: var(--space-3); }
}
@media (max-width: 720px) {
  .term-social-frame { grid-template-columns: minmax(0, 1fr); }
  .term-social-rooms { display: none; }
}

/* A plain button, used by the social tab before the chat moved inline and kept for
   any future link out of a box. */
.term-btn { display: inline-block; margin-top: var(--space-3); padding: 10px 16px;
  border: 1px solid var(--asset); color: var(--asset-ink); text-decoration: none;
  font: 600 13px var(--font-ui); }
.term-btn:hover { background: color-mix(in srgb, var(--asset) 14%, transparent); }

/* ── Kyle's admin page (/terminal/admin) ──────────────────────────────────────
   Drawn with the Grand Line design system (docs/design-system/): the page loads gl-theme.css and
   bundle.css instead of tokens.css and hub.css, and its markup uses the gl-* components (Card,
   NavTabs, BackLink, Button, TextField, Select, FileInput, SearchField, Menu, DataTable, Dialog,
   Toast, Notice, ActionBar, TierList letters). This block only lays them out. */
.term-admin-page { margin: 0; min-height: 100vh; overflow-x: clip; background: var(--bg-page); color: var(--text-primary);
  font: 400 14px/1.5 var(--font-sans); }

/* The top bar: SiteNav, with the admin tabs as NavTabs (scrolling sideways on a phone) and the ThemeToggle at its end. */
.term-admin-bar { gap: var(--space-4); margin: var(--space-3) max(var(--space-3), env(safe-area-inset-right, 0px)) 0 max(var(--space-3), env(safe-area-inset-left, 0px)); }
.term-admin-brand { flex: none; }
.term-admin-bar .gl-theme { flex: none; margin-left: auto; }
.term-admin-tabs { min-width: 0; overflow-x: auto; scrollbar-width: none; }
.term-admin-tabs::-webkit-scrollbar { display: none; }
@media (max-width: 560px) {
  .term-admin-bar { gap: var(--space-2); padding-left: var(--space-3); }
  .term-admin-bar .gl-sitenav__logo { height: 18px; }
  .term-admin-tabs .gl-tab { padding: 0 10px; }
}

.term-admin { padding: var(--space-3) max(var(--space-3), env(safe-area-inset-right, 0px)) var(--space-12) max(var(--space-3), env(safe-area-inset-left, 0px)); }
.term-admin-sub { margin: 0 0 var(--space-3); color: var(--text-secondary); font-size: 14px; line-height: 1.5; }
.term-admin-last { margin: 0 0 var(--space-3); color: var(--text-tertiary); font-size: 12px; }
.term-admin-back { margin: 0 0 var(--space-3); }
.term-admin .gl-card { margin: 0 0 var(--space-3); overflow: visible; }
.term-admin .gl-notice { margin: 0 0 var(--space-3); }
.term-admin-page .term-empty { margin: 0; color: var(--text-tertiary); font: 400 13px/1.45 var(--font-sans); }

/* "Add a coin" on the Listings tab (Coin Listings PRD, UI Req 1.1): one column on a phone, two from
   700px. Each field shows only once what it depends on is picked, from the form's own choices:
   Chain and the address for crypto, Exchange for a stock, the address once a chain is chosen, and
   the CoinGecko wording for a coin on its own chain. */
.term-listing { display: grid; gap: var(--space-4); max-width: 760px; }
.term-listing-kind { justify-self: start; }
.term-listing-row { display: grid; gap: var(--space-3); }
.term-listing-actions { display: flex; justify-content: flex-end; padding-top: var(--space-3); }
@media (min-width: 700px) {
  .term-listing-row { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); align-items: start; }
}
.term-listing:has(input[name="kind"][value="stock"]:checked) [data-show="crypto"],
.term-listing:has(input[name="kind"][value="crypto"]:checked) [data-show="stock"],
.term-listing:has(select[name="chain"] option[value=""]:checked) [data-show="address"],
.term-listing:has(select[name="chain"] option[value="native"]:checked) [data-label="contract"],
.term-listing:not(:has(select[name="chain"] option[value="native"]:checked)) [data-label="native"],
:is(.term-listing, .term-admin-form):not(:has(select[name="exchange"] option[value="other"]:checked)) [data-show="exchange-other"] { display: none; }
/* Segmented controls made of radios (Crypto / Stock, Buy / Sell): the radio is hidden, its option shows the choice. */
.term-admin .gl-seg { margin: 0; border: 0; }
.term-admin .gl-seg input { position: absolute; opacity: 0; pointer-events: none; }
.term-admin .gl-seg .gl-seg__opt { display: inline-flex; align-items: center; cursor: pointer; }
.term-admin .gl-seg input:checked + .gl-seg__opt { background: var(--fill-selected); box-shadow: var(--shadow-selected); color: var(--text-primary); }
.term-admin .gl-seg input:focus-visible + .gl-seg__opt { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Dialogs (native <dialog>, so focus stays inside and Escape closes it): the checks before listing
   (Coin Listings PRD, UI Req 1.5), one ListItem per check, and the confirmation before a trade. */
dialog.gl-dialog { border: 0; }
dialog.gl-dialog::backdrop { background: var(--scrim); }
.term-check { width: 480px; margin: 14vh auto auto; }
.term-check-title { overflow-wrap: anywhere; }
.term-check-list { margin: var(--space-4) 0 0; padding: 0; list-style: none; }
.term-check-row { align-items: flex-start; padding: 6px 0; }
.term-check-icon { width: 20px; height: 20px; flex: none; display: grid; place-items: center; }
/* Never cut a check's answer off: it wraps onto more lines instead (Coin Listings PRD, UI Req 1.5).
   The row is a ListItem, whose own small text is one line with "…", so this has to outrank it. */
.term-check-row .term-check-text { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
.term-check-text:empty, .term-check-sum:empty { display: none; }

/* A contract address is one long word: it breaks rather than widening the page on a phone. */
[data-listings] .term-admin-note, [data-room-requests] .term-admin-note { overflow-wrap: anywhere; }
.term-admin-item .gl-file { flex: 1 1 260px; }

/* Chat tab. A report is a stack: who and where, the message as written, who reported it, then its
   buttons, then Ban and Delete all folded under their own line. */
.term-chat-report { padding: var(--space-4) 0; display: grid; gap: var(--space-2); justify-items: start; }
.term-chat-report + .term-chat-report { box-shadow: 0 -1px 0 var(--line); }
.term-chat-report > p { margin: 0; }
.term-chat-report .term-admin-quote { justify-self: stretch; max-width: 720px; }
.term-admin-quote { margin: 0; padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs);
  background: var(--fill-1); color: var(--text-primary); font-size: 14px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
[data-chat-reports] .term-admin-note, [data-chat-bans] .term-admin-note { overflow-wrap: anywhere; }
.term-chat-report .term-admin-note { margin: 0; }
/* Give feedback (features/feedback): the Dialog keeps a margin on a phone; the Feedback tab's rows are laid out like a report, and a long page address breaks. */
dialog[data-feedback] { max-width: calc(100vw - 32px); }
[data-feedback-list] .term-admin-note { overflow-wrap: anywhere; }
/* The name, then Copy at the comment's top right; its Tooltip opens leftwards, inside the card. */
.term-feedback-head { justify-self: stretch; max-width: 720px; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.term-feedback-head .gl-tip__bubble { left: auto; right: 0; translate: none; }
.term-chat-more { justify-self: stretch; max-width: 720px; }
.term-chat-more > summary { list-style: none; cursor: pointer; margin-left: calc(-1 * var(--space-2)); }
.term-chat-more > summary::-webkit-details-marker { display: none; }
.term-chat-more-icon { margin-right: 4px; transition: transform .15s ease; }
.term-chat-more[open] .term-chat-more-icon { transform: rotate(90deg); }
.term-chat-more-panel { margin-top: var(--space-2); padding: var(--space-3); border-radius: var(--radius-sm); background: var(--fill-1);
  display: grid; gap: var(--space-2); }
.term-chat-more-panel .term-admin-note { margin: 0 0 var(--space-2); }
.term-chat-more-panel .term-admin-note:last-child { margin-bottom: 0; }
.term-chat-more-row { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: 0; }
.term-chat-more-row > .gl-field__input { flex: 1 1 220px; max-width: 360px; width: auto; }
.term-chat-more-row > .gl-field__hint { flex: 1 1 100%; margin: 0; }
.term-chat-views { margin-bottom: var(--space-2); }
.term-chat-resolution { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); font-size: 13px; color: var(--text-secondary); }

/* Toasts sit in the bottom-left corner (gl-toasts); while the Tier list's draft bar is stuck to the
   bottom (changes not yet saved), they sit above it. */
.term-admin-toasts:empty { display: none; }
body:has(.term-tier-draft.gl-actionbar--sticky) .term-admin-toasts { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 719px) { body:has(.term-tier-draft.gl-actionbar--sticky) .term-admin-toasts { bottom: calc(124px + env(safe-area-inset-bottom, 0px)); } }

/* Labels that only screen readers need (every control still has a name). */
.term-admin-sr { position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

.term-admin-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.term-admin-form--add { display: block; max-width: 760px; }
.term-admin-add-fields { display: grid; gap: var(--space-3); margin-bottom: var(--space-3); }
/* Selects in a form column fill it, like the text fields beside them. */
.term-admin .gl-field :is(.gl-select-wrap, .gl-select) { display: flex; width: 100%; min-width: 0; }
/* Menu caps itself at its container's width, which would squeeze a tier list into a 96px field. */
.term-admin .gl-select-wrap .gl-menu { max-width: calc(100vw - 32px); max-height: 300px; overflow-y: auto; }

.term-admin-tier .term-admin-note { margin: 0 0 var(--space-3); color: var(--text-tertiary); font-size: 13px; line-height: 1.4; }
.term-admin-item .term-admin-note { margin: var(--space-1) 0 0; }
.term-admin-items { list-style: none; margin: 0; padding: 0; display: grid; }
.term-admin-item { padding: 10px 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.term-admin-item + .term-admin-item { box-shadow: 0 -1px 0 var(--line); }
.term-admin-item-head { margin: 0; flex: 1 1 220px; min-width: 0; }
.term-admin-name { font: 500 14px/1.3 var(--font-sans); }
.term-admin-controls { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.term-admin-item .term-admin-controls { justify-content: flex-end; }
.term-admin-form--note { flex: 1 1 100%; }
.term-admin-form--note > .gl-field__input { flex: 1 1 160px; width: auto; }

/* The Trades section: Buy / Sell, the Post trade button with its error next to it, and the posted trades table. */
.term-admin-act { margin: 0; padding: 0; border: 0; }
.term-admin-act .gl-seg { align-self: flex-start; }
.term-admin-form--add:has(input[value="buy"]:checked) .term-admin-trim { opacity: .45; }
.term-admin-post { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.term-admin-error { margin: 0; color: var(--neg); font-size: 13px; }
.term-admin-table .term-admin-form { justify-content: flex-end; }
.term-admin-coin-name { margin-left: 6px; color: var(--text-tertiary); }
/* A trade just posted, while its save is on the way (terminal-coin-search.js). */
.term-admin-table tr.is-saving { opacity: .65; }

@media (min-width: 700px) {
  .term-admin-add-fields { grid-template-columns: 1fr 2fr; align-items: end; }
  .term-admin-field--wide { grid-column: 1 / -1; }
}

/* Each timeframe is its own card, its four tiers each a compact block under its TierList letter. */
.term-admin-group { margin: 0 0 var(--space-3); }
.term-admin-group:last-of-type { margin-bottom: 0; }
.term-admin-tier-head { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 6px; font: 500 12px var(--font-sans); color: var(--text-tertiary); }
.term-admin-group .term-empty { padding-left: 30px; font-size: 12.5px; }
.term-admin .gl-tier__letter { width: 22px; height: 22px; font-size: 11px; }

/* The coin picker (Trades and Tier list tabs): a SearchField, its results a Menu below it. */
.term-coin-pick { position: relative; }
.term-coin-pick .gl-search { width: 100%; }
.term-coin-pick input[type="search"]::-webkit-search-cancel-button { display: none; }
.term-coin-results { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30; width: auto; margin: 0; list-style: none; max-height: 300px; overflow-y: auto; }
.term-coin-pick .coin-types { display: flex; flex-wrap: wrap; gap: 4px; padding: var(--space-2); }
/* ListItems built as <button>s (coin search results, tier options) lose the browser's button border and fill.
   :where() keeps this weaker than ListItem's own hover and selected fills. */
:where(.term-coin-pick, .gl-select-wrap) .gl-item { width: 100%; border: 0; background: none; font: inherit; text-align: left; }
.term-coin-pick .gl-item .term-trades-logo { margin-right: 0; }
.term-coin-pick .coin-empty { padding: var(--space-2); font-size: 12px; color: var(--text-tertiary); }
/* The spinner shows only when an answer takes longer than 0.2 s, as in the chat. */
.term-coin-pick .coin-loading { display: flex; justify-content: center; padding: var(--space-3); animation: term-coin-appear 0s .2s both; }
@keyframes term-coin-appear { from { visibility: hidden; } to { visibility: visible; } }

/* ── Tier list tab (Tier List Coin Picker, 22 Oct) ─────────────────────────────
   Add form: Coin, Tier, Note and Add on one line on a wide screen, stacked on a phone.
   Each item is one row in fixed columns, so every row lines up: the ticker, the note box with
   Save, ▲ ▼, the tier, Archive. Controls are the small (28px) size. */
.term-tier-add { display: grid; gap: var(--space-3); margin: 0; }
@media (min-width: 900px) {
  .term-tier-add { grid-template-columns: minmax(240px, 2fr) 120px 96px minmax(200px, 3fr) auto; align-items: end; }
}
[data-tier-list] .term-admin-items { box-shadow: 0 -1px 0 var(--line); }
.term-admin-row { display: grid; grid-template-columns: minmax(72px, 140px) minmax(180px, 1fr) auto auto auto;
  align-items: center; gap: var(--space-2) var(--space-3); padding: 8px 0; }
.term-admin-row .term-admin-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.term-admin-row .term-admin-name .term-trades-logo { margin-right: 8px; }
.term-admin-row .term-admin-form { flex-wrap: nowrap; }
.term-admin-row .term-admin-form--note { flex: none; }
.term-admin-row .term-admin-form--tier .gl-select { width: 92px; }
.term-admin-row .term-admin-form--tier .term-tier-frame-select { width: 120px; } /* fits "Short-term", so every row lines up */
.term-admin-row .gl-select-wrap .gl-menu { left: auto; right: 0; }
.term-admin-order { display: flex; gap: 4px; }
.term-admin-row--archived { grid-template-columns: minmax(72px, 140px) 1fr auto; }
.term-admin-row--archived .term-admin-note { margin: 0; }
/* A phone: the ticker with ▲ ▼ and Archive on the first line, the note under it, the tier last. */
@media (max-width: 720px) {
  .term-admin-row { grid-template-columns: 1fr auto auto; }
  .term-admin-row .term-admin-name { grid-column: 1; grid-row: 1; }
  .term-admin-row .term-admin-order { grid-column: 2; grid-row: 1; }
  .term-admin-row > .term-admin-form:last-child { grid-column: 3; grid-row: 1; }
  .term-admin-row .term-admin-form--note { grid-column: 1 / -1; grid-row: 2; }
  .term-admin-row .term-admin-form--tier { grid-column: 1 / -1; grid-row: 3; }
  .term-admin-row--archived { grid-template-columns: 1fr auto; }
  .term-admin-row--archived .term-admin-note { grid-column: 1; grid-row: 2; }
  .term-admin-row--archived > .term-admin-form:last-child { grid-column: 2; grid-row: 1 / span 2; }
}
/* The note box: a TextField with Save inside it. With the tab's script (.is-live) Save shows only
   while the note differs from the saved one, and "Saved" shows briefly once it's saved. */
.term-note-box { flex: 1 1 auto; }
.term-note-box .term-note-save { height: 22px; padding: 0 10px; }
.term-note-box .gl-field__end { right: 3px; }
.term-note-box.is-live:not(.is-dirty) .term-note-save, .term-note-box:not(.is-saved) .gl-field__saved,
.term-note-box.is-dirty .gl-field__saved { display: none; }
/* The draft: a row moved or re-tiered but not yet published is highlighted (accent tint), and the
   ActionBar with Revert changes and Update tier list sticks to the bottom while there are changes. */
.term-admin-row.is-changed { padding-left: 10px; border-radius: var(--radius-md); background: var(--accent-tint); }
.term-tier-draft { flex-wrap: wrap; margin: 0 0 var(--space-3); } /* between the timeframe cards and Archived, spaced like the cards */

/* "Tier List": the view toggle (lines = the grid, notepad = with notes, icon Segmented options)
   and the grid: a DataTable whose Tier column is the letter and whose three timeframe columns
   share the rest equally, on a phone too. Each cell holds its assets as ticker chips, which wrap
   onto more lines inside the cell when it runs out of width, never scrolling sideways. Every
   chip is the same height and its ticker is cut with "…" when it doesn't fit, so no chip can
   push the box wider. An empty cell is a quiet dash in the tertiary text colour. */
.term-tier-toggle svg { display: block; }
.term-tier-grid { table-layout: fixed; margin-bottom: var(--space-2); } /* "Updated …" moved to the header, so the last row keeps the card's bottom room */
.term-tier-grid td { height: auto; padding-block: var(--space-2); vertical-align: top; }
.term-tier-grid .gl-tier__letter { margin-top: 2px; } /* centred on the 28px chips beside it */
/* Each column's gap is on its right only (the Tier column's room after its letter, then each cell's
   own right padding), so a 6-character ticker (HYPEUS) and its logo stay whole on a phone down to 360px wide. */
.term-tier-grid tr > * + * { padding-left: 0; }
.term-tier-none { display: block; line-height: var(--control-sm); color: var(--text-tertiary); }
.term-tier-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; list-style: none; margin: 0; padding: 0; }
.term-tier-chip { max-width: 100%; }
.term-tier-chip .term-trades-logo { flex: none; vertical-align: 0; }
.term-tier-chip span { max-width: 10ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* With chat on, a chip is the Discuss in chat menu's trigger (Discuss in Chat PRD, UI Req 2.1): it
   steps up a fill on hover and is solid accent while its menu is open, like every drop-down trigger. */
.term-tier-chips > .gl-dropdown { max-width: 100%; }
button.term-tier-chip { border: 0; cursor: pointer; }
button.term-tier-chip:hover { background: var(--fill-2); }
button.term-tier-chip[aria-expanded="true"] { background: var(--accent); color: var(--text-on-fill); }
button.term-tier-chip[aria-expanded="true"]:hover { background: var(--accent-hover); color: var(--text-on-fill); }

/* Discuss in chat (Discuss in Chat PRD, UI Req 2 to 4): the design system's drop-down with an
   IconButton trigger (src/site/discuss.mjs), for members where chat is on (.is-member). In a Tier List
   note it sits in space kept free at the right of the cell, so it never covers the note; each trade
   in the log ends with one, and the trades chart's toolbar ends with one for the selected trade; all
   show on hover or focus, and always without hover. On a
   Tools chart it is always shown, at the top right, beside the chart's legend when it has one. */
body:not(.is-member) [data-discuss] { display: none; }
.term-tiers td.term-tier-note { position: relative; padding-top: var(--space-2); padding-bottom: var(--space-2); padding-right: 44px; }
/* Centred without a transform: a transform would become the floating menu's frame instead of the screen. */
.term-tier-note [data-discuss] { position: absolute; top: calc(50% - 15px); right: 6px; }
.term-trades-tool [data-discuss] { margin-left: auto; }
/* Each trade in the log ends with its own, in space kept free at the right of the detail cell. */
.is-member .term-trades-log td.term-trades-detail { position: relative; padding-right: 44px; }
.is-member .term-trades-log [data-trades-head] { padding-right: 44px; } /* its heading lines up with it */
.term-trades-detail [data-discuss] { position: absolute; top: calc(50% - 15px); right: 6px; }
@media (hover: hover) {
  .term-tiers tr:not(:hover, :focus-within) [data-discuss], .term-trades-log tr:not(:hover, :focus-within) [data-discuss],
  .term-trades-chart:not(:hover, :focus-within) [data-discuss] { opacity: 0; }
}
.is-member .tool-chart:not([hidden]) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-2); align-items: start; }
.is-member .tool-chart > * { grid-column: 1 / -1; }
.is-member .tool-chart > [data-discuss] { grid-column: 2; grid-row: 1; }
.is-member .tool-chart > [data-discuss] + * { grid-column: 1; grid-row: 1; }
/* Inset by --space-3 on every side, so the landing flash (gl-flash) reaches a little past the chart
   and the chat button sits clear of its corner. The same negative margin at the sides keeps the
   chart's width; above and below, the space is real, so the tint never runs into a heading. */
.tool-chart { padding: var(--space-3); margin: 0 calc(-1 * var(--space-3)); border-radius: var(--radius-md); }

/* ── The logged-out terminal (staging and PR previews: src/terminal/shell/locked.mjs) ──
   One strip above Home's boxes and the social tab's frame, the only place asking to log in or
   join, and every value in the boxes a still grey shape: a Skeleton's fill-2, without its pulse,
   because nothing on this page moves (24 Oct 2026). */
.term-strip { display: flex; align-items: center; gap: var(--space-4); margin: 0 0 var(--space-3);
  padding: var(--space-4); background: var(--bg-raised); border-radius: var(--radius-lg); }
.term-strip-lock { flex: none; width: 40px; height: 40px; border-radius: var(--radius-sm); display: grid; place-items: center;
  color: var(--text-primary); background: var(--fill-2); }
.term-strip-text { min-width: 0; }
.term-strip-title { margin: 0 0 4px; font: 500 16px/1.3 var(--font-sans); letter-spacing: -0.015em; color: var(--text-primary); }
.term-strip-text p { margin: 0; font: 400 13.5px/1.5 var(--font-sans); color: var(--text-secondary); }
.term-strip-actions { flex: none; display: flex; align-items: flex-start; gap: var(--space-2); margin-left: auto; }
/* "Join via Whop" is the shared button and its two plans (joinPlans in src/auth/pages.mjs), drawn
   as a secondary Button opening a Menu; Log in is the primary Button. */
.term-strip .join { position: relative; }
.term-strip .join > summary { list-style: none; display: inline-flex; align-items: center; height: var(--control-md); padding: 0 16px;
  border-radius: var(--radius-pill); background: var(--fill-2); color: var(--text-primary); font: 500 13px/1 var(--font-sans); cursor: pointer; }
.term-strip .join > summary::-webkit-details-marker { display: none; }
.term-strip .join > summary:hover { background: var(--fill-3); }
.term-strip .join > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.term-strip .plans { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-2); width: 300px; padding: var(--space-2); background: var(--bg-overlay);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-popover); }
.term-strip .plan { display: flex; flex-direction: column; align-items: center; gap: 4px; height: auto; padding: var(--space-3) 0; border-radius: var(--radius-md);
  background: var(--fill-1); color: var(--text-primary); text-decoration: none; font: 500 13px var(--font-sans); }
.term-strip .plan:hover { background: var(--fill-2); }
@media (max-width: 760px) {
  .term-strip { flex-wrap: wrap; }
  .term-strip-text { flex: 1 1 0; }
  .term-strip-actions { flex-basis: 100%; margin-left: 0; }
  .term-strip .plans { left: 0; right: auto; }
}
.term-sk { display: inline-block; vertical-align: middle; border-radius: var(--radius-xs); background: var(--fill-2); }
.term-sk--dot { flex: none; border-radius: 50%; margin-right: 6px; }
.term-sk--line { display: block; max-width: 100%; margin-top: 6px; }
.term-grid--locked .term-seg { opacity: .45; }
.term-grid--locked .term-seg button { cursor: default; }
.term-grid--locked .term-trades > .term-card-body { padding: 0; }
.term-sk-chart { color: var(--text-primary); }
.term-sk-chart .sk-line { fill: none; stroke: var(--fill-4); stroke-width: 1.6; stroke-linejoin: round; }
.term-sk-chart .sk { fill: var(--fill-2); }

/* ── Coverage (/terminal/coverage, src/terminal/features/coverage/) ───────────────────── */
a.term-tab { display: inline-flex; align-items: center; text-decoration: none; box-sizing: border-box; }
/* Coverage is drawn with the design system's own components (bundle.css); this only lays them out.
   Its Tools trigger carries the system's caret, so the drawn one goes. */
.term-tools-trigger:has(.gl-caret)::after { content: none; }
/* Coverage and the research tools: one centred column of cards. */
.cov, .tool { display: grid; gap: var(--space-3); max-width: 980px; margin: var(--space-4) auto 0; padding-bottom: var(--space-6); }
.tool-tabs { justify-self: start; max-width: 100%; flex-wrap: wrap; } /* a tool with tabs (DAT): the NavTabs above its title */
.tool--wide { max-width: 1320px; } /* a tool built round big tables gets the room for their columns, so nothing has to scroll sideways */
.cov > nav, .cov > p { margin: 0; }
.cov-list { display: grid; gap: var(--space-3); }
.tool-note { margin: 0; font-size: 12px; line-height: 1.5; color: var(--text-tertiary); }
.tool-note + .tool-note { margin-top: var(--space-2); }
/* Inside a tool's cards (and a chart view), parts stack with the same gap. */
.tool .gl-card__body, .tool-view { display: grid; gap: var(--space-3); align-content: start; min-width: 0; }
.tool .gl-card__body > *, .tool-view > * { min-width: 0; } /* fit the card, never widen it */
.tool .gl-card__body > .gl-seg, .tool-view > .gl-legend { justify-self: start; flex-wrap: wrap; }
.tool-sub + .gl-legend { margin-top: calc(-1 * var(--space-2)); }
.tool-sub { margin: var(--space-3) 0 0; font: 600 14px/1.3 var(--font-sans); letter-spacing: -0.01em; color: var(--text-primary); }
.tool-cell-note { display: block; margin-top: 2px; font-size: 11.5px; }
.tool-more > summary { cursor: pointer; width: fit-content; color: var(--accent-text); font: 500 13px/1.4 var(--font-sans); }
.tool-more > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.tool-more[open] > summary { margin-bottom: var(--space-2); }
.tool-actions { margin: 0; }
/* Search, chips and the bar over a list of rows. */
.tool-search { width: 320px; }
.tool-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tool-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.tool-bar__end { display: inline-flex; align-items: center; gap: var(--space-2); }
.tool-glr-end { display: flex; align-items: center; gap: var(--space-2); }
.tool-glr-end > b { font-weight: 400; min-width: 4.5em; text-align: right; }
.tool-change { min-width: 4em; text-align: right; font-size: 12px; }
.tool-change:not(.gl-pos, .gl-neg) { color: var(--text-tertiary); }
@media (max-width: 700px) { .tool-glr-end .tool-change { display: none; } } /* a phone row keeps revenue and score */
/* A protocol's Dialog: its name and 30d revenue on top, the detail in two columns. */
.tool-coin__head { display: flex; align-items: center; gap: var(--space-3); padding-right: 36px; margin-bottom: var(--space-4); }
.tool-coin__head > div:nth-child(2) { flex: 1; min-width: 0; display: grid; gap: 4px; }
.tool-coin__rev { display: grid; justify-items: end; gap: 4px; }
.tool-coin__rev b { font-weight: 400; font-size: 22px; }
.tool-coin .tool-pair > div { display: grid; gap: var(--space-3); align-content: start; min-width: 0; }
/* Robinhood Chain: robinhood-chart.js builds its own tiles, tooltip and table; here they take the
   StatTile, chart tip and DataTable looks. Its colours come from the page's root (src/robinhood/page.mjs). */
.gl-stat__value.is-wait { color: var(--text-tertiary); }
.tool-rh #rh-card { display: grid; gap: var(--space-3); min-width: 0; }
.tool-rh #rh-card[data-empty] > :not(#rh-waiting) { display: none; }
.tool-rh #rh-waiting[hidden] { display: none; }
/* The chart's change tiles, as a list of thin rows (ListItem): key and name, the closes it moved
   between, then the change. Clicking a row picks that token; the line-up of 7 days against the 7
   before stays out, to keep the rows to one line. */
.tool-rh .rhc-tiles { display: flex; flex-direction: column; gap: 2px; }
.tool-rh .rhc-tiles .tile { display: grid; grid-template-columns: minmax(0, 1fr) auto 6.5em; align-items: center; gap: var(--space-3); height: auto; min-height: 40px; min-width: 0; padding: 0 12px; border: 0; border-radius: var(--radius-sm); background: transparent; box-shadow: none; } /* hub.css has an older .tile */
.tool-rh .rhc-tiles .tile:not(:last-child) { cursor: pointer; }
.tool-rh .rhc-tiles .tile:not(:last-child):hover { background: var(--fill-1); }
.tool-rh .rhc-tiles .tile.focus { background: var(--accent-tint); }
.tool-rh .rhc-tiles .k { grid-column: 1; grid-row: 1; display: flex; align-items: center; gap: 8px; min-width: 0; font: 400 13.5px/1.3 var(--font-sans); color: var(--text-primary); }
.tool-rh .rhc-tiles .key, .tool-rh .tt .key { width: 10px; height: 10px; flex: none; border-radius: 3px; }
.tool-rh .rhc-tiles .m { grid-column: 2; grid-row: 1; font: 400 12px/1.3 var(--font-mono); color: var(--text-tertiary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tool-rh .rhc-tiles .m ~ .m { display: none; }
.tool-rh .rhc-tiles .v { grid-column: 3; grid-row: 1; text-align: right; font: 400 13.5px/1.3 var(--font-mono); color: var(--text-primary); font-variant-numeric: tabular-nums; }
@media (max-width: 480px) { .tool-rh .rhc-tiles .tile { grid-template-columns: minmax(0, 1fr) 6em; } .tool-rh .rhc-tiles .m { display: none; } } /* a small phone keeps the name and the change */
.tool-rh__chart { position: relative; margin: 0; min-width: 0; }
.tool-rh #chart { display: block; width: 100%; height: auto; overflow: visible; touch-action: pan-y; }
/* The Robinhood chart (rh-chart-draw.js), on its page and shared in Social chat: the tokens wear
   ChartColours 1 to 3, falling candles neg, and the axes and brush the design system's tones. */
.rh-chart { --locked: var(--chart-1); --market: var(--chart-2); --asset: var(--chart-3); --warn: var(--neg); --rule: var(--fill-3);
  --text-2: var(--text-secondary); --text-3: var(--text-tertiary); --ink-2: var(--bg-raised); --rh-brush: var(--accent-tint); }
:is(.tool-rh #chart, .rh-chart) text { fill: var(--text-tertiary); font: 400 11px var(--font-sans); }
:is(.tool-rh #chart, .rh-chart) text:is(.axis-title, .endlabel) { fill: var(--text-secondary); }
.tool-rh .brushgrip { cursor: ew-resize; } .tool-rh .brushbody { cursor: grab; }
.tool-rh .tt { position: absolute; z-index: 5; min-width: 156px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--bg-overlay); box-shadow: var(--shadow-popover); color: var(--text-primary); font: 400 12px/1.4 var(--font-sans); pointer-events: none; opacity: 0; }
.tool-rh .tt .d { margin-bottom: 4px; font-weight: 500; }
.tool-rh .tt .r { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }
.tool-rh .tt .nm { display: flex; align-items: center; gap: 6px; color: var(--text-secondary); }
.tool-rh .tt .val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.tool-rh .tablewrap { max-height: 360px; overflow-y: auto; overflow-x: hidden; } /* a long table scrolls down inside the card, never sideways */
.tool-rh .tablewrap table { width: 100%; border-collapse: collapse; font: 400 12px/1.3 var(--font-mono); font-variant-numeric: tabular-nums; }
.tool-rh .tablewrap th { position: sticky; top: 0; height: 32px; padding: 0 8px 8px; background: var(--bg-raised); text-align: right; vertical-align: bottom; font: 400 11px/1.2 var(--font-sans); color: var(--text-tertiary); }
.tool-rh .tablewrap td { height: 36px; padding: 0 8px; text-align: right; white-space: nowrap; color: var(--text-primary); }
.tool-rh .tablewrap :is(th, td):first-child { text-align: left; }
.tool-rh .tablewrap tbody tr:hover td { background: var(--fill-1); }
@media (max-width: 700px) { .tool-rh .tablewrap :is(th, td):nth-child(n+4):nth-child(even) { display: none; } } /* a phone keeps each token's close, not its % */
.tool-item-text { display: block; margin-top: 4px; font: 400 13px/1.45 var(--font-sans); color: var(--text-secondary); } /* a line about a ListItem, under its title */
.gl-table td.is-num .tool-cell-note { white-space: normal; } /* a figure stays on one line; the note under it may wrap */
@media (min-width: 1001px) { .tool-nowrap, .gl-table td.tool-nowrap .tool-cell-note { white-space: nowrap; } } /* one line where the page is wide; it may wrap below */
.tool-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.tool-narrow { display: none; } /* shown in place of tool-wide cells on a phone */
@media (max-width: 1000px) { .tool-wider { display: none; } } /* a column only a full-width card has room for */
.tool-phone { display: none; } /* shown only where tool-wide columns are gone */
@media (max-width: 700px) { .gl-table .tool-cell-note.tool-phone { display: block; } }
.tool-under { display: none; } /* a tool-wider column's text, under the row's name once that column is gone */
@media (max-width: 1000px) and (min-width: 701px) { .gl-table .tool-cell-note.tool-under { display: block; } }
/* A row of fields and their button, the button lined up with the inputs. */
.tool-form { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3); margin: 0; }
.tool-form .gl-field { flex: 1 1 0; min-width: 104px; max-width: 160px; } /* two fields and their button fit one row on a phone */
.tool-form > .gl-tip { margin-top: calc(12px * 1.2 + 6px + 2px); } /* level with the 40px inputs, under their labels, whether or not a hint follows */
.tool-form > .gl-tip .gl-tip__bubble { left: auto; right: 0; translate: none; } /* the button ends the row: its hint opens leftwards, inside the card */
/* A ListItem with a progress meter between its name and its figure. */
.tool-meter .gl-item__main { flex: 0 0 38%; }
.tool-meter .gl-progress { flex: 1; min-width: 40px; }
.cov-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-3); }
.tool-stats { display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr)); gap: var(--space-3); }
/* Columns a narrow screen drops (DataTable: drop columns, never scroll sideways). */
@media (max-width: 700px) { .tool-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .tool-wide { display: none; } .tool-narrow { display: table-cell; } .tool .gl-bars .gl-chart__axis { font-size: 30px; } }
.tool > .gl-seg { justify-self: start; flex-wrap: wrap; }
/* A row of tiles shares its lines (subgrid): labels on one line, figures on the next, then a meter
   or toggle and a note, so figures line up however long a label is or whether a tile has a note. */
.tool-stats .gl-stat { display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: var(--space-2); align-content: start; }
.tool-stats .gl-stat > .gl-label { align-self: end; }
.cov-cases, .tool-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: var(--space-3); }
.cov-list-head, .tool-list-head { margin: 0 0 var(--space-1); padding: 0 10px; }
.cov-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0 0; }

