html, body { height: auto; overflow: visible; }

/* ---------- sidebar ---------- */
.app-sidebar {
  --side-text: var(--side-text-override, var(--text));
  --side-text-2: var(--side-text-2-override, var(--text-3));
  --side-text-3: var(--side-text-3-override, var(--text-6));
  --side-line: var(--side-line-override, var(--line));
  --side-hover: var(--side-hover-override, var(--bg-hover));

  position: fixed; top: 0; left: 0; bottom: 0; width: var(--sidebar-w); z-index: 200;
  background: var(--side-bg, var(--bg-deep)); border-right: 1px solid var(--side-line);
  display: flex; flex-direction: column;
  transition: width 0.18s ease, transform 0.18s ease, background-color 0.2s ease, border-color 0.2s ease;
}
.app-sidebar.collapsed { width: var(--sidebar-w-collapsed); }
.app-sidebar.collapsed .side-link-text,
.app-sidebar.collapsed .side-link-badge,
.app-sidebar.collapsed .side-group-label,
.app-sidebar.collapsed .side-brand-link span,
.app-sidebar.collapsed .side-foot .side-link-text { display: none; }
.app-sidebar.collapsed .side-collapse-btn i { transform: rotate(180deg); }
.app-sidebar.collapsed .side-link { justify-content: center; }

.side-brand { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 16px; border-bottom: 1px solid var(--side-line); flex-shrink: 0; height: var(--topbar-h); box-sizing: border-box; }
.side-brand-link { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 700; color: var(--side-text); text-decoration: none; }
.side-brand-link i { color: var(--accent); font-size: 16px; }
/* Brand lockup: the mark stays put when the sidebar collapses, the wordmark
   is inside the same <span> the collapse rule already hides. The mark is set
   taller than the wordmark because that is the proportion the artwork itself
   uses (LOGO+TEXT.svg gives the mark ~1.2x the height of the two-line text
   block); matching their box heights instead makes the mark look shrunken.
   The brand row's padding is trimmed from 14px to fit the taller mark inside
   the fixed --topbar-h.
   --logo-ink is re-mixed here because variables.css derives it from --text-4,
   which describes the page, not the sidebar — the Legacy LD preset
   (themePresets.js) pairs a light page with a navy sidebar, and the page's
   ink would sink into it. */
/* Pages that still pull in the legacy stylesheet stack ({{ block.super }} in
   base_app's stylesheets block — Universal Search, for one) get
   `#screen, a, img { height: 100%; width: inherit }` from
   main_static/css/index.css. Every other new_ui anchor shrugs that off, since
   a percentage height against an auto-height containing block computes to
   auto — but .side-brand has an explicit height, so there the brand link
   resolved to the full row and centred the logo in a box taller than the
   artwork. That is why the brand looked clipped on Universal Search and fine
   on Query Console. */
.side-brand-link { height: auto; width: auto; }
.side-brand-link .ld-logo { --logo-ink: color-mix(in oklab, var(--accent) 35%, var(--side-text-2)); }
.side-brand-link .ld-logo-mark { height: 30px; }
.side-brand-link .ld-logo-wordmark { height: 25px; }
.side-collapse-btn { width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--side-line); background: none; color: var(--side-text-3); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.side-collapse-btn i { transition: transform 0.2s ease; font-size: 11px; }
/* Collapsed, the header has about 36px of room: the logo mark and a 24px button
   side by side spill past the sidebar's border and the button ends up half on the
   sidebar, half on the top bar. Instead the logo is centred and the button is a
   deliberate handle on the border: solid accent, centred on the edge. */
.app-sidebar.collapsed .side-brand { position: relative; justify-content: center; padding-left: 0; padding-right: 0; }
.app-sidebar.collapsed .side-collapse-btn {
  position: absolute; top: 50%; right: -12px; transform: translateY(-50%); z-index: 2;
  margin: 0; /* a legacy global button rule adds margin: 0 5px 5px 0 */
  width: 24px; height: 24px; border-radius: 6px;
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
  box-shadow: 0 1px 6px oklch(0% 0 0 / 0.4);
}
.app-sidebar.collapsed .side-collapse-btn:hover { filter: brightness(1.1); }

.side-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px 10px 16px; }
.side-group { margin-bottom: 4px; }
/* Section headings take the accent, so the sidebar's structure reads at a
   glance instead of dissolving into the link text below it. */
.side-group-label { font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; color: var(--accent-tint); text-transform: uppercase; margin: 14px 10px 6px; }
.side-group:first-child .side-group-label { margin-top: 2px; }

/* Collapsible group (Admin): the label is a button that toggles its item list.
   Default is open; the chevron rotates and the items hide when collapsed. */
.side-group-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: calc(100% - 20px); background: none; border: none; appearance: none;
  cursor: pointer; text-align: left;
  /* not `font: inherit`: that reset the label's 9.5px size, which is why Admin
     rendered larger than the other section titles */
  font-family: inherit;
}
.side-group-toggle:hover { color: var(--accent); }
.side-group-caret { font-size: 9px; transition: transform 0.15s ease; opacity: 0.75; }
.side-group-collapsible[aria-collapsed="true"] .side-group-caret { transform: rotate(-90deg); }
.side-group-items { overflow: hidden; }
.side-group-collapsible[aria-collapsed="true"] .side-group-items { display: none; }
/* When the whole sidebar is collapsed to icons the caret is meaningless. */
.app-sidebar.collapsed .side-group-caret { display: none; }
/* background/border/box-shadow/width/text-align/appearance below are all
   no-ops for the <a> markup this was originally designed for (anchors have
   none of those by default) but are required when a sidebar item is a
   <button> instead (search-console.html's JS-action items, e.g. Canvas/
   Search History) -- browsers apply real default chrome to <button>
   otherwise, which nothing else here resets. */
.side-link { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: 7px; font-size: 12.5px; font-weight: 500; color: var(--side-text-2); text-decoration: none; white-space: nowrap; background: none; border: none; box-shadow: none; width: 100%; text-align: left; cursor: pointer; appearance: none; }
.side-link:hover { background: var(--side-hover); color: var(--side-text); }
.side-link.active { background: var(--accent-16); color: var(--accent-tint); font-weight: 600; }
.side-link-icon { width: 16px; text-align: center; flex-shrink: 0; color: inherit; opacity: 0.85; }
.side-link.active .side-link-icon { opacity: 1; color: var(--accent); }
.side-link-text { overflow: hidden; text-overflow: ellipsis; }
.side-link-badge { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 9.5px; background: var(--accent-18); color: var(--accent-tint); padding: 1px 6px; border-radius: 999px; flex-shrink: 0; }

.side-foot { border-top: 1px solid var(--side-line); padding: 10px; flex-shrink: 0; }
.side-foot .side-link { color: var(--side-text-3); font-size: 11px; }

.sidebar-backdrop { position: fixed; inset: 0; background: oklch(0% 0 0 / 0.5); z-index: 190; opacity: 0; pointer-events: none; transition: opacity 0.18s ease; }
.sidebar-backdrop.show { opacity: 1; pointer-events: auto; }

/* ---------- shell main / topbar ---------- */
/* min-height is divided by --ld-zoom because the text-size setting scales the
   whole page with `zoom` on <html> (see setTextSize in theme.js). vh resolves
   against the unscaled viewport, so a plain 100vh renders 100vh * zoom tall --
   at the 120% setting that is a fifth of a screen of dead space below the
   fold, which is what kept pushing .pub-footer out of view on short pages.
   Same trick invoice-admin.css already uses for widths. */
.shell-main { margin-left: var(--sidebar-w); min-height: calc(100vh / var(--ld-zoom, 1)); display: flex; flex-direction: column; transition: margin-left 0.18s ease; }
body.sidebar-collapsed .shell-main { margin-left: var(--sidebar-w-collapsed); }

.app-topbar { position: sticky; top: 0; z-index: 150; height: var(--topbar-h); display: flex; align-items: center; gap: 14px; padding: 0 18px; background: var(--bg-toolbar); border-bottom: 1px solid var(--line); }
.topbar-menu-btn { display: none; width: 30px; height: 30px; border-radius: 7px; border: 1px solid var(--line-input); background: none; color: var(--text-3); align-items: center; justify-content: center; flex-shrink: 0; }
.topbar-crumbs { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-5); flex-shrink: 0; min-width: 0; }
.crumb-link { color: var(--text-4); text-decoration: none; }
.crumb-link:hover { color: var(--accent); }
.crumb-current { color: var(--text-2); font-weight: 600; }
.crumb-sep { color: var(--text-6); font-size: 10px; }
.crumb-text { color: var(--text-5); }

.topbar-search { display: flex; align-items: center; gap: 8px; background: var(--bg-sunken); border: 1px solid var(--line-input); border-radius: 7px; padding: 7px 10px; color: var(--text-5); font-size: 12px; max-width: 260px; flex: 1; margin-left: 12px; cursor: pointer; }
.topbar-search input { border: none; background: none; outline: none; color: var(--text-3); font-size: 12px; flex: 1; font-family: inherit; cursor: pointer; }
.topbar-search input::placeholder { color: var(--text-6); }
.topbar-search kbd { background: var(--bg-hover); border: 1px solid var(--line-input); border-radius: 4px; padding: 1px 5px; font-size: 10px; color: var(--text-5); }

.topbar-right { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-shrink: 0; }
/* A legacy global rule gives every <button> margin-bottom: 5px. The credits pill is a div, so it alone sat centred and the buttons rode ~2.5px high. */
.topbar-right > * { margin-top: 0; margin-bottom: 0; }
.topbar-iconbtn { position: relative; width: 32px; height: 32px; border-radius: 7px; border: 1px solid var(--line-input); background: none; color: var(--text-3); display: flex; align-items: center; justify-content: center; }
.topbar-iconbtn:hover { color: var(--text); border-color: var(--accent-60); }
.settings-btn i { transition: transform 0.35s ease; }
.settings-btn:hover i { transform: rotate(70deg); }
.topbar-dot { position: absolute; top: 6px; right: 7px; width: 6px; height: 6px; border-radius: 50%; background: var(--danger); border: 1.5px solid var(--bg-toolbar); }
.topbar-user { display: flex; align-items: center; gap: 8px; padding: 4px 8px 4px 4px; border-radius: 20px; border: 1px solid var(--line-input); background: none; margin-left: 4px; }
.topbar-user-name { font-size: 11.5px; color: var(--text-3); font-weight: 600; padding-left: 10px; }
.topbar-user-chev { font-size: 9px; color: var(--text-5); }

/* ---------- dropdown menu panels (positioned via JS) ---------- */
.menu-panel { position: fixed; width: 300px; max-height: 70vh; overflow-y: auto; background: var(--panel-bg-2); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-menu); z-index: 10070; padding: 6px; opacity: 0; transform: translateY(-6px); transition: opacity 0.14s ease, transform 0.14s ease, background-color 0.2s ease, border-color 0.2s ease; }
.menu-panel.open { opacity: 1; transform: translateY(0); }
.menu-panel-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px 6px; font-size: 11px; font-weight: 700; color: var(--text-4); text-transform: uppercase; letter-spacing: 0.04em; }
.menu-item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 7px; font-size: 12.5px; color: var(--text-2); text-decoration: none; background: none; border: none; width: 100%; text-align: left; }
.menu-item:hover { background: var(--bg-hover); }
.menu-item i { width: 15px; text-align: center; color: var(--text-5); flex-shrink: 0; }
.menu-sep { height: 1px; background: var(--line-soft); margin: 6px 4px; }
.menu-notif { display: flex; gap: 10px; padding: 9px 10px; border-radius: 7px; }
.menu-notif:hover { background: var(--bg-hover); }
.menu-notif-icon { width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 13px; }
.menu-notif-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.menu-notif-title { font-size: 12px; color: var(--text-2); }
.menu-notif-time { font-size: 10.5px; color: var(--text-6); }
.menu-notif-msg { font-size: 11.5px; color: var(--text-4); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* Two tabs at the head of the notifications panel: Activity and Announcements. */
.notif-tabs { display: flex; gap: 2px; padding: 6px 6px 0; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.notif-tab { flex: 1 1 0; min-width: 0; padding: 8px 6px 9px; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600; color: var(--text-5); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; transition: color .12s; }
.notif-tab:hover { color: var(--text-2); }
.notif-tab.is-on { color: var(--accent); border-bottom-color: var(--accent); }
.notif-tabdot { min-width: 16px; height: 16px; padding: 0 5px; border-radius: 999px; background: var(--accent); color: var(--on-accent); font-size: 10px; font-weight: 700; line-height: 16px; text-align: center; }
.notif-tab:not(.is-on) .notif-tabdot { background: var(--text-5); }
.menu-notif-list { max-height: 380px; overflow-y: auto; }
.menu-notif.is-clickable { cursor: pointer; }
/* Unread marker: a rail rather than a background, so it survives the hover fill. */
.menu-notif.is-unread { position: relative; }
.menu-notif.is-unread::before { content: ''; position: absolute; left: 0; top: 10px; bottom: 10px; width: 2px; border-radius: 2px; background: var(--accent); }
.menu-panel-foot { display: flex; gap: 14px; }
/* Count on the bell itself. */
#notif-btn, #jobs-btn { position: relative; }
.topbar-iconbtn[hidden] { display: none; }
.notif-dot { position: absolute; top: 2px; right: 2px; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px; background: var(--accent); color: var(--on-accent); font-size: 9.5px; font-weight: 700; line-height: 15px; text-align: center; pointer-events: none; }
.menu-panel-foot { text-align: center; padding: 8px; }
.menu-panel-foot a { font-size: 11.5px; color: var(--accent); text-decoration: none; font-weight: 600; }

/* ---------- page wrapper ---------- */
/* .page-wrapper carries flex:1 to push the footer down, but #page-root sits
   between it and .shell-main, so that grow had nothing to act on and the
   footer rode up under the content on any page shorter than the viewport.
   Making #page-root a flex column that grows hands the intent through. */
#page-root { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.page-wrapper { flex: 1; width: 100%; max-width: 1400px; margin: 0 auto; padding: 20px 24px 40px; display: flex; flex-direction: column; gap: 18px; box-sizing: border-box; }
.page-header-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.page-pretitle { font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-5); }
.page-title { font-size: 19px; font-weight: 700; margin: 2px 0 0; color: var(--text); }
.page-sub { font-size: 12px; color: var(--text-5); margin: 4px 0 0; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- responsive ---------- */
@media (max-width: 980px) {
  .app-sidebar { transform: translateX(-100%); }
  .app-sidebar.mobile-open { transform: translateX(0); width: var(--sidebar-w); }
  .shell-main, body.sidebar-collapsed .shell-main { margin-left: 0; }
  .topbar-menu-btn { display: flex; }
  .topbar-search { display: none; }
  .side-collapse-btn { display: none; }
}

/* Phones: the right-hand cluster (session, demo, bell, settings, account) plus a
   long username is wider than the screen. The account button becomes an icon,
   the crumb is allowed to shrink, and the bar gets tighter spacing. */
@media (max-width: 1250px) {
  .topbar-crumbs { flex-shrink: 1; overflow: hidden; }
  .crumb-current { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar-search { flex: 0 1 240px; min-width: 0; }
  .topbar-search input { min-width: 0; width: 100%; }
  .topbar-search kbd { display: none; }
  .topbar-user { width: 32px; height: 32px; padding: 0; margin-left: 0; justify-content: center; }
  .topbar-user-name, .topbar-user .topbar-user-chev { display: none; }
  .topbar-user::before { font-family: 'Font Awesome 6 Free'; font-weight: 900; content: '\f007'; font-size: 12px; color: var(--text-3); }
}
@media (max-width: 700px) {
  .app-topbar { gap: 8px; padding: 0 10px; }
  .topbar-right { gap: 4px; }
}
@media (max-width: 520px) {
  .topbar-crumbs .crumb-link, .topbar-crumbs .crumb-sep { display: none; }
}

.side-legal {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; padding: 6px 12px 0;
  font-size: 10.5px; color: var(--side-text-3);
}
.side-foot { display: flex; flex-direction: column; flex-shrink: 0; }
/* The public sidebar's foot and the page footer (.pub-footer in public.css) sit
   side by side along the bottom edge, so they share one height. --foot-h is the
   whole box including the 1px top border on each. */
:root { --foot-h: 52px; }
.side-foot-public { box-sizing: border-box; min-height: var(--foot-h); justify-content: center; padding: 0 10px; }
.side-foot-public .side-legal { padding: 0 12px; }
.side-legal a { color: var(--side-text-3); text-decoration: none; }
.side-legal a:hover { color: var(--accent); text-decoration: underline; }
.side-legal-btn { background: none; border: 0; padding: 0; font: inherit; font-size: 10.5px; color: var(--side-text-3); cursor: pointer; }
.side-legal-btn:hover { color: var(--accent); text-decoration: underline; }
.side-legal-btn[aria-pressed="false"] { color: var(--side-text-3); opacity: .8; }
.app-sidebar.collapsed .side-legal { display: none; }

/* Label shown beside a sidebar icon while the sidebar is collapsed (shell.js,
   initSidebarTips). Fixed to <body>, so it clears the sidebar's own overflow. */
.side-tip {
  position: fixed; z-index: 500; transform: translateY(-50%);
  display: flex; align-items: center; gap: 8px; white-space: nowrap; pointer-events: none;
  padding: 6px 10px; border-radius: 7px; font-size: 12px; font-weight: 600;
  color: var(--text); background: var(--panel-bg); border: 1px solid var(--line-input);
  box-shadow: var(--shadow-card);
  opacity: 0; visibility: hidden; transition: opacity 0.12s ease, visibility 0.12s;
}
.side-tip.show { opacity: 1; visibility: visible; }

.side-tip-badge {
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; font-weight: 400;
  background: var(--accent-18); color: var(--accent-tint); padding: 1px 6px; border-radius: 999px;
}

/* ---------- credits meter ---------- */
.topbar-credits { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; color: var(--text-3); cursor: default; }
.topbar-credits[hidden] { display: none; }
.topbar-credits { margin-right: 6px; }
.topbar-credits-icon { font-size: 12px; color: var(--text-5); }
.topbar-credits-text { display: flex; flex-direction: column; line-height: 1.05; }
.topbar-credits-label { font-size: 8.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-5); }
.topbar-credits-num { font-size: 12px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.topbar-credits-bar { width: 44px; flex-shrink: 0; }
.topbar-credits-bar[hidden] { display: none; }
.topbar-credits.is-low { border-color: var(--warn); }
.topbar-credits.is-low .bar { background: var(--warn); }
.topbar-credits.is-low .topbar-credits-icon { color: var(--warn); }
.topbar-credits.is-empty { border-color: var(--danger); }
.topbar-credits.is-empty .bar { background: var(--danger); }
.topbar-credits.is-empty .topbar-credits-icon { color: var(--danger); }
@media (max-width: 1250px) {
  .topbar-credits-bar { display: none; }
}
@media (max-width: 760px) {
  .topbar-credits { padding: 0 9px; }
  .topbar-credits-label { display: none; }
}
