/* Everdeck app shell.
   Layout and component vocabulary follow the kitset ops platform (dark 260px sidebar, sticky top bar,
   eyebrow + H1 page heads, table cards, dotted badges). Colours are Everdeck's own, with dark mode.
   Fonts fall back to the system stack until the self-hosted files land in Phase 1. */


:root {
  --side: #1a1622; --side-ink: #ddd8e9; --side-muted: #8f88a3; --side-active: rgba(139, 123, 255, .16); --side-accent: #b2a6ff;
  --canvas: #f5f4f8; --surface: #ffffff; --surface-soft: #f9f8fb; --ink: #1b1726; --muted: #645e73;
  --line: #e6e3ec; --line-strong: #d4cfde;
  --accent: #5b45e0; --accent-dark: #4a35c8; --accent-soft: #ece8fd; --on-accent: #ffffff;
  --green: #17784a; --green-soft: #e2f3ea; --amber: #9a5a00; --amber-soft: #fbefd9;
  --red: #b3303e; --red-soft: #fbe6e8; --blue: #2460c8; --blue-soft: #e5edfc; --grey: #5d576b; --grey-soft: #efedf3;
  --shadow-sm: 0 1px 2px rgba(27, 23, 38, .06); --shadow-md: 0 10px 28px rgba(27, 23, 38, .10);
  --radius-sm: 8px; --radius: 12px; --radius-lg: 18px; --sidebar: 260px; --topbar: 64px;
  --font: "Instrument Sans", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --side: #0b0a0f; --side-active: rgba(139, 123, 255, .18);
    --canvas: #110f16; --surface: #1a1721; --surface-soft: #211d2a; --ink: #ece9f3; --muted: #a39db3;
    --line: #2d2838; --line-strong: #3c354b;
    --accent: #8b7bff; --accent-dark: #a99bff; --accent-soft: #2a2448; --on-accent: #120f1c;
    --green: #4cc38a; --green-soft: #14301f; --amber: #e3a33b; --amber-soft: #33260f;
    --red: #ef6b78; --red-soft: #3a1a1f; --blue: #7aa7ff; --blue-soft: #172743; --grey: #b3adc2; --grey-soft: #2a2633;
    --shadow-sm: none; --shadow-md: 0 10px 28px rgba(0, 0, 0, .45);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --side: #0b0a0f; --side-active: rgba(139, 123, 255, .18);
  --canvas: #110f16; --surface: #1a1721; --surface-soft: #211d2a; --ink: #ece9f3; --muted: #a39db3;
  --line: #2d2838; --line-strong: #3c354b;
  --accent: #8b7bff; --accent-dark: #a99bff; --accent-soft: #2a2448; --on-accent: #120f1c;
  --green: #4cc38a; --green-soft: #14301f; --amber: #e3a33b; --amber-soft: #33260f;
  --red: #ef6b78; --red-soft: #3a1a1f; --blue: #7aa7ff; --blue-soft: #172743; --grey: #b3adc2; --grey-soft: #2a2633;
  --shadow-sm: none; --shadow-md: 0 10px 28px rgba(0, 0, 0, .45);
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* The hidden attribute always wins over component display rules (e.g. .pill). */
[hidden] { display: none !important; }
/* Read by screen readers, not shown. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
a.btn, a.pill, a.icon-btn { text-decoration: none; }
html, body { margin: 0; }
body { min-height: 100vh; background: var(--canvas); color: var(--ink); font: 14px/1.5 var(--font); -webkit-font-smoothing: antialiased; }
a { color: var(--accent-dark); }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
svg.icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: 0 0 auto; }

/* Shell */
.sidebar { position: fixed; inset: 0 auto 0 0; width: var(--sidebar); display: flex; flex-direction: column; padding: 20px 14px 14px; background: var(--side); color: var(--side-ink); z-index: 40; }
.sidebar-brand { display: flex; align-items: center; gap: 10px; padding: 2px 9px 18px; color: #fff; font-weight: 700; font-size: 16px; }
.brand-mark { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 10px; color: #fff; background: linear-gradient(150deg, #6e5af0, #3f2db8); font-weight: 700; }
.workspace { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 9px; align-items: center; margin: 0 2px 18px; padding: 9px 10px; border: 1px solid rgba(255, 255, 255, .08); border-radius: 10px; background: rgba(255, 255, 255, .04); }
.workspace-logo { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; background: var(--side-active); color: var(--side-accent); font-size: 11px; font-weight: 800; }
.workspace-text { min-width: 0; }
.workspace-text strong, .workspace-text span { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.workspace-text strong { font-size: 12px; }
.workspace-text span { color: var(--side-muted); font-size: 10px; }
.nav-scroll { flex: 1; overflow-y: auto; scrollbar-width: thin; }
.nav-label { padding: 0 10px 7px; color: var(--side-muted); font-size: 9px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; }
.nav-group { margin-bottom: 16px; }
.nav-item { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 10px; border-radius: 8px; color: var(--side-ink); opacity: .82; font-size: 12.5px; text-decoration: none; }
.nav-item:hover { opacity: 1; background: rgba(255, 255, 255, .055); }
.nav-item.active { opacity: 1; color: #fff; background: var(--side-active); }
.nav-item.active .icon { color: var(--side-accent); }
.main-shell { margin-left: var(--sidebar); min-height: 100vh; }
.topbar { position: sticky; top: 0; z-index: 30; height: var(--topbar); display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 0 32px; background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: blur(16px); border-bottom: 1px solid var(--line); }
.topbar-left, .topbar-right { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* On a narrow screen the breadcrumb gives way; the buttons on the right keep their size. */
.topbar-left { flex: 1 1 auto; }
.topbar-right, .topbar-right > * { flex: 0 0 auto; }
/* The breadcrumb (navigation.js): links to where the page sits, then the page. The separator is drawn here
   ('›' with empty alternative text, so screen readers skip it; older browsers read the first `content`). A
   long name is cut short; its title attribute keeps the whole. On a narrow screen only the last two show: the
   others are hidden from sight only, so screen readers still read the whole trail, and one comes back while it
   has the keyboard's focus; the first shown then has no separator before it. On a phone the page's own crumb
   goes too (its heading says the same), so the one before it, the way back, has the room. */
.breadcrumb { min-width: 0; font-size: 12px; }
.breadcrumb ol { display: flex; align-items: center; min-width: 0; margin: 0; padding: 0; list-style: none; color: var(--muted); }
.breadcrumb li { display: flex; align-items: center; min-width: 0; flex: 0 1 auto; }
.breadcrumb li + li::before { content: '›'; content: '›' / ''; flex: none; margin: 0 7px; color: var(--muted); }
.breadcrumb a, .breadcrumb span { min-width: 0; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.breadcrumb a { color: var(--muted); text-decoration: none; border-radius: 4px; }
.breadcrumb a:hover { color: var(--ink); text-decoration: underline; }
.breadcrumb [aria-current="page"] { max-width: 40ch; color: var(--ink); font-size: 13px; font-weight: 600; }
/* The thin bar along the bottom of the top bar while a page is slow to render (navigation.js). */
.route-progress { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; overflow: hidden; pointer-events: none; }
.route-progress::before { content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: var(--accent); animation: route-progress 1.1s ease-in-out infinite; }
@keyframes route-progress { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .route-progress::before { width: 100%; opacity: .6; animation: none; } }
.topbar .menu-btn { display: none; }
.scrim { display: none; }
.page { max-width: 1560px; margin: 0 auto; padding: 30px 32px 60px; }
/* The page container takes focus on navigation so screen readers announce the new page; it is not
   a control, so it gets no visible ring. */
.page:focus, .page:focus-visible { outline: none; }
/* A page's head (ui.js pageHead, and agent.js's own): the title block, then the page's buttons. The title
   block takes the room (420px of it at least) and the buttons keep their size, each label on one line. When
   the two can't sit side by side, the buttons go under the title as one row, instead of wrapping inside the
   head. On a phone (680px or narrower) they always go under it, and wrap there when they must. */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px 24px; margin-bottom: 24px; }
.page-head > :not(.page-actions) { flex: 1 1 420px; min-width: 0; }
.page-head > .page-actions { flex: 0 0 auto; flex-wrap: nowrap; }
.page-head .page-actions .btn { white-space: nowrap; }
.page-head h1 { margin: 0; font-size: 25px; line-height: 1.2; letter-spacing: -.035em; }
.page-head p { max-width: 720px; margin: 7px 0 0; color: var(--muted); font-size: 13px; }
.page-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.eyebrow { margin-bottom: 7px; color: var(--accent-dark); font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }

/* Controls */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 38px; padding: 8px 13px; border: 1px solid transparent; border-radius: 9px; font: 600 12px var(--font); cursor: pointer; transition: transform .12s ease; }
.btn:hover { transform: translateY(-1px); }
.btn-primary { color: var(--on-accent); background: var(--accent); }
.btn-primary:hover { background: var(--accent-dark); }
.btn-secondary { color: var(--ink); background: var(--surface); border-color: var(--line-strong); }
.btn-secondary:hover { background: var(--surface-soft); }
.btn-ghost { color: var(--muted); background: transparent; }
/* A button that can't be used now (disabled, or aria-disabled while it explains why) looks it: faded, no lift
   or colour change on hover, and the not-allowed pointer. */
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn-primary:disabled, .btn-primary[aria-disabled="true"] { background: var(--accent); }
.btn-secondary:disabled, .btn-secondary[aria-disabled="true"] { background: var(--surface); }
.icon-btn { width: 36px; height: 36px; display: inline-grid; place-items: center; border: 1px solid var(--line); border-radius: 9px; color: var(--muted); background: var(--surface); cursor: pointer; }
.icon-btn:hover { color: var(--ink); }
/* The profile button (profile-menu.js): the person's initials in a circle, at the end of the top bar. */
.profile-btn { border-radius: 50%; border-color: transparent; background: var(--accent-soft); color: var(--accent-dark); font: 750 11.5px var(--font); letter-spacing: .02em; }
.profile-btn:hover { color: var(--accent-dark); box-shadow: 0 0 0 2px var(--line-strong); }
.profile-btn[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--accent); }
.pill { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 99px; font-size: 11px; font-weight: 650; background: var(--amber-soft); color: var(--amber); white-space: nowrap; }

/* Surfaces */
.grid { display: grid; gap: 16px; }
/* Sibling cards one under another: the gap between them, so no two touch. */
.stack { display: grid; gap: 16px; min-width: 0; }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-split { grid-template-columns: 1.55fr .75fr; }
.card { min-width: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.card-head { min-height: 54px; display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 15px 18px; border-bottom: 1px solid var(--line); }
.card-head h2 { margin: 0; font-size: 13px; }
.card-head p { margin: 3px 0 0; color: var(--muted); font-size: 10.5px; }
/* A button in a card's head keeps its label on one line; the heading's text beside it wraps instead. */
.card-head > .btn, .card-head > .row > .btn { flex-shrink: 0; white-space: nowrap; }
.card-body { padding: 17px 18px; }
.metric-card { padding: 17px; display: flex; flex-direction: column; min-height: 118px; }
.metric-label { color: var(--muted); font-size: 11px; font-weight: 650; }
.metric-value { margin-top: 12px; font-size: 25px; font-weight: 750; letter-spacing: -.035em; line-height: 1; font-variant-numeric: tabular-nums; }
.metric-foot { margin-top: 9px; color: var(--muted); font-size: 10.5px; }
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; }
.table th { padding: 10px 18px; color: var(--muted); background: var(--surface-soft); border-bottom: 1px solid var(--line); font-size: 9.5px; font-weight: 750; letter-spacing: .08em; text-align: left; text-transform: uppercase; white-space: nowrap; }
.table td { padding: 12px 18px; border-bottom: 1px solid var(--line); font-size: 12px; vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
/* A table whose rows stack on a phone, and columns that give way first. Any page's table can use them:
   - .table-stack, on the table: at 680px or narrower its head row is hidden and each row becomes a block, its
     cells one under another.
   - data-label="…", on a cell: stacked, the cell shows that label above its value, since the head row is
     gone. Leave it off the row's first cell (its name), which then reads as the row's heading, and off the
     actions cell.
   - .table-actions, on the box that holds a row's buttons: compact buttons whose labels stay on one line,
     at the end of the row; stacked, a row of their own under the other cells, from the left, wrapping when
     they don't fit.
   - .table-stack-wide, with .table-stack: the rows stack at 1100px or narrower instead, for a table of more
     columns than a tablet's width, or a laptop's beside the sidebar, can hold without scrolling.
   - .hide-narrow, on a column's header and its cells: hidden at 760px or narrower, stacked rows included,
     for a column the row can do without there (a date, a size). */
.table-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.table-actions .btn { min-height: 30px; padding: 5px 10px; white-space: nowrap; }
/* Stacked or not: a stacked row's cells are shown as blocks, which mustn't bring a hidden column back. */
@media (max-width: 760px) { .hide-narrow, .table-stack .hide-narrow { display: none; } }
@media (max-width: 1100px) {
  .table-stack-wide thead { display: none; }
  .table-stack-wide, .table-stack-wide tbody, .table-stack-wide tr, .table-stack-wide td { display: block; width: 100%; }
  .table-stack-wide tr { padding: 12px 16px; border-bottom: 1px solid var(--line); }
  .table-stack-wide tbody tr:last-child { border-bottom: 0; }
  .table.table-stack-wide td, .table.table-stack-wide tbody tr:last-child td { padding: 3px 0; border: 0; }
  .table-stack-wide td[data-label]::before { content: attr(data-label); display: block; margin-bottom: 2px; color: var(--muted); font-size: 9.5px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
  .table-stack-wide .table-actions { justify-content: flex-start; margin-top: 6px; }
}
@media (max-width: 680px) {
  .table-stack thead { display: none; }
  .table-stack, .table-stack tbody, .table-stack tr, .table-stack td { display: block; width: 100%; }
  .table-stack tr { padding: 12px 16px; border-bottom: 1px solid var(--line); }
  .table-stack tbody tr:last-child { border-bottom: 0; }
  .table.table-stack td, .table.table-stack tbody tr:last-child td { padding: 3px 0; border: 0; }
  .table-stack td[data-label]::before { content: attr(data-label); display: block; margin-bottom: 2px; color: var(--muted); font-size: 9.5px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
  .table-stack .table-actions { justify-content: flex-start; margin-top: 6px; }
}
.badge { display: inline-flex; align-items: center; gap: 5px; min-height: 22px; padding: 2px 8px; border-radius: 99px; font-size: 10px; font-weight: 700; white-space: nowrap; color: var(--grey); background: var(--grey-soft); }
.badge::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .75; }
.badge.green { color: var(--green); background: var(--green-soft); }
.badge.amber { color: var(--amber); background: var(--amber-soft); }
.badge.red { color: var(--red); background: var(--red-soft); }
.badge.blue { color: var(--blue); background: var(--blue-soft); }
.badge.accent { color: var(--accent-dark); background: var(--accent-soft); }
.empty-state { padding: 46px 24px; text-align: center; }
.empty-icon { width: 44px; height: 44px; margin: 0 auto 13px; display: grid; place-items: center; border-radius: 13px; color: var(--accent-dark); background: var(--accent-soft); }
.empty-state h2 { margin: 0 0 5px; font-size: 14px; }
.empty-state p { max-width: 440px; margin: 0 auto 16px; color: var(--muted); font-size: 12px; }
.activity-item { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.activity-item:last-child { border-bottom: 0; }
.activity-dot { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%; color: var(--accent-dark); background: var(--accent-soft); }
.activity-copy { font-size: 11.5px; }
.activity-copy strong { display: block; font-weight: 650; }
.activity-copy span, .activity-time { color: var(--muted); font-size: 10.5px; }
.toast-stack { position: fixed; right: 20px; bottom: 20px; z-index: 150; display: grid; gap: 8px; }
.toast { padding: 11px 14px; border-radius: 11px; background: var(--side); color: #fff; font-size: 12px; box-shadow: var(--shadow-md); }
.toast-link { color: #fff; font-weight: 650; text-decoration: underline; }

/* Attaching files (files-ui.js), in the app and the Portal */
.fa { display: grid; gap: 8px; min-width: 0; }
.fa-drop { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 9px 11px; border: 1px dashed var(--line-strong); border-radius: 10px; background: var(--surface-soft); }
.fa-drop.is-over { border-color: var(--accent); background: var(--accent-soft); }
.fa-pick .icon { width: 15px; height: 15px; }
.fa-hint { color: var(--muted); font-size: 11.5px; }
.fa-list, .fa-shown-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.fa-item { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.fa-item.is-failed { border-color: var(--red); }
.fa-thumb, .fa-glyph { width: 40px; height: 40px; border-radius: 7px; object-fit: cover; background: var(--surface-soft); }
.fa-glyph { display: grid; flex: 0 0 auto; place-items: center; color: var(--accent-dark); background: var(--accent-soft); font-size: 9px; font-weight: 800; letter-spacing: .04em; }
.fa-main { display: grid; gap: 2px; min-width: 0; font-size: 12.5px; }
.fa-name { font-weight: 650; overflow-wrap: anywhere; }
.fa-sub { color: var(--muted); font-size: 11px; }
.fa-why { color: var(--red); font-size: 11px; }
.fa-progress { width: 100%; height: 6px; accent-color: var(--accent); }
.fa-remove { min-height: 30px; padding: 4px 9px; }
.fa-error { margin: 0; color: var(--red); font-size: 11.5px; }
.fa-sr { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.fa-shown-list { display: flex; flex-wrap: wrap; margin-top: 8px; }
.fa-shown { display: flex; align-items: center; gap: 8px; max-width: 100%; min-width: 0; padding: 6px 10px 6px 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.fa-shown.is-image { flex-direction: column; align-items: flex-start; padding: 6px; }
.fa-shot { display: block; border-radius: 7px; }
.fa-shot img { display: block; width: 160px; max-width: 100%; height: 110px; object-fit: cover; border-radius: 7px; background: var(--surface-soft); }
.fa-shown.is-image .fa-main { max-width: 160px; }
.fa-groups { display: grid; gap: 14px; }
.fa-group-title { margin: 0 0 8px; color: var(--muted); font-size: 10px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
@media (max-width: 560px) { .fa-shot img { width: 120px; height: 84px; } .fa-shown.is-image .fa-main { max-width: 120px; } .fa-hint { flex-basis: 100%; } }

@media (max-width: 1180px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .sidebar { transform: translateX(-100%); transition: transform .2s ease; width: 250px; }
  body.nav-open .sidebar { transform: none; }
  body.nav-open .scrim { display: block; position: fixed; inset: 0; z-index: 35; background: rgba(8, 6, 14, .55); }
  .main-shell { margin-left: 0; }
  .topbar .menu-btn { display: inline-grid; }
  .topbar { padding: 0 16px; }
  .breadcrumb li:not(:nth-last-child(-n+2)):not(:focus-within) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .breadcrumb li:nth-last-child(2):not(:first-child)::before { content: none; }
  .breadcrumb [aria-current="page"] { max-width: 28ch; }
  .page { padding: 22px 16px 48px; }
  .grid-split { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 680px) {
  .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .page-head { flex-direction: column; }
  .page-head > :not(.page-actions) { flex: 0 0 auto; }
  .page-head > .page-actions { flex-wrap: wrap; }
  /* The trial pill stays, shorter ("5 days left"); the link's label keeps the whole of it. */
  .pill { height: 26px; padding: 0 8px; font-size: 10.5px; }
  .pill-more { display: none; }
  .topbar-right { gap: 6px; }
  .breadcrumb a { max-width: 12ch; }
  .breadcrumb [aria-current="page"] { max-width: 18ch; }
}
@media (max-width: 560px) {
  /* No room for the Portal's own button: the profile menu opens the Portal too. */
  .topbar-portal { display: none; }
  .topbar { gap: 8px; }
  .topbar-left { gap: 8px; }
  .breadcrumb li:last-child:not(:first-child) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .breadcrumb a, .breadcrumb span { max-width: none; }
  .breadcrumb a { font-size: 12.5px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* Workspace switcher: a native select laid over the workspace card, so it stays accessible. */
.workspace { position: relative; cursor: pointer; }
.workspace-select { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }
.workspace:focus-within { outline: 2px solid var(--side-accent); outline-offset: 2px; }
.loading { height: 160px; border-radius: var(--radius); background: linear-gradient(90deg, var(--surface) 25%, var(--surface-soft) 50%, var(--surface) 75%); background-size: 200% 100%; animation: shimmer 1.2s infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
/* The sidebar before its first render (index.html): rows the height of .nav-item, replaced by renderNav. */
.nav-skeleton { padding-top: 16px; }
.nav-skeleton span { display: block; width: 64%; height: 12px; margin: 12px 10px; border-radius: 6px; background: linear-gradient(90deg, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .1) 50%, rgba(255, 255, 255, .05) 75%); background-size: 200% 100%; animation: shimmer 1.2s infinite; }
.nav-skeleton span:nth-child(even) { width: 48%; }
.nav-skeleton span:nth-child(3n) { width: 72%; }
@media (prefers-reduced-motion: reduce) { .loading, .nav-skeleton span { animation: none; } }

/* Forms (shared by every page). */
.form { display: grid; gap: 14px; max-width: 560px; }
/* A field's label, control and hints keep their own height: in a row of fields (two columns, a grid) the
   row grows to its tallest field, and without align-content the shorter field's rows would stretch to
   fill it, drawing its select or input taller than its neighbour's. */
.field { display: grid; gap: 6px; align-content: start; }
.field label { font-size: 12px; font-weight: 650; }
.field .hint { color: var(--muted); font-size: 11px; }
.field .error { color: var(--red); font-size: 11px; }
.input, .select, .textarea { width: 100%; min-height: 40px; padding: 9px 11px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--surface); color: var(--ink); font: 13px var(--font); }
.textarea { min-height: 96px; resize: vertical; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.notice { padding: 10px 12px; border-radius: 9px; font-size: 12px; background: var(--accent-soft); color: var(--accent-dark); }
.notice.warn { background: var(--amber-soft); color: var(--amber); }
.notice.error { background: var(--red-soft); color: var(--red); }
.btn-danger { color: var(--red); background: var(--red-soft); }
.muted { color: var(--muted); }
.mono { font-family: var(--mono); font-size: 12px; }
dialog { border: 1px solid var(--line); border-radius: 16px; padding: 0; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-md); width: min(560px, calc(100vw - 32px)); }
dialog::backdrop { background: rgba(8, 6, 14, .55); backdrop-filter: blur(3px); }
dialog .dialog-body { padding: 20px; display: grid; gap: 14px; max-height: min(72vh, 760px); overflow-y: auto; }
dialog .dialog-foot { padding: 12px 20px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: 8px; }
/* A dialog's heading (.dialog-head, before its body) stays put while the body scrolls, as the buttons in its
   foot do. The head takes the body's top padding and the body keeps 4px, room for a focused field's ring,
   so a dialog looks as it did before when nothing scrolls; once the body is scrolled (data-scrolled, set by
   watchDialogScroll in ui.js) a hairline under the head marks where the fields go under it. */
dialog .dialog-head { padding: 20px 20px 9px; }
dialog .dialog-head + .dialog-body { padding-top: 4px; border-top: 1px solid transparent; }
dialog .dialog-head + .dialog-body[data-scrolled] { border-top-color: var(--line); }
/* The dialog is a column, whether its head, body and foot are its own children or a form's around them: the
   head and foot keep their height and the body shrinks to what's left when the window is too short for all
   three, so the dialog itself never scrolls and takes the head away. */
dialog[open]:has(.dialog-body) { display: flex; flex-direction: column; }
dialog[open] > :not(.dialog-head, .dialog-body, .dialog-foot):has(> .dialog-body) { display: flex; flex-direction: column; min-height: 0; }
dialog .dialog-head, dialog .dialog-foot { flex: none; }
/* The body is also where the enhanced controls' hidden natives (controls.css, position: absolute) belong:
   otherwise their box is the dialog's, and one far down a long body makes the dialog itself scroll. */
dialog .dialog-body { min-height: 0; position: relative; }
/* The dialogs' own parts (dialogs.js). The ag- names are the ones the pages wrote before the dialogs moved
   out of the agents page; they look the same. */
dialog.wide { width: min(760px, calc(100vw - 32px)); }
.dialog-title, .ag-dialog-title { margin: 0; font-size: 16px; }
.dialog-help, .ag-help { margin: 0; color: var(--muted); font-size: 11.5px; }

.field .hint, .field .error { margin: 0; }

/* Tabs (ui.js tabs(): a tablist whose panels switch in place) and the bars of links that change page the
   same way (Tasks' Board, List and Recurring): one underline bar, which scrolls sideways when it doesn't fit
   (bindTabs keeps the selected tab in view), and on a phone wraps onto more lines instead, so every tab shows. */
.tabs { display: flex; gap: 4px; margin: 0 0 18px; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; box-shadow: inset 0 -1px 0 var(--line); }
.tabs > a, .tabs > [role="tab"] { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 9px 12px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); font: 650 12.5px var(--font); text-decoration: none; white-space: nowrap; cursor: pointer; }
.tabs > a:hover, .tabs > [role="tab"]:hover { color: var(--ink); }
.tabs > [aria-current="page"], .tabs > [aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.tabs > :focus-visible { outline-offset: -3px; }
.tab-count { min-width: 20px; padding: 1px 7px; border-radius: 99px; background: var(--grey-soft); color: var(--grey); font-size: 10.5px; text-align: center; }
.tabs > [aria-current="page"] .tab-count, .tabs > [aria-selected="true"] .tab-count { background: var(--accent-soft); color: var(--accent-dark); }
.tab-panel[hidden] { display: none; }
/* A tab's panel takes the focus (Tab from the tab bar) to say where its content starts; no ring around all of it. */
.tab-panel:focus { outline: none; }
.tab-panel:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
@media (max-width: 680px) {
  .tabs { flex-wrap: wrap; overflow-x: visible; row-gap: 0; }
  .tabs > a, .tabs > [role="tab"] { padding: 9px 10px; }
}
/* A few choices of one thing shown (a period, a view), and the theme in the profile menu: pills in a frame. */
.segmented { display: inline-flex; flex-wrap: wrap; gap: 3px; padding: 3px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.segmented > a, .segmented > button { display: inline-flex; align-items: center; justify-content: center; min-height: 30px; padding: 4px 12px; border: 0; border-radius: 7px; background: transparent; color: var(--muted); font: 650 12px var(--font); text-decoration: none; cursor: pointer; }
.segmented > a:hover, .segmented > button:hover { color: var(--ink); }
.segmented > [aria-current="page"], .segmented > [aria-current="true"], .segmented > [aria-pressed="true"] { color: var(--accent-dark); background: var(--accent-soft); }

/* Wizards (wizard.js): the numbered steps, one step's panel at a time, and Back / Next below. A step that's
   done shows a check in an accent ring (not only a fill, which is faint in dark mode), the one on screen a
   filled circle, the ones to come their number in a grey ring. On a phone the list is read, not shown: one
   line says "Step 2 of 5: Team" instead. Only the wizard's own list ([data-steps]): the marketing site loads
   this stylesheet too, and its "how it works" .steps are another list, which must stay seen on a phone. */
.steps[data-steps] { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0; padding: 0; list-style: none; color: var(--muted); font-size: 12px; }
.steps[data-steps] li { display: inline-flex; align-items: center; gap: 7px; }
.step-n { width: 22px; height: 22px; display: inline-grid; place-items: center; flex: 0 0 auto; border: 1px solid var(--line-strong); border-radius: 50%; font-size: 11px; font-weight: 700; }
.step-check { display: none; width: 12px; height: 12px; stroke-width: 2.6; }
.steps[data-steps] li[aria-current="step"] { color: var(--ink); font-weight: 650; }
.steps[data-steps] li[aria-current="step"] .step-n { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.steps[data-steps] li[data-done] { color: var(--ink); }
.steps[data-steps] li[data-done] .step-n { border: 2px solid var(--accent); background: var(--accent-soft); color: var(--accent-dark); }
.steps[data-steps] li[data-done] .step-num { display: none; }
.steps[data-steps] li[data-done] .step-check { display: block; }
.steps[data-steps] li:not([data-done]) .step-done { display: none; }
.steps-now { display: none; margin: 0; color: var(--muted); font-size: 12px; }
.steps-now strong { color: var(--ink); font-weight: 650; }
@media (max-width: 560px) {
  .steps[data-steps] { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .steps-now { display: block; }
}
.wizard { display: grid; gap: 16px; min-width: 0; }
.wizard-panel { display: grid; gap: 14px; min-width: 0; }
.wizard-panel[hidden] { display: none; }
.wizard-title { margin: 0; font-size: 15px; }
.wizard-title:focus { outline: none; }
.wizard-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; padding-top: 14px; border-top: 1px solid var(--line); }

/* Popups anchored to a top-bar button (popup.js): the notification bell's, the Portal's updates and the
   profile menu. Placed by popup.js; above the help panel (45). */
.popup { position: fixed; z-index: 60; overflow-y: auto; background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-md); }
/* The profile menu (profile-menu.js). */
.pm { width: min(300px, calc(100vw - 24px)); padding: 6px; }
.pm-who { display: flex; align-items: center; gap: 10px; min-width: 0; margin-bottom: 6px; padding: 8px 10px 12px; border-bottom: 1px solid var(--line); }
.pm-avatar { width: 36px; height: 36px; flex: 0 0 auto; display: grid; place-items: center; border-radius: 50%; background: var(--accent-soft); color: var(--accent-dark); font-size: 12px; font-weight: 750; }
.pm-who div { display: grid; gap: 1px; min-width: 0; }
.pm-who strong { font-size: 13px; overflow-wrap: anywhere; }
.pm-who span { color: var(--muted); font-size: 11.5px; overflow-wrap: anywhere; }
.pm-list { margin: 0; padding: 0; list-style: none; }
.pm-item { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 38px; padding: 8px 10px; border: 0; border-radius: 8px; background: none; color: var(--ink); font: 600 12.5px var(--font); text-align: left; text-decoration: none; cursor: pointer; }
.pm-item:hover { background: var(--surface-soft); }
.pm-item .icon { color: var(--muted); }
.pm-theme { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin: 6px 0; padding: 10px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.pm-label { color: var(--muted); font-size: 12px; font-weight: 650; }
.pm form { margin: 0; }
@media (max-width: 560px), (pointer: coarse) {
  .pm-item { min-height: 44px; }
  .pm .segmented > button { min-height: 40px; }
}
/* A chart's words (charts.js axisFrame): HTML around its SVG, at their own size whatever width the SVG is drawn
   at. The y axis's labels sit in a gutter as wide as the longest (the hidden copy sets it), each centred on its
   line; the x axis's sit under the plot, at a start, a middle or an end. Six dates (2026-10-12) need about
   560px side by side, so on a narrower plot (a half-width card, a phone) only the first, middle and last show. */
.ch-frame { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 6px; }
.ch-y { position: relative; }
.ch-tick { position: absolute; color: var(--muted); font-size: 10.5px; line-height: 1.2; white-space: nowrap; font-variant-numeric: tabular-nums; pointer-events: none; }
.ch-y .ch-tick { right: 0; transform: translateY(-50%); }
.ch-y-size { display: block; height: 0; overflow: hidden; visibility: hidden; font-size: 10.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ch-area { position: relative; min-width: 0; }
.ch-x { grid-column: 2; position: relative; height: 20px; container-type: inline-size; }
.ch-x .ch-tick { top: 5px; transform: translateX(-50%); }
.ch-x .ch-tick.is-start { transform: none; }
.ch-x .ch-tick.is-end { transform: translateX(-100%); }
@container (max-width: 560px) { .ch-x .ch-tick.is-minor { display: none; } }
