/* ==========================================================================
   Q4Family Design v2 — components
   Needs: q4-tokens.css. Every class is prefixed q4- (no clash with the legacy
   .btn / .container / .modal ...). Only tokens are used — never a raw colour.
   State hooks: every stateful component supports BOTH the new hook
   (`is-open`, `is-active`, `is-loading`…) AND the legacy hook the old inline
   JS toggles (`open`, `active`, `show`, `hidden`, `selected`…), so a page can
   be moved to the new CSS without rewriting its JS on day one.
   Sections: 0 base · 1 layout · 2 actions · 3 forms · 4 data · 5 feedback ·
             6 overlays · 7 navigation · 8 composites · 9 utilities
   ========================================================================== */

/* ---------- 0. base ---------- */
.q4-app *, .q4-app *::before, .q4-app *::after { box-sizing: border-box; }
.q4-app { font-variant-numeric: tabular-nums; }
.q4-app a:not([class]) { color: var(--primary); text-decoration: none; }
.q4-app a:not([class]):hover { color: var(--primary-hover); text-decoration: underline; }
.q4-app :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.q4-app ::selection { background: var(--primary-soft); }
.q4-app [hidden] { display: none !important; }
.q4-icon { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.q4-app i.fa-solid, .q4-app i.fa-regular, .q4-app i.fa-brands { flex: none; } /* Font Awesome stays the icon set during migration */
@keyframes q4-spin { to { transform: rotate(360deg); } }
.q4-app .fa-spin { animation: q4-spin .8s linear infinite !important; } /* FA mutes .fa-spin under prefers-reduced-motion; a loading indicator must keep moving */

/* ---------- 1. layout ---------- */
.q4-container { width: min(100% - 32px, var(--layout-container)); margin-inline: auto; }
@media (min-width: 600px) { .q4-container { width: min(100% - 48px, var(--layout-container)); } }
.q4-shell { min-height: 100vh; display: flex; flex-direction: column; }
.q4-shell > main { flex: 1; }

.q4-site-header { height: 64px; border-bottom: 1px solid var(--border); background: var(--bg); position: sticky; top: 0; z-index: var(--z-sticky); }
.q4-site-header .q4-container { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.q4-brand { display: inline-flex; align-items: center; gap: var(--space-2); font: 700 16px/22px var(--font-sans); letter-spacing: -.01em; color: var(--ink); text-decoration: none; }
.q4-mark { width: 28px; height: 28px; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--primary); color: var(--on-primary); font: 700 12px/1 var(--font-sans); flex: none; }
.q4-site-footer { border-top: 1px solid var(--border); padding: var(--space-4) 0; color: var(--ink-muted); font: 400 13px/20px var(--font-sans); }
.q4-site-footer .q4-container { display: flex; align-items: center; justify-content: center; gap: var(--space-3); flex-wrap: wrap; }

/* dashboard shell */
.q4-dash { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.q4-sidebar { position: fixed; inset: 0 auto 0 0; width: var(--layout-sidebar); z-index: var(--z-sidebar); display: flex; flex-direction: column; background: var(--surface); border-right: 1px solid var(--border); }
.q4-sidebar__brand { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); height: 56px; padding: 0 var(--space-4); border-bottom: 1px solid var(--border); flex: none; }
.q4-sidebar__brand .q4-sidebar__close { display: none; }
.q4-nav { display: flex; flex-direction: column; gap: 2px; padding: var(--space-3); flex: 1; overflow-y: auto; }
.q4-nav__group, .q4-nav .dash-nav-group { padding: var(--space-3) var(--space-3) var(--space-1); font: 500 12px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-muted); }
.q4-nav__item, .q4-nav .dash-nav-item, .q4-nav__back, .q4-nav .dash-nav-back {
  display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 36px; padding: 0 var(--space-3);
  border: 0; border-radius: var(--radius-md); background: transparent; color: var(--ink-muted);
  font: 500 14px/20px var(--font-sans); text-align: left; text-decoration: none; cursor: pointer;
}
.q4-nav__item:hover, .q4-nav .dash-nav-item:hover, .q4-nav__back:hover, .q4-nav .dash-nav-back:hover { background: var(--primary-soft); color: var(--ink); text-decoration: none; }
.q4-nav__item[aria-current="page"], .q4-nav__item.is-active,
.q4-nav .dash-nav-item.active { background: var(--primary-soft); color: var(--primary); box-shadow: inset 2px 0 0 var(--primary); }
.q4-nav i { width: 16px; text-align: center; }
.q4-sidebar__foot { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); flex: none; }
.q4-sidebar__user { min-width: 0; flex: 1; font: 500 13px/18px var(--font-sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q4-sidebar__user small { display: block; color: var(--ink-muted); font-weight: 400; }
.q4-topbar { display: none; }
.q4-main { flex: 1; min-width: 0; min-height: 0; margin-left: var(--layout-sidebar); display: flex; flex-direction: column; overflow: hidden; }
.q4-main__content { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: var(--space-6) var(--space-5) var(--space-8); }

/* Info strip (e.g. a live clock row) — a plain, unpadded direct child of
   .q4-main (not .q4-main__content, which is the only part of .q4-main that
   scrolls — see .q4-main/.q4-main__content above). Being outside the
   scrolling element, it naturally stays in place with no sticky/scroll
   trickery needed. Opt in per-page/per-project via the main_prefix block. */
.q4-timebar {
  flex: none;
  height: var(--layout-topbar);
  display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap;
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding: 0 var(--space-5);
}
.q4-timebar__label { display: flex; align-items: center; gap: 6px; color: var(--ink-muted); font: 700 11px/16px var(--font-sans); text-transform: uppercase; letter-spacing: .04em; }
.q4-timebar__label i { color: var(--primary); }
.q4-timebar__item { display: flex; align-items: center; gap: 6px; }
.q4-timebar__tz { color: var(--ink-muted); font: 600 12px/16px var(--font-sans); }
.q4-timebar__value { font: 600 14px/20px var(--font-mono); color: var(--ink); }
.q4-timebar__sep { width: 1px; height: 16px; background: var(--border); }
@media (max-width: 768px) {
  .q4-timebar { height: auto; padding-block: var(--space-2); }
}
@media (max-width: 599px) {
  .q4-timebar { padding-inline: var(--space-4); }
}
.q4-page { width: 100%; max-width: var(--layout-content); margin-inline: auto; padding: var(--space-6) var(--space-5); }
.q4-nav-scrim { display: none; }
@media (max-width: 768px) {
  .q4-sidebar { transform: translateX(-100%); transition: transform .2s; box-shadow: var(--shadow-lg); }
  .q4-sidebar.is-open, .q4-sidebar.open { transform: none; }
  .q4-sidebar__brand .q4-sidebar__close { display: inline-flex; }
  .q4-main { margin-left: 0; }
  .q4-topbar { display: flex; align-items: center; gap: var(--space-2); position: sticky; top: 0; z-index: var(--z-sticky); height: var(--layout-topbar); padding: 0 var(--space-3); background: var(--surface); border-bottom: 1px solid var(--border); }
  .q4-topbar__title { flex: 1; font: 600 15px/22px var(--font-sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .q4-nav-scrim { position: fixed; inset: 0; z-index: calc(var(--z-sidebar) - 1); background: var(--overlay); }
  .q4-nav-scrim.is-open, .q4-nav-scrim.open, .q4-nav-scrim.visible { display: block; }
}
@media (max-width: 599px) {
  .q4-main__content { padding: var(--space-4); }
  .q4-page { padding: var(--space-4); }
}
html.embed-mode .q4-sidebar, html.embed-mode .q4-topbar, html.embed-mode .q4-nav-scrim, html.embed-mode .q4-site-header, html.embed-mode .q4-site-footer { display: none !important; }
html.embed-mode .q4-main { margin-left: 0; }
html.embed-mode .q4-main__content { padding: var(--space-4); }

/* page header, breadcrumb, card */
.q4-pagehead { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5); }
.q4-pagehead__title { margin: 0; display: flex; align-items: center; gap: var(--space-3); font: 700 28px/36px var(--font-sans); letter-spacing: -.02em; }
.q4-pagehead__title i, .q4-pagehead__title .q4-icon { color: var(--primary); }
.q4-pagehead__sub { margin: 2px 0 0; color: var(--ink-muted); font: 400 14px/22px var(--font-sans); }
.q4-pagehead__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.q4-crumbs { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3); color: var(--ink-muted); font: 500 13px/18px var(--font-sans); }
.q4-crumbs a { color: var(--ink-muted); text-decoration: none; }
.q4-crumbs a:hover { color: var(--primary); }
.q4-crumbs [aria-current="page"] { color: var(--ink); }
.q4-crumbs__sep { color: var(--border-strong); }
h1.q4-h1 { font: 700 28px/36px var(--font-sans); letter-spacing: -.02em; margin: 0; }
.q4-h2 { font: 650 22px/30px var(--font-sans); letter-spacing: -.015em; margin: 0; }
.q4-h3 { font: 600 18px/26px var(--font-sans); letter-spacing: -.01em; margin: 0; }
.q4-h4 { font: 600 15px/22px var(--font-sans); margin: 0; }
.q4-eyebrow { font: 500 12px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-muted); }

.q4-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: var(--shadow-sm); }
.q4-card--flush { padding: 0; overflow: hidden; }
.q4-card--accent { border-left: 3px solid var(--primary); }
.q4-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-4); }
.q4-card--flush > .q4-card__head { margin: 0; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.q4-card__title { margin: 0; display: flex; align-items: center; gap: var(--space-2); font: 600 18px/26px var(--font-sans); letter-spacing: -.01em; }
.q4-card__title i, .q4-card__title .q4-icon { color: var(--primary); }
.q4-card__foot { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.q4-card--flush > .q4-card__foot { margin: 0; padding: var(--space-3) var(--space-4); }
.q4-divider { height: 1px; border: 0; margin: var(--space-4) 0; background: var(--border); }
.q4-kv { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-5); margin: 0; }
.q4-kv dt { color: var(--ink-muted); font: 400 13px/20px var(--font-sans); }
.q4-kv dd { margin: 0; font: 500 14px/22px var(--font-sans); min-width: 0; overflow-wrap: anywhere; }
.q4-hero { padding: var(--space-8) 0 var(--space-7); display: flex; align-items: center; justify-content: space-between; gap: var(--space-7); flex-wrap: wrap; }
.q4-hero__title { margin: 0; font: 700 56px/64px var(--font-sans); letter-spacing: -.03em; }
.q4-hero__text { margin: var(--space-4) 0 0; max-width: 520px; color: var(--ink-muted); font: 400 18px/28px var(--font-sans); }
.q4-hero__media { width: min(100%, 480px); aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius-lg); border: 1px solid var(--border); box-shadow: var(--shadow-md); }
@media (max-width: 768px) { .q4-hero__title { font-size: 36px; line-height: 44px; } .q4-pagehead__title { font-size: 22px; line-height: 30px; } }
.q4-auth { min-height: calc(100vh - 64px); display: grid; place-items: center; padding: var(--space-5) var(--space-4); }

/* Opt-in via page_class — fits the whole page (header+content+footer) inside
   the viewport, no page scroll, for short fixed-size content like an auth
   card or a 404 message. .q4-shell > main already has flex:1, so capping the
   shell's own height to 100vh is enough; .q4-auth's own min-height must be
   dropped to 0 so it doesn't force an overflow past what's left for footer. */
body.q4-fit-page .q4-shell { height: 100vh; overflow: hidden; }
body.q4-fit-page .q4-auth { min-height: 0; }
.q4-auth__card { width: min(100%, 400px); display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-6); box-shadow: var(--shadow-md); }

/* ---------- 2. actions ---------- */
.q4-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: 36px; padding: 0 var(--space-4); border: 1px solid transparent; border-radius: var(--radius-md);
  font: 500 14px/20px var(--font-sans); white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.q4-btn:disabled, .q4-btn[aria-disabled="true"], .q4-btn.is-disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }
.q4-btn--primary { background: var(--primary); color: var(--on-primary); }
.q4-btn--primary:hover { background: var(--primary-hover); }
.q4-btn--secondary { background: transparent; color: var(--ink); border-color: var(--border-strong); }
.q4-btn--secondary:hover { background: var(--primary-soft); border-color: var(--primary); }
.q4-btn--ghost { background: transparent; color: var(--ink-muted); }
.q4-btn--ghost:hover { background: var(--primary-soft); color: var(--ink); }
.q4-btn--danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.q4-btn--danger:hover { background: var(--danger-soft); }
.q4-btn--danger-solid { background: var(--danger); color: var(--on-danger); }
.q4-btn--danger-solid:hover { filter: brightness(1.08); }
.q4-btn--warning { background: transparent; color: var(--warning); border-color: var(--warning); }
.q4-btn--warning:hover { background: var(--warning-soft); }
.q4-btn--sm { height: 30px; padding: 0 var(--space-3); font-size: 13px; line-height: 18px; }
.q4-btn--lg { height: 44px; padding: 0 var(--space-5); font-size: 14px; }
.q4-btn--icon { width: 36px; padding: 0; }
.q4-btn--icon.q4-btn--sm { width: 30px; }
.q4-btn--block { width: 100%; }
.q4-btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.q4-btn.is-loading::after { content: ""; position: absolute; width: 14px; height: 14px; border: 2px solid var(--border-strong); border-top-color: var(--ink); border-radius: 50%; animation: q4-spin .8s linear infinite; }
.q4-btn--primary.is-loading::after { border-color: #04130c55; border-top-color: var(--on-primary); }
.q4-btn-row { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.q4-btn-group { display: inline-flex; }
.q4-btn-group > .q4-btn { border-radius: 0; margin-left: -1px; }
.q4-btn-group > .q4-btn:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); margin-left: 0; }
.q4-btn-group > .q4-btn:last-child { border-radius: 0 var(--radius-md) var(--radius-md) 0; }

/* segmented control (hist-switch, rm-mode-toggle, fm-kg-view-toggle) */
.q4-seg { display: inline-flex; padding: 2px; gap: 2px; background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-md); }
.q4-seg__btn { height: 30px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-muted); font: 500 13px/18px var(--font-sans); cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-2); }
.q4-seg__btn:hover { color: var(--ink); }
.q4-seg__btn[aria-pressed="true"], .q4-seg__btn.is-active, .q4-seg__btn.active { background: var(--primary); color: var(--on-primary); }

/* ---------- 3. forms ---------- */
.q4-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.q4-label { font: 500 13px/18px var(--font-sans); color: var(--ink); }
.q4-label .q4-req { color: var(--danger); }
.q4-hint { font: 400 13px/20px var(--font-sans); color: var(--ink-muted); }
.q4-error { display: flex; gap: var(--space-1); align-items: center; font: 400 13px/20px var(--font-sans); color: var(--danger); }
.q4-input, .q4-select, .q4-textarea {
  width: 100%; height: 36px; padding: 0 var(--space-3); background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md); font: 400 14px/22px var(--font-sans);
}
.q4-textarea { height: auto; min-height: 96px; padding: var(--space-2) var(--space-3); resize: vertical; }
.q4-input--sm, .q4-select--sm { height: 30px; font-size: 13px; }
.q4-input::placeholder, .q4-textarea::placeholder { color: var(--ink-muted); }
.q4-input:hover, .q4-select:hover, .q4-textarea:hover { border-color: var(--ink-muted); }
.q4-input:focus-visible, .q4-select:focus-visible, .q4-textarea:focus-visible { outline: 2px solid color-mix(in srgb, var(--focus) 55%, transparent); outline-offset: 1px; }
.q4-input[aria-invalid="true"], .q4-select[aria-invalid="true"], .q4-textarea[aria-invalid="true"], .q4-input.is-invalid { border-color: var(--danger); }
.q4-input:disabled, .q4-select:disabled, .q4-textarea:disabled { opacity: .5; cursor: not-allowed; }
.q4-input[type="number"] { font-variant-numeric: tabular-nums; }
.q4-select {
  appearance: none; -webkit-appearance: none; padding-right: 32px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b8378' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
.q4-select option { background: var(--surface-raised); color: var(--ink); }
.q4-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); }
.q4-form-section { margin: var(--space-5) 0 var(--space-3); font: 600 15px/22px var(--font-sans); padding-bottom: var(--space-2); border-bottom: 1px solid var(--border); }

/* filter bar (pagination + filter row — used on uids, history, gift_codes, knowledge pages) */
.q4-filter-bar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3) 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5); margin-bottom: var(--space-5);
}
.q4-filter-group { display: flex; flex-direction: column; gap: 5px; }
.q4-filter-group label { font: 700 12px/16px var(--font-sans); letter-spacing: .05em; text-transform: uppercase; color: var(--ink-muted); }
.q4-filter-group--search { flex: 1 1 220px; min-width: 220px; }
.q4-filter-actions { display: flex; gap: var(--space-2); align-items: center; }
.q4-filter-sep { width: 1px; align-self: stretch; background: var(--border); margin: 0 2px; }

/* search box with icon + clear (gc-search, kb-docs-search, sc-filter, fm-kg-search) */
.q4-search { position: relative; display: block; min-width: 180px; }
.q4-search > i, .q4-search > .q4-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--ink-muted); pointer-events: none; }
.q4-search .q4-input { padding-left: 34px; padding-right: 32px; }
.q4-search__clear { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; display: none; place-items: center; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-muted); cursor: pointer; }
.q4-search__clear:hover { color: var(--ink); background: var(--primary-soft); }
.q4-search.has-value .q4-search__clear, .q4-search__clear.is-visible { display: grid; }

/* check / radio / switch */
.q4-check, .q4-radio { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; font: 400 14px/22px var(--font-sans); }
.q4-check input, .q4-radio input { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; flex: none; border: 1px solid var(--border-strong); background: var(--surface); cursor: pointer; display: grid; place-content: center; }
.q4-check input { border-radius: var(--radius-sm); }
.q4-radio input { border-radius: 50%; }
.q4-check input:checked, .q4-radio input:checked { background: var(--primary); border-color: var(--primary); }
.q4-check input:checked::after { content: ""; width: 9px; height: 5px; border-left: 2px solid var(--on-primary); border-bottom: 2px solid var(--on-primary); transform: translateY(-1px) rotate(-45deg); }
.q4-radio input:checked::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--on-primary); }
.q4-check input:disabled, .q4-radio input:disabled { opacity: .5; cursor: not-allowed; }
.q4-switch { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; font: 400 14px/22px var(--font-sans); }
.q4-switch input { appearance: none; -webkit-appearance: none; width: 36px; height: 20px; margin: 0; flex: none; cursor: pointer; background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-full); position: relative; transition: background .12s; }
.q4-switch input::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--ink-muted); transition: transform .12s, background .12s; }
.q4-switch input:checked { background: var(--primary); border-color: var(--primary); }
.q4-switch input:checked::after { transform: translateX(16px); background: var(--on-primary); }
.q4-switch input:disabled { opacity: .5; cursor: not-allowed; }
.q4-switch-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid var(--border); }
.q4-switch-row + .q4-btn-row { margin-top: var(--space-4); }
.q4-switch-row__text small { display: block; color: var(--ink-muted); font-size: 13px; line-height: 20px; }

/* choice cards — radio cards (scheduler type-radio-opt, interval-opt) */
.q4-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
.q4-choice { position: relative; display: flex; flex-direction: column; gap: 2px; padding: var(--space-3) var(--space-4); border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); cursor: pointer; }
.q4-choice input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.q4-choice__title { font: 500 14px/22px var(--font-sans); }
.q4-choice__desc { font: 400 13px/20px var(--font-sans); color: var(--ink-muted); }
.q4-choice:hover { border-color: var(--ink-muted); }
.q4-choice:has(input:checked), .q4-choice.is-selected, .q4-choice.selected { border-color: var(--primary); background: var(--primary-soft); box-shadow: inset 0 0 0 1px var(--primary); }
.q4-choice:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }

/* day picker (day-btn, src-day-btn) */
.q4-daypick { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.q4-daypick__btn { min-width: 42px; height: 32px; padding: 0 var(--space-2); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink-muted); font: 500 13px/18px var(--font-sans); cursor: pointer; }
.q4-daypick__btn:hover { color: var(--ink); border-color: var(--ink-muted); }
.q4-daypick__btn[aria-pressed="true"], .q4-daypick__btn.is-selected, .q4-daypick__btn.selected, .q4-daypick__btn.active { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }

/* chips (filter chips, permission chips, kg type chips) */
.q4-chip { display: inline-flex; align-items: center; gap: var(--space-2); height: 28px; padding: 0 var(--space-3); border: 1px solid var(--border-strong); border-radius: var(--radius-full); background: transparent; color: var(--ink-muted); font: 500 13px/18px var(--font-sans); cursor: pointer; }
.q4-chip:hover { color: var(--ink); border-color: var(--ink-muted); }
.q4-chip[aria-pressed="true"], .q4-chip.is-active, .q4-chip.active, .q4-chip:has(input:checked) { background: var(--primary-soft); border-color: var(--primary); color: var(--primary); }
.q4-chip input { position: absolute; opacity: 0; pointer-events: none; }
.q4-chip__count { padding: 0 6px; border-radius: var(--radius-full); background: var(--primary-soft); font-size: 12px; line-height: 18px; }
.q4-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* dropzone (oa-dropzone) */
.q4-dropzone { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-6); border: 2px dashed var(--border-strong); border-radius: var(--radius-lg); background: var(--bg); color: var(--ink-muted); text-align: center; cursor: pointer; }
.q4-dropzone:hover, .q4-dropzone.is-dragover, .q4-dropzone.drag-over { border-color: var(--primary); background: var(--primary-soft); color: var(--ink); }
.q4-dropzone__label { font: 500 14px/22px var(--font-sans); color: var(--ink); }

/* ---------- 4. data display ---------- */
.q4-table-wrap { position: relative; min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: auto; box-shadow: var(--shadow-sm); }
.q4-table { width: 100%; border-collapse: collapse; font: 400 14px/22px var(--font-sans); font-variant-numeric: tabular-nums; }
.q4-table th { position: sticky; top: 0; z-index: 1; text-align: left; white-space: nowrap; padding: var(--space-2) var(--space-4); background: var(--surface-raised); border-bottom: 1px solid var(--border); font: 500 12px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-muted); }
.q4-table td { padding: var(--space-2) var(--space-4); border-bottom: 1px solid var(--border); vertical-align: middle; }
.q4-table tbody tr:last-child td { border-bottom: 0; }
.q4-table tbody tr:hover { background: var(--primary-soft); }
.q4-table tr[aria-selected="true"], .q4-table tr.is-selected, .q4-table tr.selected { background: var(--primary-soft); box-shadow: inset 3px 0 0 var(--primary); }
.q4-table .q4-num, .q4-table th.q4-num { text-align: right; }
.q4-table--nowrap td { white-space: nowrap; }
.q4-table th[data-sort], .q4-table th.sortable { cursor: pointer; user-select: none; }
.q4-table th[aria-sort="ascending"], .q4-table th[aria-sort="descending"], .q4-table th.active-sort { color: var(--primary); }
.q4-table th[aria-sort="ascending"]::after { content: " \25B2"; font-size: 9px; }
.q4-table th[aria-sort="descending"]::after { content: " \25BC"; font-size: 9px; }

/* Mobile: each row becomes a stacked card with "label: value" pairs. Labels come
   from data-label, filled in from the column headers by q4-ui.js. Switches at 1100px rather than 768px:
   the sidebar leaves ~760px at 1024px, narrower than most tables' natural width. */
@media (max-width: 1100px) {
  .q4-table-wrap { overflow: visible; background: transparent; border: 0; box-shadow: none; }
  .q4-table, .q4-table tbody, .q4-table tr, .q4-table td { display: block; width: 100%; }
  .q4-table thead { display: none; }
  .q4-table tbody { display: flex; flex-direction: column; gap: var(--space-3); }
  .q4-table tbody tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-3); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-3); }
  .q4-table tbody tr:hover { background: var(--surface); }
  .q4-table td { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 0; border-bottom: 0; text-align: left; min-width: 0; overflow-wrap: anywhere; }
  .q4-table td[data-label]::before { content: attr(data-label); font: 500 11px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-muted); }
  .q4-table td[colspan] { grid-column: 1 / -1; display: block; text-align: center; padding: var(--space-3) 0; }
  .q4-table td[colspan]::before { content: none; }
}
.q4-table__actions { display: flex; gap: var(--space-1); justify-content: flex-end; }
.q4-cell-sub { display: block; color: var(--ink-muted); font: 400 12px/16px var(--font-sans); }
.q4-table-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }

/* toolbar + compact pager (cp-nav-bar): filters | pagination | count */
.q4-toolbar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-3); min-height: 42px; padding: 0 var(--space-1) var(--space-3); }
.q4-toolbar__left { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
.q4-toolbar__center { display: flex; align-items: center; justify-content: center; gap: var(--space-1); }
.q4-toolbar__right { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); white-space: nowrap; color: var(--ink-muted); font: 400 13px/20px var(--font-sans); }
.q4-pager { display: inline-flex; align-items: center; gap: var(--space-1); }
.q4-pager__btn { width: 30px; height: 30px; display: inline-grid; place-items: center; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-muted); cursor: pointer; }
.q4-pager__btn:hover:not(:disabled):not(.is-disabled) { background: var(--primary-soft); color: var(--primary); }
.q4-pager__btn:disabled, .q4-pager__btn.is-disabled { opacity: .3; cursor: default; pointer-events: none; }
.q4-pager__input { width: 48px; height: 30px; text-align: center; background: var(--surface); color: var(--ink); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); font: 400 13px/18px var(--font-sans); -moz-appearance: textfield; appearance: textfield; }
.q4-pager__input::-webkit-inner-spin-button, .q4-pager__input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.q4-pager__total { color: var(--ink-muted); font: 400 13px/20px var(--font-sans); white-space: nowrap; }
@media (max-width: 768px) { .q4-toolbar { display: flex; flex-direction: column; align-items: stretch; } .q4-toolbar__center { justify-content: center; } .q4-toolbar__right { justify-content: flex-start; } }

/* stat card */
.q4-stat { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.q4-stat__title { display: flex; align-items: center; gap: var(--space-2); font: 500 12px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-muted); }
.q4-stat__title i, .q4-stat__title .q4-icon { color: var(--primary); }
.q4-stat__value { font: 700 32px/38px var(--font-sans); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.q4-stat__value small { font-size: 18px; color: var(--ink-muted); font-weight: 500; }
.q4-stat__meta { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; font: 400 13px/20px var(--font-sans); color: var(--ink-muted); }
.q4-stat--click { cursor: pointer; }
.q4-stat--click:hover, .q4-stat.is-active { border-color: var(--primary); }
.q4-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); }

/* progress */
.q4-progress { height: 6px; border-radius: var(--radius-full); background: var(--primary-soft); overflow: hidden; }
.q4-progress > span { display: block; height: 100%; width: 0; background: var(--primary); border-radius: inherit; transition: width .3s; }
.q4-progress--lg { height: 10px; }
.q4-progress--warning > span { background: var(--warning); }
.q4-progress--danger > span { background: var(--danger); }
.q4-progress--indeterminate > span { width: 40%; animation: q4-indet 1.2s ease-in-out infinite; }
@keyframes q4-indet { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
.q4-progress-head { display: flex; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-1); font: 500 13px/18px var(--font-sans); }
.q4-progress-head span:last-child { color: var(--ink-muted); }

/* badge / dot */
.q4-badge { display: inline-flex; align-items: center; gap: var(--space-1); height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-sm); font: 500 12px/16px var(--font-sans); white-space: nowrap; }
.q4-badge i, .q4-badge .q4-icon { font-size: 11px; width: 12px; height: 12px; }
.q4-badge--neutral { background: var(--primary-soft); color: var(--ink); }
.q4-badge--success { background: var(--success-soft); color: var(--success); }
.q4-badge--warning { background: var(--warning-soft); color: var(--warning); }
.q4-badge--danger { background: var(--danger-soft); color: var(--danger); }
.q4-badge--info { background: var(--info-soft); color: var(--info); }
.q4-badge--brand { background: var(--primary); color: var(--on-primary); }
.q4-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); flex: none; }
.q4-dot--ok { background: var(--success); } .q4-dot--warn { background: var(--warning); } .q4-dot--err { background: var(--danger); } .q4-dot--info { background: var(--info); }
.q4-dot.is-live, .q4-dot.on { background: var(--success); animation: q4-pulse 1.6s ease-in-out infinite; }
@keyframes q4-pulse { 0%, 100% { box-shadow: 0 0 0 0 #4ade8066; } 50% { box-shadow: 0 0 0 5px transparent; } }
.q4-live { display: inline-flex; align-items: center; gap: var(--space-2); font: 500 12px/16px var(--font-sans); color: var(--ink-muted); }
.q4-code { display: inline-block; padding: 1px 6px; border-radius: var(--radius-sm); background: var(--bg); border: 1px solid var(--border); font: 400 13px/20px var(--font-mono); }
.q4-pre { margin: 0; padding: var(--space-3) var(--space-4); overflow: auto; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md); font: 400 13px/20px var(--font-mono); white-space: pre-wrap; word-break: break-word; }
.q4-copy { display: flex; align-items: stretch; gap: var(--space-2); }
.q4-copy > .q4-pre, .q4-copy > .q4-code { flex: 1; min-width: 0; }

/* dual timezone cell (renderDualTime keeps working; legacy classes styled too) */
.q4-dt, .q4-app .dual-time { display: block; }
.q4-dt__primary, .q4-app .dt-primary { display: block; font: 400 14px/22px var(--font-sans); }
.q4-dt__secondary, .q4-app .dt-secondary { display: block; margin-top: 1px; color: var(--ink-muted); font: 400 12px/16px var(--font-sans); }
.q4-tz, .q4-app .tz-label { color: var(--ink-muted); font-weight: 500; font-size: 12px; letter-spacing: .02em; }

/* list rows */
.q4-list { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.q4-list__row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.q4-list__row:last-child { border-bottom: 0; }
.q4-list__main { flex: 1; min-width: 0; font: 500 14px/22px var(--font-sans); }
.q4-list__main small { display: block; color: var(--ink-muted); font-weight: 400; font-size: 13px; line-height: 20px; }
.q4-tile { width: 40px; height: 40px; display: grid; place-items: center; flex: none; border-radius: var(--radius-md); background: var(--primary-soft); color: var(--primary); }
.q4-avatar { width: 30px; height: 30px; display: grid; place-items: center; flex: none; border-radius: var(--radius-full); background: var(--primary-soft); color: var(--primary); font: 600 12px/1 var(--font-sans); overflow: hidden; object-fit: cover; }
.q4-avatar--lg { width: 48px; height: 48px; font-size: 16px; }

/* steps — vertical job steps (tool page) + wizard bar (setup) */
.q4-steps { display: flex; flex-direction: column; }
.q4-step { display: grid; grid-template-columns: 24px 1fr; gap: var(--space-3); position: relative; padding-bottom: var(--space-4); }
.q4-step:last-child { padding-bottom: 0; }
.q4-step::before { content: ""; position: absolute; left: 11px; top: 24px; bottom: 0; width: 2px; background: var(--border); }
.q4-step:last-child::before { display: none; }
.q4-step__icon { width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; background: var(--surface-raised); border: 1px solid var(--border-strong); color: var(--ink-muted); font-size: 12px; z-index: 1; }
.q4-step__text { font: 500 14px/24px var(--font-sans); }
.q4-step__text small { display: block; color: var(--ink-muted); font-weight: 400; font-size: 13px; line-height: 20px; }
.q4-step.is-running .q4-step__icon { border-color: var(--info); color: var(--info); }
.q4-step.is-success .q4-step__icon { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.q4-step.is-fail .q4-step__icon { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.q4-step.is-retry .q4-step__icon { background: var(--warning-soft); border-color: var(--warning); color: var(--warning); }
.q4-wizard { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-5); }
.q4-wizard__step { display: inline-flex; align-items: center; gap: var(--space-2); height: 32px; padding: 0 var(--space-3); border: 1px solid var(--border-strong); border-radius: var(--radius-full); color: var(--ink-muted); font: 500 13px/18px var(--font-sans); background: transparent; cursor: default; }
.q4-wizard__num { width: 20px; height: 20px; display: grid; place-items: center; border-radius: 50%; background: var(--surface-raised); font-size: 12px; }
.q4-wizard__step.is-active, .q4-wizard__step.active { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.q4-wizard__step.is-done { color: var(--ink); } .q4-wizard__step.is-done .q4-wizard__num { background: var(--primary); color: var(--on-primary); }

/* log rows (scheduler run logs) */
.q4-log { display: flex; flex-direction: column; }
.q4-log__row { display: grid; grid-template-columns: 20px auto 1fr; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); font: 400 13px/20px var(--font-sans); }
.q4-log__row:last-child { border-bottom: 0; }
.q4-log__time { color: var(--ink-muted); font-family: var(--font-mono); font-size: 12px; white-space: nowrap; }

/* ---------- 5. feedback ---------- */
.q4-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid var(--border-strong); border-top-color: var(--primary); border-radius: 50%; animation: q4-spin .8s linear infinite; flex: none; }
.q4-spinner--sm { width: 12px; height: 12px; border-width: 2px; }
.q4-spinner--lg { width: 28px; height: 28px; border-width: 3px; }
.q4-loading { display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-6) var(--space-4); color: var(--ink-muted); font: 400 14px/22px var(--font-sans); }
.q4-loading--inline { display: inline-flex; padding: 0; }
td.q4-loading { display: table-cell; text-align: center; }
.q4-loading-overlay { position: absolute; inset: 0; z-index: 2; display: none; place-items: center; background: color-mix(in srgb, var(--surface) 72%, transparent); border-radius: inherit; }
.is-busy > .q4-loading-overlay, .q4-loading-overlay.is-visible { display: grid; }
.q4-skel { display: block; height: 14px; border-radius: var(--radius-sm); background: linear-gradient(90deg, var(--surface-raised), var(--border), var(--surface-raised)); background-size: 200% 100%; animation: q4-shimmer 1.4s linear infinite; }
.q4-skel--block { height: 80px; border-radius: var(--radius-md); }
@keyframes q4-shimmer { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .q4-skel, .q4-dot.is-live, .q4-dot.on, .q4-progress--indeterminate > span { animation: none; } }

.q4-empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-8) var(--space-5); text-align: center; }
.q4-empty--compact { padding: var(--space-5) var(--space-4); }
td.q4-empty { display: table-cell; text-align: center; color: var(--ink-muted); padding: var(--space-6) var(--space-4); }
.q4-empty__icon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: var(--radius-lg); background: var(--primary-soft); color: var(--primary); margin-bottom: var(--space-2); font-size: 20px; }
.q4-empty__title { margin: 0; font: 600 15px/22px var(--font-sans); }
.q4-empty__text { margin: 0 0 var(--space-3); max-width: 360px; color: var(--ink-muted); font: 400 14px/22px var(--font-sans); }
.q4-empty__code { font: 700 72px/80px var(--font-sans); letter-spacing: -.04em; color: var(--primary); margin: 0; }

.q4-alert { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); font: 400 14px/22px var(--font-sans); }
.q4-alert > i, .q4-alert > .q4-icon { margin-top: 3px; }
.q4-alert__body { flex: 1; min-width: 0; }
.q4-alert__title { font-weight: 600; }
.q4-alert--info { background: var(--info-soft); border-color: var(--info); } .q4-alert--info > i, .q4-alert--info > .q4-icon { color: var(--info); }
.q4-alert--success { background: var(--success-soft); border-color: var(--success); } .q4-alert--success > i, .q4-alert--success > .q4-icon { color: var(--success); }
.q4-alert--warning { background: var(--warning-soft); border-color: var(--warning); } .q4-alert--warning > i, .q4-alert--warning > .q4-icon { color: var(--warning); }
.q4-alert--danger { background: var(--danger-soft); border-color: var(--danger); } .q4-alert--danger > i, .q4-alert--danger > .q4-icon { color: var(--danger); }

.q4-toasts { position: fixed; right: var(--space-4); bottom: var(--space-4); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-2); width: min(360px, calc(100vw - 32px)); pointer-events: none; }
.q4-toast { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); font: 400 14px/22px var(--font-sans); color: var(--ink); pointer-events: auto; animation: q4-toast-in .18s ease-out; }
@keyframes q4-toast-in { from { opacity: 0; transform: translateY(8px); } }
.q4-toast > i, .q4-toast > .q4-icon { margin-top: 3px; }
.q4-toast--success > i, .q4-toast--success > .q4-icon { color: var(--success); }
.q4-toast--warning > i, .q4-toast--warning > .q4-icon { color: var(--warning); }
.q4-toast--danger > i, .q4-toast--danger > .q4-icon { color: var(--danger); }
.q4-toast--info > i, .q4-toast--info > .q4-icon { color: var(--info); }
.q4-toast__body { flex: 1; min-width: 0; }
.q4-toast__title { font-weight: 600; }
.q4-toast__close { border: 0; background: transparent; color: var(--ink-muted); cursor: pointer; padding: 0 var(--space-1); }

/* ---------- 6. overlays ---------- */
.q4-overlay { position: fixed; inset: 0; z-index: var(--z-modal); display: none; place-items: center; padding: var(--space-4); background: var(--overlay); }
.q4-overlay.is-open, .q4-overlay.open, .q4-overlay.show { display: grid; }
.q4-modal { width: min(480px, 100%); max-height: calc(100vh - 160px); overflow: hidden; display: flex; flex-direction: column; background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.q4-modal--sm { width: min(400px, 100%); } .q4-modal--md { width: min(820px, 100%); } .q4-modal--lg { width: min(720px, 100%); } .q4-modal--xl { width: min(960px, 100%); }
.q4-modal__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); flex: none; min-width: 0; }
.q4-modal__title { margin: 0; font: 600 15px/22px var(--font-sans); }
.q4-modal__body { padding: var(--space-5); overflow: auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.q4-modal__foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border); flex: none; }
.q4-pop { position: absolute; z-index: var(--z-dropdown); min-width: 220px; max-width: 320px; padding: var(--space-3) var(--space-4); background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-md); font: 400 13px/20px var(--font-sans); }
.q4-menu { position: absolute; z-index: var(--z-dropdown); min-width: 180px; padding: var(--space-1); background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-md); }
.q4-menu__item { display: flex; align-items: center; gap: var(--space-2); width: 100%; height: 32px; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink); font: 400 13px/18px var(--font-sans); text-align: left; cursor: pointer; }
.q4-menu__item:hover { background: var(--primary-soft); }
.q4-menu__item--danger { color: var(--danger); }

/* ---------- 7. navigation: tabs ---------- */
.q4-tabs { display: flex; gap: var(--space-1); height: 40px; border-bottom: 1px solid var(--border); overflow-x: auto; overflow-y: hidden; }
.q4-tabs { scrollbar-width: none; -ms-overflow-style: none; }
.q4-tabs::-webkit-scrollbar { display: none; }
.q4-tab { display: inline-flex; align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-4); margin-bottom: -1px; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--ink-muted); font: 500 14px/20px var(--font-sans); white-space: nowrap; cursor: pointer; }
.q4-tab:hover { color: var(--ink); }
.q4-tab[aria-selected="true"], .q4-tab.is-active, .q4-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
.q4-tabpanel { display: none; flex-direction: column; gap: var(--space-5); padding-top: var(--space-4); }
.q4-tabpanel.is-active, .q4-tabpanel.active, .q4-tabpanel:not([hidden]).is-open { display: flex; }

/* ---------- 8. composites ---------- */
/* project card (portal) & integration card */
.q4-project { display: flex; flex-direction: column; gap: var(--space-5); }
.q4-project__top { display: flex; gap: var(--space-4); align-items: flex-start; }
.q4-project__logo { width: 44px; height: 44px; border-radius: var(--radius-md); object-fit: contain; flex: none; }
.q4-project__actions { display: flex; gap: var(--space-2); margin-top: auto; }
.q4-grid { display: grid; gap: var(--space-5); grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); }
.q4-grid--2 { --cols: 2; } .q4-grid--3 { --cols: 3; } .q4-grid--4 { --cols: 4; }
@media (max-width: 1024px) { .q4-grid--4 { --cols: 2; } .q4-grid--3 { --cols: 2; } }
@media (max-width: 640px) { .q4-grid, .q4-grid--2, .q4-grid--3, .q4-grid--4 { --cols: 1; } }
.q4-conn { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.q4-jobcard { display: flex; flex-direction: column; gap: var(--space-3); }
.q4-jobcard__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.q4-jobcard__badges { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.q4-notice { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: color-mix(in srgb, var(--primary) 10%, var(--surface)); border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--border)); font: 400 14px/22px var(--font-sans); }

/* chat (FinnMind) */
.q4-chat { display: grid; grid-template-columns: 260px 1fr; height: calc(100vh - 2 * var(--space-6)); min-height: 480px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; }
.q4-chat__side { display: flex; flex-direction: column; border-right: 1px solid var(--border); min-height: 0; }
.q4-chat__side-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.q4-chat__sessions { flex: 1; overflow-y: auto; padding: var(--space-2); }
.q4-chat__session { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); width: 100%; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--ink-muted); font: 500 13px/18px var(--font-sans); text-align: left; cursor: pointer; }
.q4-chat__session:hover { background: var(--primary-soft); color: var(--ink); }
.q4-chat__session.is-active, .q4-chat__session.active { background: var(--primary-soft); color: var(--primary); }
.q4-chat__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.q4-chat__window { flex: 1; overflow-y: auto; padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }
.q4-chat__input { display: flex; gap: var(--space-2); align-items: flex-end; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); }
.q4-chat__input .q4-textarea { min-height: 40px; max-height: 160px; }
.q4-msg { display: flex; gap: var(--space-3); max-width: 820px; }
.q4-msg--user { align-self: flex-end; flex-direction: row-reverse; }
.q4-msg__avatar { width: 32px; height: 32px; border-radius: var(--radius-full); flex: none; overflow: hidden; display: grid; place-items: center; background: var(--primary-soft); color: var(--primary); }
.q4-msg__avatar img { width: 100%; height: 100%; object-fit: cover; }
.q4-msg__bubble { padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); background: var(--surface-raised); border: 1px solid var(--border); min-width: 0; overflow-wrap: anywhere; }
.q4-msg--user .q4-msg__bubble { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
.q4-typing { display: inline-flex; gap: 4px; padding: 6px 0; }
.q4-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-muted); animation: q4-bounce 1.2s infinite ease-in-out; }
.q4-typing i:nth-child(2) { animation-delay: .15s; } .q4-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes q4-bounce { 0%, 60%, 100% { opacity: .3; transform: none; } 30% { opacity: 1; transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .q4-typing i { animation: none; opacity: .6; } }
.q4-cite { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 4px; border-radius: var(--radius-sm); background: var(--primary-soft); color: var(--primary); font: 600 11px/1 var(--font-sans); vertical-align: super; }
.q4-sources { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-2); margin-top: var(--space-3); }
.q4-source { padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg); font: 400 13px/18px var(--font-sans); }
@media (max-width: 768px) {
  .q4-chat { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .q4-chat__side { max-height: 35vh; border-right: 0; border-bottom: 1px solid var(--border); }
}

/* prose (markdown output: chat, wiki, docs) */
.q4-prose { font: 400 14px/24px var(--font-sans); }
.q4-prose > :first-child { margin-top: 0; } .q4-prose > :last-child { margin-bottom: 0; }
.q4-prose h1, .q4-prose h2, .q4-prose h3, .q4-prose h4 { margin: var(--space-5) 0 var(--space-2); line-height: 1.3; letter-spacing: -.01em; }
.q4-prose h1 { font-size: 22px; } .q4-prose h2 { font-size: 18px; } .q4-prose h3 { font-size: 16px; } .q4-prose h4 { font-size: 14px; }
.q4-prose p, .q4-prose ul, .q4-prose ol, .q4-prose blockquote, .q4-prose pre, .q4-prose table { margin: 0 0 var(--space-3); }
.q4-prose ul, .q4-prose ol { padding-left: var(--space-5); }
.q4-prose a { color: var(--primary); }
.q4-prose code { padding: 1px 5px; border-radius: var(--radius-sm); background: var(--bg); border: 1px solid var(--border); font: 400 13px/20px var(--font-mono); }
.q4-prose pre { padding: var(--space-3) var(--space-4); overflow: auto; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md); }
.q4-prose pre code { padding: 0; border: 0; background: none; }
.q4-prose blockquote { padding-left: var(--space-4); border-left: 3px solid var(--border-strong); color: var(--ink-muted); }
.q4-prose table { border-collapse: collapse; width: 100%; font-size: 13px; }
.q4-prose th, .q4-prose td { padding: var(--space-2) var(--space-3); border: 1px solid var(--border); text-align: left; }
.q4-prose th { background: var(--surface-raised); font-weight: 600; }

/* files, knowledge graph, charts */
.q4-filegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-3); }
.q4-file { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); text-align: center; cursor: pointer; font: 500 13px/18px var(--font-sans); overflow-wrap: anywhere; }
.q4-file:hover { border-color: var(--primary); background: var(--primary-soft); }
.q4-file small { color: var(--ink-muted); font-weight: 400; }
.q4-graph { position: relative; height: 560px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg); overflow: hidden; }
.q4-graph__detail { position: absolute; top: var(--space-3); right: var(--space-3); width: 300px; max-height: calc(100% - 24px); overflow: auto; padding: var(--space-4); background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.q4-chartbox { position: relative; height: 260px; }
.q4-legend { display: flex; gap: var(--space-4); flex-wrap: wrap; font: 400 13px/18px var(--font-sans); color: var(--ink-muted); }
.q4-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; }

/* ---------- 9. utilities ---------- */
.q4-muted { color: var(--ink-muted) !important; }
.q4-mono { font-family: var(--font-mono); }
.q4-num { font-variant-numeric: tabular-nums; }
.q4-nowrap { white-space: nowrap; }
.q4-grow { flex: 1; min-width: 0; }
.q4-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.q4-stack { display: flex; flex-direction: column; gap: var(--space-4); }
.q4-stack--sm { gap: var(--space-2); } .q4-stack--lg { gap: var(--space-5); }
.q4-mt-4 { margin-top: var(--space-4); } .q4-mt-5 { margin-top: var(--space-5); } .q4-mb-4 { margin-bottom: var(--space-4); } .q4-mb-5 { margin-bottom: var(--space-5); }
.q4-hidden { display: none !important; }
.q4-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.q4-text-success { color: var(--success); } .q4-text-warning { color: var(--warning); } .q4-text-danger { color: var(--danger); } .q4-text-info { color: var(--info); } .q4-text-primary { color: var(--primary); }

/* ---------- 10. logo variants (theme-aware, no legacy CSS needed) ---------- */
.q4-logo { height: 28px; width: auto; display: block; }
.q4-logo--light { display: none; }
html body.q4-app[data-theme="light"] .q4-logo--dark, html body.q4-app.light-mode .q4-logo--dark { display: none; }
html body.q4-app[data-theme="light"] .q4-logo--light, html body.q4-app.light-mode .q4-logo--light { display: block; }
.q4-actions { display: flex; align-items: center; gap: var(--space-2); }

/* ---------- 11. touch targets (Material: 48x48dp minimum, 8dp between targets) ----------
   Applied on touch devices (coarse pointer) and on widths up to 768px, where the
   layout already collapses. Desktop mouse keeps the dense sizes above. Inline
   height/width on an element beats these rules, so do not set them inline. */
@media (pointer: coarse), (max-width: 768px) {
  .q4-btn, .q4-btn--sm, .q4-btn--lg { height: 48px; }
  .q4-btn--icon, .q4-btn--icon.q4-btn--sm { width: 48px; }
  .q4-input, .q4-select, .q4-input--sm, .q4-select--sm { height: 48px; }
  .q4-search__clear { width: 48px; height: 48px; }
  .q4-nav__item, .q4-nav .dash-nav-item, .q4-nav__back, .q4-nav .dash-nav-back { min-height: 48px; }
  .q4-nav { gap: var(--space-2); }
  .q4-tabs, .q4-tab { height: 48px; }
  .q4-pager { gap: var(--space-2); }
  .q4-pager__btn, .q4-pager__input { width: 48px; height: 48px; }
  .q4-seg__btn { height: 48px; }
  .q4-chip { height: 48px; }
  .q4-daypick { gap: var(--space-2); }
  .q4-daypick__btn { height: 48px; min-width: 48px; }
  .q4-menu__item { height: 48px; }
  .q4-toast__close { min-width: 48px; min-height: 48px; }
  .q4-wizard__step { height: 48px; }
  .q4-check, .q4-radio, .q4-switch { min-height: 48px; }
  .q4-table__actions { gap: var(--space-2); }
}
