/* =========================================================
   PROCWIRE DASHBOARD — styles
   Phase 2 (Dashboard Shell).

   Token architecture matches site/styles.css exactly: this file
   RE-DECLARES the same :root custom-property set (see
   shared/design-tokens.md — read-only reference this was copied
   from) rather than inventing new names or values, because the
   dashboard is a separate deployable project and can't @import
   site/styles.css across Cloudflare Pages projects. Component rules
   below the tokens are dashboard-specific (sidebar, topbar, widget
   grid, data tables, skeleton loaders) plus the .btn family and a
   couple of small chrome utilities (tooltips, account popup) that
   are direct ports of the equivalent site/styles.css rules so the
   two products share the exact same feel.
   ========================================================= */
:root{
  /* ---- Colors: surfaces ---- */
  --bg: #fafafa;
  --paper: #ffffff;
  --grey-25: #f7f7f7;
  --grey-50: #f2f2f2;
  --grey-100: #e8e8e8;
  --grey-200: #dcdcdc;
  --grey-400: #b8b8b8;

  /* ---- Colors: text ---- */
  --text-primary: #4d4d4d;
  --text-secondary: #8f8f8f;
  --text-disabled: #c7c7c7;

  /* ---- Colors: brand ---- */
  --primary: #bd32af;
  --primary-light: #cf5cc4;
  --primary-dark: #9b2a90;
  --primary-tint: #fbebf9;

  --accent-blue: #00c0eb;
  --accent-green: #67bb3a;
  --accent-gold: #f8a32a;

  /* ---- Colors: state ---- */
  --success: #67bb3a;
  --success-tint: #eaf8ec;
  --warning: #f8a32a;
  --warning-tint: #fdf5e6;
  --error: #e35d6a;
  --error-tint: #fdecee;

  /* ---- Radius scale ---- */
  --radius-4xl: 32px;
  --radius-3xl: 28px;
  --radius-2xl: 22px;
  --radius-xl: 18px;
  --radius-lg: 14px;
  --radius-md: 10px;

  /* ---- Shadow scale ---- */
  --shadow-xs: 0px 3px 8px #0000000a;
  --shadow-sm: 0px 3px 12px #0000000a;
  --shadow-md: 0px 3px 16px #0000000a;
  --shadow-darker: 0px 3px 8px #0000000f;

  --grad-brand: var(--primary);

  /* ---- Fonts ---- */
  --font-heading: "Urbanist", "Mulish", ui-sans-serif, sans-serif;
  --font-body: "Mulish", ui-sans-serif, sans-serif;
  --font-code: "Fira Code", "JetBrains Mono", monospace;

  /* ---- Layout ---- */
  --rail-w: 76px;
  --header-h: 64px;
  --sidebar-w: 240px; /* dashboard-only: labeled sidebar width, see design-tokens.md */

  /* ---- Motion ---- */
  --trans-1: .15s ease;
  --trans-2: .2s ease;
  --trans-3: .25s ease;
}

/* ---------------- Dark mode palette (same values as site/styles.css) ---------------- */
html.dark{
  color-scheme: dark;
  --bg: hsl(226, 4%, 13%);
  --paper: hsl(226, 4%, 15%);
  --grey-25: hsl(226, 4%, 17%);
  --grey-50: hsl(226, 4%, 19%);
  --grey-100: hsl(226, 4%, 22%);
  --grey-200: hsl(226, 4%, 26%);
  --grey-400: hsl(226, 4%, 34%);

  --text-primary: hsl(0, 0%, 90%);
  --text-secondary: hsl(0, 0%, 60%);
  --text-disabled: hsl(0, 0%, 40%);

  --primary-tint: rgba(189, 50, 175, 0.12);
  --error-tint: rgba(227, 93, 106, 0.12);
  --success-tint: rgba(103, 187, 58, 0.12);
  --warning-tint: rgba(248, 163, 42, 0.12);

  --shadow-xs: 0px 3px 8px #0003;
  --shadow-sm: 0px 3px 12px #0003;
  --shadow-md: 0px 3px 16px #0003;
  --shadow-darker: 0px 3px 8px #0003;
}

*{box-sizing:border-box;}
html,body{margin:0; padding:0;}
body{
  background:var(--bg); color:var(--text-primary);
  font-family:var(--font-body); font-size:15px; -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{font-family:var(--font-heading); margin:0;}
a{color:inherit; text-decoration:none;}
button{font-family:inherit; background:none; border:none; cursor:pointer; color:inherit;}
img{max-width:100%; display:block;}

/* Auth-guard flash prevention — the class auth-guard.html adds to
   <html> while it resolves the session/permission check (see the
   comment in dashboard/partials/auth-guard.html; this rule was
   explicitly deferred to Phase 2). */
html.auth-guard-pending body{visibility:hidden;}

/* ---------------- Scrollbar (ported from site/styles.css) ---------------- */
*{scrollbar-width:thin; scrollbar-color:var(--grey-200) transparent;}
::-webkit-scrollbar{width:10px; height:10px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:var(--grey-200); border-radius:999px; border:2px solid transparent; background-clip:padding-box;}
::-webkit-scrollbar-thumb:hover{background:var(--primary); background-clip:padding-box;}
::-webkit-scrollbar-corner{background:transparent;}
/* Without this, some Chromium builds still draw the native up/down
   arrow buttons at the ends of the track alongside our custom thumb
   (visible as a mismatched "only the down arrow shows" glitch since
   the top one gets clipped by a rounded, overflow:hidden parent like
   .dash-sidebar). Zeroing them out fully hands the scrollbar over to
   the custom thumb/track styling above. */
::-webkit-scrollbar-button{display:none; width:0; height:0;}

/* ---------------- Shared tooltip (ported from site/styles.css) ---------------- */
[data-tooltip]{position:relative;}
[data-tooltip]::after{
  content:attr(data-tooltip); position:absolute; background:var(--paper); color:var(--text-primary);
  font-size:12px; font-weight:600; font-family:var(--font-body); padding:6px 12px; border-radius:50px;
  white-space:nowrap; opacity:0; visibility:hidden; pointer-events:none; box-shadow:var(--shadow-sm);
  border:1px solid var(--grey-100);
  transition:opacity 0s 0s, visibility 0s 0s; z-index:90;
}
[data-tooltip]:hover::after{opacity:1; visibility:visible; transition:opacity .25s ease .15s, visibility 0s ease 0s;}
.dash-topbar [data-tooltip]::after{top:calc(100% + 10px); left:50%; transform:translateX(-50%);}
/* Sidebar items never use the ::after popup above: .dash-sidebar-scroll
   clips with overflow-x:hidden (see the comment on it, and on
   .dash-sidebar-collapse-btn below) so a popup positioned to poke out
   past an icon's right edge would always render fully invisible there,
   clipped before it ever reaches the sidebar's edge. Suppressed here;
   shell.js's initSidebarTooltip() floats a real tooltip element on
   <body> instead, which isn't inside that clipped container. */
.dash-sidebar [data-tooltip]::after{content:none;}
@media (max-width:760px){ [data-tooltip]::after{display:none;} }
/* Floating sidebar tooltip — see initSidebarTooltip() in shell.js.
   Positioned with fixed coordinates computed from the hovered item's
   own bounding box, which escapes .dash-sidebar-scroll's clipping. */
.dash-sidebar-tooltip{
  position:fixed; background:var(--paper); color:var(--text-primary);
  font-size:12px; font-weight:600; font-family:var(--font-body); padding:6px 12px; border-radius:50px;
  white-space:nowrap; opacity:0; visibility:hidden; pointer-events:none; box-shadow:var(--shadow-sm);
  border:1px solid var(--grey-100); z-index:90;
  transition:opacity 0s 0s, visibility 0s 0s;
}
.dash-sidebar-tooltip.visible{opacity:1; visibility:visible; transition:opacity .25s ease .15s, visibility 0s ease 0s;}
@media (max-width:760px){ .dash-sidebar-tooltip{display:none;} }

/* ---------------- Buttons (same recipe as site .btn family) ---------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 24px; border-radius:999px; font-weight:800; font-size:14px;
  transition:transform .15s ease, box-shadow .15s ease, opacity .15s ease;
}
.btn-primary{background:var(--grad-brand); color:#fff;}
.btn-primary:hover{transform:translateY(-2px); box-shadow:0 14px 26px -10px rgba(176,51,159,0.45);}
.btn-pastel{background:var(--primary-tint); color:var(--primary);}
.btn-pastel:hover{background:#f5ddf2;}
html.dark .btn-pastel:hover{background:rgba(189,50,175,0.2);}
.btn-outline{border:1.5px solid var(--grey-200); color:var(--text-primary);}
.btn-outline:hover{border-color:var(--primary); color:var(--primary);}
.btn-danger{background:var(--error-tint); color:var(--error);}
.btn-danger:hover{background:#fbd9dc;}
.btn[disabled], .btn:disabled{opacity:.5; cursor:not-allowed; transform:none;}
.btn-sm{padding:8px 16px; font-size:13px;}

/* ---------------- Shell layout ----------------
   Collapse state is toggled as a class on <body> (not a wrapper div)
   so every page just needs <body> — no extra shell element to include
   in all 20 page templates. See shell.js. */
.dash-sidebar{
  position:fixed; top:12px; left:12px; bottom:12px; width:var(--sidebar-w); z-index:30;
  background:var(--paper); border-radius:28px; box-shadow:var(--shadow-darker);
  display:flex; flex-direction:column; overflow:hidden;
  transition:width var(--trans-3), box-shadow var(--trans-3);
}
/* Scrolling happens in here, not on .dash-sidebar — the outer element
   clips with overflow:hidden so the scrollbar is masked to the 28px
   rounded corners instead of drawing a straight bar past them.
   min-height:0 lets it actually shrink/scroll inside the flex column
   instead of forcing the sidebar to grow with its content. */
.dash-sidebar-scroll{
  flex:1; min-width:0; min-height:0; display:flex; flex-direction:column;
  padding:18px 12px 16px; overflow-y:auto; overflow-x:hidden;
  transition:padding var(--trans-3);
}
/* Slimmer than the site-wide 10px scrollbar (above) — the sidebar is
   narrow, especially in the collapsed/icon-only rail, so the default
   thickness crowds the icons. */
.dash-sidebar-scroll::-webkit-scrollbar{width:5px;}
.dash-sidebar-scroll{scrollbar-width:thin;}
.dash-sidebar-brand{display:flex; align-items:center; gap:10px; padding:6px 10px 20px; font-family:var(--font-heading); font-weight:800; font-size:18px; letter-spacing:-.01em;}
.dash-sidebar-brand svg{width:28px; height:28px; flex-shrink:0;}
.dash-sidebar-brand span{white-space:nowrap; overflow:hidden;}
.dash-nav-group{margin-bottom:4px;}
.dash-nav-group-label{
  font-size:11px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  color:var(--text-disabled); padding:14px 12px 6px; white-space:nowrap; overflow:hidden;
}
.dash-nav-item{
  display:flex; align-items:center; gap:12px; padding:10px 12px; border-radius:14px;
  font-weight:700; font-size:14px; color:var(--text-primary); margin-bottom:1px;
  transition:background var(--trans-1), color var(--trans-1);
}
.dash-nav-item:hover{background:var(--grey-50);}
.dash-nav-item.active{background:var(--primary-tint); color:var(--primary);}
.dash-nav-icon{width:20px; height:20px; flex-shrink:0; display:flex; align-items:center; justify-content:center;}
.dash-nav-label{white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}

/* Collapsed (icon-rail) sidebar state, toggled by the button below the
   nav list (#dashSidebarCollapseBtn) — see shell.js initSidebarCollapse.
   body.sidebar-collapsed (toggled alongside .collapsed) is what makes
   .dash-main / .dash-topbar reflow to match, below. */
.dash-sidebar.collapsed{width:var(--rail-w);}
.dash-sidebar.collapsed .dash-sidebar-scroll{padding-left:8px; padding-right:8px;}
.dash-sidebar.collapsed .dash-sidebar-brand span,
.dash-sidebar.collapsed .dash-nav-group-label,
.dash-sidebar.collapsed .dash-nav-label,
.dash-sidebar.collapsed .dash-sidebar-collapse-label{display:none;}
.dash-sidebar.collapsed .dash-nav-item{justify-content:center; padding:10px;}
.dash-sidebar.collapsed .dash-sidebar-brand{justify-content:center; padding-left:0; padding-right:0;}
.dash-sidebar.collapsed .dash-sidebar-collapse-btn{padding:14px 0;}

/* Collapse toggle button — pinned under the scrollable nav, outside
   .dash-sidebar-scroll so it never scrolls out of view. The chevron
   points left when expanded ("collapse this") and flips to point
   right when collapsed ("expand this"). */
.dash-sidebar-collapse-btn{
  display:flex; align-items:center; justify-content:center; gap:8px; flex-shrink:0;
  width:100%; padding:14px 12px; margin:0; border-top:1px solid var(--grey-100);
  color:var(--text-secondary); font-weight:700; font-size:13px;
  transition:background var(--trans-1), color var(--trans-1);
}
.dash-sidebar-collapse-btn:hover{background:var(--grey-50); color:var(--primary);}
.dash-sidebar-collapse-btn svg{flex-shrink:0; transition:transform var(--trans-2);}
.dash-sidebar.collapsed .dash-sidebar-collapse-btn svg{transform:rotate(180deg);}

.dash-topbar{
  position:fixed; top:12px; right:12px; z-index:40; height:var(--header-h);
  left:calc(var(--sidebar-w) + 24px);
  background:var(--paper); border-radius:999px; box-shadow:var(--shadow-darker);
  display:flex; align-items:center; justify-content:space-between; padding:0 10px 0 22px;
  transition:left var(--trans-3);
}
body.sidebar-collapsed .dash-topbar{left:calc(var(--rail-w) + 24px);}
.dash-topbar-left{display:flex; align-items:center; gap:14px; min-width:0;}
.dash-topbar-right{display:flex; align-items:center; gap:2px;}
/* button.dash-sidebar-toggle (not .dash-sidebar-toggle alone) is
   deliberate: it appears together with .dash-icon-btn on this element,
   and .dash-icon-btn's own "display:flex" is declared later in this
   file, so with equal (single-class) specificity it was winning the
   cascade and showing this button on desktop. The extra element-type
   selector bumps specificity so this "hidden by default" rule wins
   instead — the mobile media query below re-shows it past 960px. */
button.dash-sidebar-toggle{
  display:none; width:38px; height:38px; border-radius:999px; align-items:center; justify-content:center;
  color:var(--text-primary); flex-shrink:0; transition:background var(--trans-1);
}
button.dash-sidebar-toggle:hover{background:var(--grey-50);}
.dash-page-title{font-family:var(--font-heading); font-weight:800; font-size:17px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}

.dash-search-trigger{
  display:flex; align-items:center; gap:10px; color:var(--text-secondary);
  background:var(--grey-50); border-radius:999px; padding:9px 14px 9px 16px; font-size:13.5px; font-weight:600;
  transition:background var(--trans-1), color var(--trans-1);
}
.dash-search-trigger:hover{background:var(--grey-100); color:var(--text-primary);}
.dash-search-trigger kbd{
  font-family:var(--font-body); font-size:11px; font-weight:800; color:var(--text-disabled);
  background:var(--paper); border-radius:6px; padding:2px 6px; border:1px solid var(--grey-200);
}

.dash-icon-btn{
  width:42px; height:42px; border-radius:999px;
  display:flex; align-items:center; justify-content:center;
  color:var(--text-primary); position:relative; flex-shrink:0;
  transition:background var(--trans-1), color var(--trans-1);
}
.dash-icon-btn:hover{background:var(--grey-25); color:var(--primary);}
.dash-icon-btn svg{transition:transform var(--trans-1);}
.dash-icon-btn:hover svg{transform:scale(0.92);}
.dash-icon-btn .dot-badge{
  position:absolute; top:2px; right:2px; min-width:16px; height:16px; border-radius:999px;
  background:var(--primary); color:#fff; font-size:10px; font-weight:800;
  display:flex; align-items:center; justify-content:center; padding:0 4px; line-height:1;
}

/* Theme toggle — dual-icon crossfade, ported exactly from
   site/styles.css .theme-toggle-icon (see partials/topbar.html). */
.theme-toggle-icon{position:relative;}
.theme-toggle-icon .ti-moon, .theme-toggle-icon .ti-sun{
  transform-origin:center; transition:opacity var(--trans-2), transform var(--trans-2);
}
.theme-toggle-icon .ti-sun{opacity:0; transform:scale(.5) rotate(-90deg); position:absolute; top:0; left:0;}
.theme-toggle-icon .ti-moon{opacity:1; transform:scale(1) rotate(0deg);}
html.dark .theme-toggle-icon .ti-moon{opacity:0; transform:scale(.5) rotate(90deg);}
html.dark .theme-toggle-icon .ti-sun{opacity:1; transform:scale(1) rotate(0deg);}

.dash-user-chip{
  display:flex; align-items:center; gap:10px; padding:6px 8px 6px 14px; border-radius:999px;
  margin-left:6px; transition:background var(--trans-1);
}
.dash-user-chip:hover{background:var(--grey-50);}
.dash-user-chip span{font-weight:700; font-size:13.5px; color:var(--text-primary); white-space:nowrap;}
.dash-user-avatar{width:34px; height:34px; border-radius:50%; background:var(--grad-brand); flex-shrink:0; display:flex; align-items:center; justify-content:center; color:#fff;}

/* Account popup — same recipe as site's .account-popup */
.dash-account-popup{
  position:fixed; top:calc(var(--header-h) + 22px); right:24px; width:280px; max-width:92vw;
  background:var(--paper); border-radius:20px; border:1.5px solid var(--grey-100); box-shadow:var(--shadow-md); z-index:80; padding:18px;
  visibility:hidden; pointer-events:none;
  transform:scale(0.95) translateY(-8px); opacity:0; transition:transform .2s ease, opacity .2s ease, visibility 0s 0.2s;
}
.dash-account-popup.open{visibility:visible; pointer-events:auto; transform:scale(1) translateY(0); opacity:1; transition:transform .2s ease, opacity .2s ease, visibility 0s 0s;}
.dash-account-header{display:flex; align-items:center; gap:12px; margin-bottom:12px; padding-bottom:12px; border-bottom:1px solid var(--grey-100);}
.dash-account-name{font-size:14px; font-weight:800;}
.dash-account-email{font-size:12px; color:var(--text-secondary); margin-top:2px; word-break:break-all;}
.dash-account-menu-item{
  display:flex; align-items:center; gap:10px; width:100%; padding:11px 10px; border-radius:12px;
  font-size:13.5px; font-weight:700; color:var(--text-primary); text-align:left;
}
.dash-account-menu-item:hover{background:var(--grey-50);}
.dash-account-menu-item.danger{color:var(--error);}
.dash-account-menu-item.danger:hover{background:var(--error-tint);}

/* ---------------- Main content area ---------------- */
.dash-main{
  margin-left:calc(var(--sidebar-w) + 24px);
  padding:calc(var(--header-h) + 34px) 28px 40px;
  transition:margin-left var(--trans-3);
  min-height:100vh;
}
body.sidebar-collapsed .dash-main{margin-left:calc(var(--rail-w) + 24px);}
.dash-page-header{display:flex; align-items:center; justify-content:space-between; margin-bottom:24px; flex-wrap:wrap; gap:12px;}
.dash-page-header h1{font-size:24px; font-weight:800;}
.dash-page-sub{color:var(--text-secondary); font-size:14px; margin-top:4px;}

/* ---------------- Cards / widgets (paper + shadow-sm/md recipe) ---------------- */
.dash-card{
  background:var(--paper); border-radius:var(--radius-xl); box-shadow:var(--shadow-sm); padding:20px;
}
.dash-widget-grid{
  display:grid; grid-template-columns:repeat(4, 1fr); gap:16px; margin-bottom:16px;
}
.dash-widget-grid.stats{grid-template-columns:repeat(4, 1fr);}
.dash-widget-grid.wide{grid-template-columns:repeat(2, 1fr);}
@media (max-width:1200px){
  .dash-widget-grid.stats{grid-template-columns:repeat(3, 1fr);}
}
@media (max-width:900px){
  .dash-widget-grid.stats{grid-template-columns:repeat(2, 1fr);}
  .dash-widget-grid.wide{grid-template-columns:1fr;}
}
@media (max-width:560px){
  .dash-widget-grid.stats{grid-template-columns:1fr;}
}

/* Stat tile */
.stat-tile{
  background:var(--paper); border-radius:var(--radius-xl); box-shadow:var(--shadow-sm); padding:18px 20px;
  display:flex; flex-direction:column; gap:10px;
}
.stat-tile-top{display:flex; align-items:center; justify-content:space-between;}
.stat-tile-icon{
  width:38px; height:38px; border-radius:12px; background:var(--primary-tint); color:var(--primary);
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
.stat-tile-label{font-size:13px; font-weight:700; color:var(--text-secondary);}
.stat-tile-value{font-family:var(--font-heading); font-size:26px; font-weight:800; line-height:1.1;}
.stat-tile-trend{font-size:12.5px; font-weight:700; display:inline-flex; align-items:center; gap:4px; width:fit-content;}
.stat-tile-trend.up{color:var(--success);}
.stat-tile-trend.down{color:var(--error);}
.stat-tile-trend.flat{color:var(--text-disabled);}

/* Skeleton loading state — every widget carries this until a later
   phase replaces it with real data (see PHASE_2_HANDOFF.md for the
   exact id/data-* hooks). */
.skeleton-block{
  background:linear-gradient(90deg, var(--grey-50) 25%, var(--grey-100) 37%, var(--grey-50) 63%);
  background-size:400% 100%; animation:dash-shimmer 1.6s ease infinite;
  border-radius:8px; display:block;
}
@keyframes dash-shimmer{0%{background-position:100% 50%;} 100%{background-position:0 50%;}}
.skeleton-line{height:12px; border-radius:6px;}
.skeleton-value{height:24px; width:70%; border-radius:6px;}
.skeleton-icon{width:38px; height:38px; border-radius:12px;}
.skeleton-row{height:44px; border-radius:12px;}
html.dark .skeleton-block{background:linear-gradient(90deg, var(--grey-50) 25%, var(--grey-200) 37%, var(--grey-50) 63%); background-size:400% 100%;}

/* List-style widgets (Latest Orders, Recent Activity, Top Articles/Products, Notifications) */
.widget-header{display:flex; align-items:center; justify-content:space-between; margin-bottom:14px;}
.widget-header h3{font-size:15px; font-weight:800;}
.widget-header a{font-size:12.5px; font-weight:700; color:var(--primary);}
.widget-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:4px;}
.widget-list-item{display:flex; align-items:center; gap:12px; padding:10px 6px; border-radius:12px; transition:background var(--trans-1);}
.widget-list-item:hover{background:var(--grey-25);}
.widget-list-thumb{width:36px; height:36px; border-radius:10px; background:var(--grey-50); flex-shrink:0;}
.widget-list-empty{
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:8px;
  padding:28px 12px; color:var(--text-secondary); font-size:13.5px;
}
.widget-list-empty svg{color:var(--text-disabled);}

/* Traffic graph */
.dash-chart-wrap{height:220px; border-radius:var(--radius-lg); background:var(--grey-25); position:relative; overflow:hidden;}
.dash-chart-range{display:flex; gap:4px; background:var(--grey-50); padding:3px; border-radius:999px;}
.dash-chart-range button{padding:6px 12px; border-radius:999px; font-size:12px; font-weight:700; color:var(--text-secondary);}
.dash-chart-range button.active{background:var(--paper); color:var(--primary); box-shadow:var(--shadow-xs);}

/* Breakdown bar rows (Device / Country statistics) */
.stat-row{display:flex; align-items:center; gap:10px; padding:7px 0; font-size:13px;}
.stat-row-label{width:84px; flex-shrink:0; color:var(--text-secondary); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.stat-row-bar{flex:1; height:8px; border-radius:999px; background:var(--grey-50); overflow:hidden;}
.stat-row-fill{height:100%; border-radius:999px; background:var(--grad-brand); width:0%; transition:width .6s ease;}
.stat-row-value{width:38px; text-align:right; flex-shrink:0; font-weight:800;}

/* Quick actions */
.quick-actions-grid{display:grid; grid-template-columns:repeat(2, 1fr); gap:10px;}
.quick-action-btn{
  display:flex; align-items:center; gap:10px; padding:14px; border-radius:14px; background:var(--grey-25);
  font-weight:700; font-size:13.5px; color:var(--text-primary); transition:background var(--trans-1), transform var(--trans-1);
}
.quick-action-btn:hover{background:var(--primary-tint); color:var(--primary); transform:translateY(-1px);}
.quick-action-btn svg{flex-shrink:0;}

/* Realtime pulse dot (Realtime Visitors widget) */
.pulse-dot{width:9px; height:9px; border-radius:50%; background:var(--success); position:relative; flex-shrink:0;}
.pulse-dot::after{
  content:''; position:absolute; inset:0; border-radius:50%; background:var(--success);
  animation:dash-pulse 1.8s ease-out infinite;
}
@keyframes dash-pulse{0%{transform:scale(1); opacity:.6;} 100%{transform:scale(2.6); opacity:0;}}

/* ---------------- Data table base (Phase 3+ reuses) ---------------- */
.dash-table{width:100%; border-collapse:collapse; font-size:13.5px;}
.dash-table th{text-align:left; color:var(--text-secondary); font-weight:700; font-size:12px; text-transform:uppercase; letter-spacing:.04em; padding:10px 14px; border-bottom:1px solid var(--grey-100);}
.dash-table td{padding:13px 14px; border-bottom:1px solid var(--grey-50); vertical-align:middle;}
.dash-table tr:last-child td{border-bottom:none;}
.dash-table-wrap{overflow-x:auto;}

/* ---------------- Coming-soon placeholder ---------------- */
.dash-coming-soon{
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  padding:80px 24px; background:var(--paper); border-radius:var(--radius-xl); box-shadow:var(--shadow-sm);
  min-height:360px;
}
.dash-coming-soon-icon{
  width:64px; height:64px; border-radius:20px; background:var(--primary-tint); color:var(--primary);
  display:flex; align-items:center; justify-content:center; margin-bottom:18px;
}
.dash-coming-soon h2{font-size:19px; font-weight:800; margin-bottom:8px;}
.dash-coming-soon p{color:var(--text-secondary); font-size:14px; max-width:380px; line-height:1.6;}

/* ---------------- Mobile drawer (narrow-viewport sidebar) ---------------- */
.dash-mobile-drawer{position:fixed; inset:0; z-index:85; display:flex; visibility:hidden; pointer-events:none; transition:visibility 0s .25s;}
.dash-mobile-drawer.open{visibility:visible; pointer-events:auto; transition:none;}
.dash-mobile-backdrop{position:absolute; inset:0; background:rgba(0,0,0,0.4); opacity:0; transition:opacity var(--trans-3);}
.dash-mobile-drawer.open .dash-mobile-backdrop{opacity:1;}
.dash-mobile-panel{
  position:absolute; top:0; left:0; bottom:0; width:288px; max-width:82vw;
  background:var(--paper); box-shadow:var(--shadow-md); padding:16px 14px 24px; overflow-y:auto;
  border-radius:0 28px 28px 0;
  transform:translateX(-100%); transition:transform var(--trans-3);
}
.dash-mobile-drawer.open .dash-mobile-panel{transform:translateX(0);}

/* ---------------- Command palette shell (non-functional this phase) ---------------- */
.dash-cmdk-overlay{position:fixed; inset:0; z-index:95; display:flex; visibility:hidden; pointer-events:none; align-items:flex-start; justify-content:center; padding-top:12vh; transition:visibility 0s .25s;}
.dash-cmdk-overlay.open{visibility:visible; pointer-events:auto; transition:none;}
.dash-cmdk-backdrop{position:absolute; inset:0; background:rgba(0,0,0,0.4); opacity:0; transition:opacity var(--trans-3);}
.dash-cmdk-overlay.open .dash-cmdk-backdrop{opacity:1;}
.dash-cmdk-modal{
  position:relative; width:100%; max-width:560px; margin:0 20px; background:var(--paper);
  border-radius:var(--radius-2xl); box-shadow:var(--shadow-md); overflow:hidden;
  transform:scale(0.96) translateY(-10px); opacity:0; transition:transform var(--trans-3), opacity var(--trans-3);
}
.dash-cmdk-overlay.open .dash-cmdk-modal{transform:scale(1) translateY(0); opacity:1;}
.dash-cmdk-input-row{display:flex; align-items:center; gap:12px; padding:16px 20px; border-bottom:1px solid var(--grey-100); color:var(--text-secondary);}
.dash-cmdk-input-row input{border:none; outline:none; background:none; font-size:15px; color:var(--text-primary); font-family:var(--font-body); flex:1;}
.dash-cmdk-empty{padding:36px 20px; text-align:center; color:var(--text-secondary); font-size:13.5px;}

/* ---------------- Responsive ---------------- */
@media (max-width:960px){
  .dash-sidebar{display:none;}
  button.dash-sidebar-toggle{display:flex;}
  .dash-topbar{left:12px;}
  .dash-main{margin-left:0;}
  body.sidebar-collapsed .dash-topbar,
  body.sidebar-collapsed .dash-main{margin-left:0; left:12px;}
  .dash-widget-grid.wide{grid-template-columns:1fr;}
}
@media (max-width:640px){
  .dash-user-chip span{display:none;}
  .dash-search-trigger span, .dash-search-trigger kbd{display:none;}
  .dash-search-trigger{padding:9px;}
  .dash-topbar{padding:0 8px;}
}
