/* DUKA app shell — POS-style left sidebar + content frame for the web app.
   Design language tuned to IEWRS-grade parity: Poppins throughout (UI AND
   figures — one typeface everywhere, see --dk-mono below), cool-slate neutrals
   under a warm-amber brand, rounded-2xl cards on layered elevation, pill nav
   with a soft tinted-fill active state, a scrimmed gradient hero, stat cards
   with an icon disc + tabular number, and a data-coverage row treatment. */
:root {
	/* Neutrals — cool slate (crisp, IEWRS-like) */
	--dk-ink: #0f172a;
	--dk-ink-2: #1e293b;
	--dk-ink-soft: #334155;
	--dk-muted: #64748b;
	--dk-faint: #94a3b8;
	--dk-line: #e6eaf0;
	--dk-line-soft: #eef2f7;
	--dk-bg: #f7f8fa;
	--dk-topbar-bg: color-mix(in srgb, var(--dk-bg) 82%, transparent); /* frosted sticky top bar */
	--dk-white: #fff;
	--dk-white-40: rgba(255, 255, 255, 0.4);
	--dk-hover-bg: #f1f5f9;
	--dk-row-hover: #f8fafc;
	--dk-scroll: #e2e8f0;

	/* Brand — warm amber */
	--dk-brand: #f59e0b;
	--dk-brand-600: #d97706;
	--dk-brand-ink: #b45309;
	--dk-brand-ink2: #92400e;
	--dk-brand-50: #fffbeb;
	--dk-brand-100: #fef3c7;
	--dk-brand-200: #fde68a;
	--dk-brand-bg: #fffbeb;
	--dk-brand-ring: rgba(245, 158, 11, 0.16);
	--dk-grad-brand: linear-gradient(140deg, #f59e0b 0%, #d97706 100%);
	--dk-grad-brand-deep: linear-gradient(140deg, #f59e0b 0%, #b45309 100%);
	/* Hero wash — espresso→amber, matching the approved /today hero direction
	   (three explicit stops, not composed from the semantic brand tokens above:
	   the hero needs a much darker "espresso" anchor than any existing brand
	   shade so white/cream hero text clears AA at every point along it). */
	/* stop-3 is deliberately a shade deeper than the spec mock's literal #c07d1e:
	   at the gradient's far bottom-right corner (the one place the hero's
	   translucent ghost pills can end up sitting), the lighter mock value only
	   clears ~3.3–3.7:1 against --dk-hero-ink/-ink-soft — under AA's 4.5:1
	   normal-text floor. This value keeps the same warm-amber identity while
	   pushing that worst-case corner to ~4.0–4.9:1 (verified: see the contrast
	   check this rebuild ran against stop2→stop3's actual visible blend, not
	   the raw stop3 swatch, since stop3 sits at 128% — past the visible 0–100%
	   range — and is never fully reached on-screen). */
	--dk-hero-stop-1: #2b1a0d;
	--dk-hero-stop-2: #7a460f;
	--dk-hero-stop-3: #a5680c;
	--dk-hero: linear-gradient(120deg, var(--dk-hero-stop-1) 0%, var(--dk-hero-stop-2) 52%, var(--dk-hero-stop-3) 128%);
	/* Soft amber radial highlight overlaid top-right of the hero card. */
	--dk-hero-glow: rgba(245, 158, 11, 0.35);
	/* Hero text — cream/amber tones over the dark gradient above, each picked to
	   clear WCAG AA against the darker (visible, 0–100%) portion of the wash. */
	--dk-hero-ink: #fdf6ea;
	--dk-hero-ink-soft: #ecd6b2;
	--dk-hero-ink-dim: #f3dcb4;
	/* Trend up/down tuned to read on the dark espresso hero (the light-ground
	   --dk-green/--dk-red fail contrast there) — hero-context only. */
	--dk-hero-up: #8ff0b6;
	--dk-hero-down: #ffb4a8;
	--dk-hero-shadow: 0 12px 30px -14px rgba(122, 70, 15, 0.5);
	--dk-hero-spark-fill: rgba(253, 246, 234, 0.1);
	--dk-hero-border: rgba(253, 246, 234, 0.22);
	/* Ghost quick-action pills on the hero — translucent cream fill/border. */
	--dk-hero-pill-bg: rgba(253, 246, 234, 0.1);
	--dk-hero-pill-bg-hover: rgba(253, 246, 234, 0.19);
	--dk-hero-pill-border: rgba(253, 246, 234, 0.17);
	--dk-hero-pill-border-hover: rgba(253, 246, 234, 0.28);
	/* Dark ink for text/icons sitting on a SOLID amber fill (the hero's primary
	   "New sale" pill) — white fails AA on amber (~1.9:1); this dark brown clears
	   it comfortably. Distinct from --dk-brand-ink/-ink2, which are amber-tinted
	   text used on light (not solid-amber) backgrounds elsewhere in the app. */
	--dk-on-brand: #3a2408;

	--dk-sb-w: 262px;
	--dk-sb-w-collapsed: 76px;

	/* Surfaces */
	--dk-card-bg: var(--dk-white);
	--dk-radius: 16px;
	--dk-radius-lg: 18px;
	--dk-radius-xl: 24px;
	/* Shared form-control height so SearchPicker / Combobox / DatePicker /
	   TextInput sit level on the same row (stock composer, receive, transfer). */
	--dk-control-h: 45px;
	--dk-elev-1: 0 1px 2px -1px rgba(15, 23, 42, 0.06), 0 1px 3px 0 rgba(15, 23, 42, 0.05);
	--dk-elev-2: 0 2px 4px -2px rgba(15, 23, 42, 0.08), 0 4px 12px -2px rgba(15, 23, 42, 0.08);
	--dk-elev-3: 0 8px 24px -6px rgba(15, 23, 42, 0.12), 0 16px 40px -12px rgba(15, 23, 42, 0.14);
	/* Premium card treatment — a layered resting shadow (near/mid/far), a
	   hair-off-white surface, and a fine top inset highlight so cards read as a
	   lit physical sheet rather than a flat rectangle. Used across the dashboard. */
	--dk-elev-card: 0 1px 2px -1px rgba(15, 23, 42, 0.05), 0 4px 14px -6px rgba(15, 23, 42, 0.08), 0 14px 34px -18px rgba(15, 23, 42, 0.12);
	--dk-surface-tint: #fcfcfd;
	--dk-inset-hi: inset 0 1px 0 rgba(255, 255, 255, 0.7);
	--dk-hero-hi: inset 0 1px 0 rgba(255, 255, 255, 0.09), inset 0 0 0 1px rgba(255, 255, 255, 0.04);
	/* Data-viz — area-fill stops + hairline grid for the sales chart. */
	--dk-chart-grid: #eef2f7;
	--dk-chart-fill-top: rgba(245, 158, 11, 0.20);
	--dk-chart-fill-bot: rgba(245, 158, 11, 0);

	/* Semantic accents */
	--dk-green: #15803d;
	--dk-green-600: #16a34a;
	--dk-green-800: #166534;
	--dk-green-bg: #f0fdf4;
	--dk-green-50: #f0fdf4;
	--dk-green-line: rgba(21, 128, 61, 0.28);
	--dk-red: #b91c1c;
	--dk-red-bg: #fef2f2;
	--dk-red-line: rgba(185, 28, 28, 0.28);
	--dk-amber-soft: rgba(245, 158, 11, 0.16);
	--dk-blue: #1d4ed8;
	--dk-blue-bg: #eff6ff;
	--dk-skeleton: #e8edf3;
	--dk-skeleton-shine: #f4f7fa;

	/* Decorative chip tokens — icon discs (kpi/activity/quick-link) and the
	   list-page primary-button glow reference these instead of the amber
	   tokens directly, defaulting to today's exact amber look. The Petite
	   calm layer below (#duka-app) redefines just these two so the SPA's
	   icon chips read as quiet neutral instead of tinted-amber, while every
	   other page still using these classes (unscoped) is byte-for-byte
	   unchanged. */
	--dk-chip-bg: var(--dk-brand-50);
	--dk-chip-fg: var(--dk-brand-ink);
	--dk-cta-glow: 0 6px 16px -8px rgba(217, 119, 6, 0.6);

	/* User-initial avatar discs (sidebar footer + topbar chip) — shared shell
	   markup, so this is a real token (not scoped): every avatar app-wide
	   moves off the amber gradient to a calm neutral-ink disc. */
	--dk-avatar-bg: #33415c;
	--dk-avatar-fg: var(--dk-white);

	--dk-sans: "Poppins", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	/* ONE typeface across the whole product: Poppins. Numbers used to be set in
	   IBM Plex Mono for tabular alignment — but that font was NEVER loaded on the
	   SPA (only Poppins/Inter are), so on real customer devices numbers silently
	   fell back to the system monospace (Menlo/SF Mono) while the UI was Poppins:
	   two clashing fonts. Numbers now use the UI font too (same font everywhere).
	   `--dk-mono` is kept as the single numeric seam — same family as --dk-sans,
	   paired with `font-variant-numeric: tabular-nums` at its call sites — so if
	   number styling ever needs to diverge again it has exactly one home. It is
	   deliberately NOT monospace despite the historical name. */
	--dk-mono: var(--dk-sans);
}

/* ======================================================================
   PETITE CALM LAYER — scoped to the SPA mount (#duka-app) only.
   Part of the frappe-ui 1.0 "Petite" migration: calmer, cleaner, more
   restrained surfaces with amber kept as a precise accent instead of a loud
   fill. These custom-property overrides cascade to the whole SPA subtree but
   NOT to the Jinja marketing/storefront pages (which have no #duka-app), so
   the public brand is untouched. Values live here in the token file (not in
   the SPA bundle) so there's still a single source of colour truth.
   ====================================================================== */
#duka-app {
	/* Cleaner, cooler canvas + crisp (not hairline) borders. --dk-line was #e9edf3:
	   ~1.05:1 against the white card, so card edges barely registered even on a good
	   panel and vanished entirely on washed-out / older displays (a real client on an
	   old Dell couldn't see them), leaving the whole SPA reading flat. Bumped to a
	   clear slate line that holds up on bad displays while staying soft and modern on
	   good ones; --dk-line-soft (internal dividers) lifted just enough to be present. */
	--dk-bg: #f8fafc;
	--dk-line: #d8dee8;
	--dk-line-soft: #e7ebf2;
	/* Hover/scroll neutral must sit DARKER than the resting --dk-line above, or a
	   hover that swaps border-color to it would LIGHTEN the edge (inverted affordance).
	   Was #e2e8f0 (now lighter than the crisper resting line) — deepened one step. */
	--dk-scroll: #cbd3e0;
	/* Chart hairline grid, kept in step with the SPA's --dk-line-soft (the :root
	   default #eef2f7 is the pre-bump value, for the legacy Jinja charts). */
	--dk-chart-grid: #e7ebf2;
	/* Premium canvas — a whisper-soft cool wash at the top fading to the flat bg,
	   so cards read as floating on a lit surface (the depth the reference dashboards
	   get from a tinted gradient) instead of sitting on flat grey. Deliberately
	   neutral-cool, not tinted amber — keeps the single warm accent for the brand
	   moments, not the whole page. The content area is the only place it shows; the
	   sidebar sits on its own opaque white panel over it. */
	--dk-canvas: linear-gradient(180deg, #f3f5f8 0%, #f8fafc 44%);

	/* REVERSAL 2026-07, product-owner-approved /today redesign: the calm
	   ink-slate hero direction above is retired in favour of the rich
	   espresso-to-amber wash — no override needed here any more, the SPA now uses
	   the same --dk-hero and its --dk-hero-stop and --dk-hero-ink tokens as :root.
	   Left as an explicit no-op, not deleted, so a future make-it-calm-again
	   ask has an obvious place to reintroduce a scoped override, and so this
	   block's history stays legible. */

	/* Flatter, calmer elevation. */
	--dk-elev-1: 0 1px 2px -1px rgba(15, 23, 42, 0.05), 0 1px 2px 0 rgba(15, 23, 42, 0.04);
	--dk-elev-2: 0 1px 3px -1px rgba(15, 23, 42, 0.06), 0 4px 10px -3px rgba(15, 23, 42, 0.07);
	--dk-elev-3: 0 6px 20px -6px rgba(15, 23, 42, 0.10), 0 12px 32px -10px rgba(15, 23, 42, 0.10);
	/* Calmer card elevation inside the SPA — the base --dk-elev-card is tuned for
	   the louder legacy Jinja pages; the SPA wants a quieter, more precise lift. */
	/* Apple-quiet lift: tight, low-opacity, layered — a whisper of depth, not a
	   "premium" float. Definition is carried by the (Dell-safe) border; the shadow
	   only lifts the card a hair off the canvas. Restraint over richness. */
	--dk-elev-card: 0 0.5px 1.5px rgba(15, 23, 42, 0.04), 0 3px 8px -4px rgba(15, 23, 42, 0.06), 0 8px 20px -14px rgba(15, 23, 42, 0.08);
	--dk-surface-tint: #fdfdfe;

	/* Tighter radii, Petite-scale (base system runs 16/18/24 for legacy Jinja
	   dashboard pages outside this reskin; the SPA gets a crisper 10/12/16). */
	--dk-radius: 16px;
	--dk-radius-lg: 19px;
	--dk-radius-xl: 22px;
	/* The one deliberately larger radius in the SPA — reserved for the app
	   shell's single floating structural panel, the sidebar card styled in
	   frontend/src/styles/main.css via the dkshell sidebar slot, matching
	   the approved dashboard mockup's ~22px separated-card sidebar. Not a page
	   card radius, so it stays its own token rather than forking --dk-radius-xl. */
	--dk-sb-panel-radius: 22px;

	/* Icon-chip + CTA-glow overrides — see the --dk-chip and --dk-cta-glow
	   definitions in :root for the legacy unscoped amber default these
	   replace. Within the SPA, decorative icon discs go quiet neutral instead
	   of tinted-amber, and the "+ New" button's glow calms down to a hairline
	   lift instead of a saturated amber halo. */
	--dk-chip-bg: #eef1f6;
	--dk-chip-fg: var(--dk-ink-soft);

	/* Soft metric-icon tints (Imboni-inspired) — used ONLY on the /today KPI-card
	   icon chips to give the dashboard richness. Amber stays the single brand accent
	   (CTAs, active nav, the hero); these are quiet supporting hues, never fills. */
	--dk-tint-blue: #2f74e6;   --dk-tint-blue-bg: #eef4fe;
	--dk-tint-green: #12924e;  --dk-tint-green-bg: #ebf8f0;
	--dk-tint-violet: #7b5cf0; --dk-tint-violet-bg: #f2eefe;
	--dk-tint-amber: var(--dk-brand-ink); --dk-tint-amber-bg: var(--dk-brand-50);
	--dk-cta-glow: 0 2px 6px -2px rgba(217, 119, 6, 0.35);
}

/* Calmer hover lift — a 2px float read as bouncy against the flatter elevation
   scale above; 1px is enough affordance without feeling animated. */
#duka-app .dksec__card:hover,
#duka-app .dkkpi__card:hover { transform: translateY(-1px); }

body { background: var(--dk-bg); }
.dkapp-layout, .dkapp-layout button, .dkapp-layout input { font-family: var(--dk-sans); }
.dkapp-layout { color: var(--dk-ink); -webkit-font-smoothing: antialiased; }

/* Break the shell out of Frappe's centered web container. */
.main-section:has(.dkapp-layout),
.page-content:has(.dkapp-layout),
.page_content:has(.dkapp-layout),
.container:has(.dkapp-layout) {
	max-width: none !important; width: 100% !important; padding: 0 !important; margin: 0 !important;
}
.dkapp-layout ~ footer, footer.web-footer:has(~ .dkapp-layout) { display: none !important; }

/* ============================ Sidebar ============================ */
.dksb {
	position: fixed; top: 0; left: 0; bottom: 0; width: var(--dk-sb-w); z-index: 60;
	background: var(--dk-white); border-right: 1px solid var(--dk-line);
	display: flex; flex-direction: column; padding: 12px 14px 14px;
	transition: width .18s ease;
}

/* Brand */
.dksb__brandrow { display: flex; align-items: center; gap: 11px; height: 52px; padding: 0 6px 0 4px; position: relative; }
.dksb__mark {
	flex: 0 0 38px; width: 38px; height: 38px; border-radius: 12px;
	background: var(--dk-grad-brand);
	box-shadow: 0 3px 10px -5px rgba(217, 119, 6, 0.5);
	display: inline-flex; align-items: center; justify-content: center; color: var(--dk-white);
}
.dksb__mark svg { width: 20px; height: 20px; }
.dksb__brandtext { display: flex; flex-direction: column; min-width: 0; line-height: 1.05; }
.dksb__wordmark { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; color: var(--dk-ink); line-height: 1.3; }
.dksb__tagline {
	font-size: 12px; font-weight: 500; letter-spacing: normal; text-transform: none;
	color: var(--dk-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.dksb__nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; gap: 2px; padding-top: 8px; }
.dksb__nav::-webkit-scrollbar { width: 6px; }
.dksb__nav::-webkit-scrollbar-thumb { background: var(--dk-scroll); border-radius: 3px; }
.dksb__group {
	font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
	color: var(--dk-faint); padding: 14px 12px 6px; white-space: nowrap; overflow: hidden;
}
/* Calm nav rows — quiet rounded-rect (Frappe CRM/Drive), not a pill: a soft
   tinted-fill + hairline ring marks the active row, never a loud fill. */
.dksb__link {
	display: flex; align-items: center; gap: 12px; min-height: 42px;
	padding: 8px 14px; border-radius: 10px; text-decoration: none; position: relative;
	font-size: 13.5px; font-weight: 500; color: var(--dk-ink-soft); white-space: nowrap;
	transition: background .13s ease, color .13s ease, box-shadow .13s ease;
}
.dksb__link span { overflow: hidden; text-overflow: ellipsis; }
.dksb__link:hover { background: var(--dk-hover-bg); color: var(--dk-ink); text-decoration: none; }
.dksb__link.is-active {
	background: var(--dk-brand-50); color: var(--dk-brand-ink); font-weight: 600;
	box-shadow: inset 0 0 0 1px var(--dk-brand-200);
}
.dksb__ic { flex: 0 0 20px; width: 20px; height: 20px; opacity: .9; color: var(--dk-faint); }
.dksb__link:hover .dksb__ic { color: var(--dk-muted); }
.dksb__link.is-active .dksb__ic { color: var(--dk-brand-600); opacity: 1; }

.dksb__admin { border-top: 1px solid var(--dk-line-soft); margin-top: 10px; padding-top: 4px; }

.dksb__foot { border-top: 1px solid var(--dk-line-soft); padding-top: 8px; margin-top: 8px; flex: 0 0 auto; }
/* Collapse toggle — a quiet full-width row at the very bottom, mirroring the SPA
   shell's frappe-ui SidebarCollapseToggle (was a floating chevron circle before). */
.dksb__collapse {
	display: flex; align-items: center; gap: 12px; width: 100%; min-height: 36px; margin-top: 4px;
	padding: 7px 14px; border: 0; border-radius: 10px; background: none; cursor: pointer;
	font-size: 13px; font-weight: 500; color: var(--dk-muted); font-family: var(--dk-sans); white-space: nowrap;
	transition: background .13s ease, color .13s ease;
}
.dksb__collapse:hover { background: var(--dk-hover-bg); color: var(--dk-ink); }
.dksb__collapse-ic { flex: 0 0 18px; width: 18px; height: 18px; color: var(--dk-faint); transition: transform .18s ease; }
.dksb__collapse:hover .dksb__collapse-ic { color: var(--dk-muted); }
.dksb__desk {
	display: flex; align-items: center; gap: 12px; min-height: 40px; padding: 7px 14px; border-radius: 10px;
	font-size: 13px; font-weight: 500; color: var(--dk-muted); text-decoration: none; white-space: nowrap;
}
.dksb__desk:hover { background: var(--dk-hover-bg); color: var(--dk-ink); text-decoration: none; }
.dksb__desk .dksb__ic { color: var(--dk-faint); }
.dksb__user {
	display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 12px; margin-top: 2px;
	background: var(--dk-hover-bg);
}
.dksb__avatar {
	width: 34px; height: 34px; border-radius: 10px; flex: 0 0 34px;
	background: var(--dk-avatar-bg); color: var(--dk-avatar-fg);
	font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; justify-content: center;
}
.dksb__userbody { flex: 1; min-width: 0; line-height: 1.25; }
.dksb__uname { font-size: 13px; font-weight: 600; color: var(--dk-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dksb__urole { font-size: 11.5px; color: var(--dk-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dksb__logout { color: var(--dk-faint); display: inline-flex; flex: 0 0 auto; padding: 4px; border-radius: 8px; }
.dksb__logout:hover { color: var(--dk-red); background: var(--dk-white); }

/* Collapsed rail */
.dkapp-layout.is-collapsed .dksb { width: var(--dk-sb-w-collapsed); }
.dkapp-layout.is-collapsed .dkapp-main { margin-left: var(--dk-sb-w-collapsed); }
.dkapp-layout.is-collapsed .dksb__brandtext,
.dkapp-layout.is-collapsed .dksb__link span,
.dkapp-layout.is-collapsed .dksb__desk span,
.dkapp-layout.is-collapsed .dksb__userbody,
.dkapp-layout.is-collapsed .dksb__logout,
.dkapp-layout.is-collapsed .dksb__collapse span,
.dkapp-layout.is-collapsed .dksb__group { opacity: 0; width: 0; overflow: hidden; }
.dkapp-layout.is-collapsed .dksb__group { padding: 8px 0 4px; height: 8px; }
.dkapp-layout.is-collapsed .dksb__brandrow { justify-content: center; padding: 0; }
.dkapp-layout.is-collapsed .dksb__collapse-ic { transform: rotate(180deg); }
.dkapp-layout.is-collapsed .dksb__link,
.dkapp-layout.is-collapsed .dksb__desk,
.dkapp-layout.is-collapsed .dksb__collapse { justify-content: center; }
.dkapp-layout.is-collapsed .dksb__user { justify-content: center; background: none; }

/* ============================ Main ============================ */
.dkapp-main { margin-left: var(--dk-sb-w); min-height: 100vh; transition: margin-left .18s ease; }

.dkapp-top {
	position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 16px;
	padding: 14px 34px; background: var(--dk-topbar-bg); backdrop-filter: saturate(1.4) blur(8px);
	border-bottom: 1px solid var(--dk-line);
}
.dkapp-top__menu, .dkapp-top__brand { display: none; }
/* Page-context crumb — icon + active page title, mirroring the SPA shell's
   .dkshell__context so Jinja pages read identically. */
.dkapp-top__context { display: flex; align-items: center; gap: 11px; min-width: 0; }
.dkapp-top__context-ico {
	flex: 0 0 30px; width: 30px; height: 30px; border-radius: 9px;
	background: var(--dk-hover-bg); color: var(--dk-ink-soft);
	display: grid; place-items: center;
}
.dkapp-top__context-ico .dksb__ic { width: 17px; height: 17px; color: inherit; opacity: 1; }
.dkapp-top__context-title {
	font-size: 15.5px; font-weight: 650; letter-spacing: -0.015em; color: var(--dk-ink);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dksearch { flex: 1; max-width: 480px; position: relative; }
.dksearch svg { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: var(--dk-faint); width: 17px; height: 17px; }
.dksearch input {
	width: 100%; border: 1px solid var(--dk-line); background: var(--dk-white); border-radius: 14px;
	padding: 11px 16px 11px 42px; font-size: 13.5px; color: var(--dk-ink);
	transition: border-color .12s ease, box-shadow .12s ease;
}
.dksearch input::placeholder { color: var(--dk-faint); }
.dksearch input:focus { outline: none; border-color: var(--dk-brand); box-shadow: 0 0 0 4px var(--dk-brand-ring); }
.dkapp-top__spacer { flex: 1; }
.dkchip {
	display: flex; align-items: center; gap: 10px; padding: 5px 9px 5px 6px; border-radius: 999px;
	border: 1px solid var(--dk-line); background: var(--dk-white); text-decoration: none; cursor: pointer; box-shadow: var(--dk-elev-1);
}
.dkchip:hover { border-color: var(--dk-brand-200); text-decoration: none; }
.dkchip__avatar {
	width: 30px; height: 30px; border-radius: 50%; flex: 0 0 30px;
	background: var(--dk-avatar-bg); color: var(--dk-avatar-fg);
	font-weight: 600; font-size: 12.5px; display: inline-flex; align-items: center; justify-content: center;
}
.dkchip__body { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; text-align: left; }
.dkchip__name { display: block; font-size: 12.5px; font-weight: 600; color: var(--dk-ink); white-space: nowrap; }
.dkchip__role { display: block; font-size: 11px; color: var(--dk-muted); white-space: nowrap; }
.dkchip__caret { color: var(--dk-faint); flex: 0 0 auto; }
.dkmenu { position: relative; }
.dkmenu__pop {
	position: absolute; right: 0; top: calc(100% + 8px); min-width: 200px; background: var(--dk-white);
	border: 1px solid var(--dk-line); border-radius: 12px; box-shadow: var(--dk-elev-3); padding: 6px;
	opacity: 0; visibility: hidden; transform: translateY(-4px); transition: all .14s ease; z-index: 50;
}
.dkmenu.is-open .dkmenu__pop { opacity: 1; visibility: visible; transform: translateY(0); }
.dkmenu__item {
	display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: 10px;
	font-size: 13px; font-weight: 500; color: var(--dk-ink-soft); text-decoration: none;
}
.dkmenu__item:hover { background: var(--dk-hover-bg); color: var(--dk-ink); text-decoration: none; }
.dkmenu__item svg { width: 17px; height: 17px; color: var(--dk-faint); }
.dkmenu__item--danger:hover { color: var(--dk-red); }
.dkmenu__item--danger:hover svg { color: var(--dk-red); }
.dkmenu__sep { height: 1px; background: var(--dk-line-soft); margin: 5px 4px; }

.dkapp-content { max-width: 2100px; margin: 0 auto; padding: 24px 30px 44px; }

/* Tab panels sit flush under the tab bar by default — frappe-ui's TabsContent
   (reka `[role="tabpanel"]`) ships no top spacing, so every tabbed surface
   (Cash & bank, Adjust stock, and any future one) has the content jammed
   against the tabs. One global rule gives them all the same breathing room as
   the rest of the app's vertical rhythm (matches .dkph's 20px), instead of
   each page re-inventing a margin. */
[role="tabpanel"] { padding-top: 20px; }

/* ============================ Section landing ============================ */
.dksec__eyebrow { font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--dk-faint); }
.dksec__title { font-size: 26px; font-weight: 700; letter-spacing: -.02em; color: var(--dk-ink); margin: 6px 0 4px; }
.dksec__lede { color: var(--dk-muted); font-size: 14px; margin-bottom: 24px; }
.dksec__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 16px; }
.dksec__card { display: block; background: var(--dk-white); border: 1px solid var(--dk-line); border-radius: var(--dk-radius); padding: 18px; text-decoration: none; box-shadow: var(--dk-elev-1); transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease; }
.dksec__card:hover { box-shadow: var(--dk-elev-2); transform: translateY(-2px); border-color: var(--dk-line); text-decoration: none; }
.dksec__card-title { font-size: 15px; font-weight: 600; color: var(--dk-ink); }
.dksec__card-sub { font-size: 13px; color: var(--dk-muted); margin-top: 3px; }

/* ============================ List pages ============================ */
.dklist__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.dklist__new { background: var(--dk-grad-brand); color: var(--dk-white); font-weight: 600; font-size: 13px; border: 0; border-radius: 999px; padding: 10px 18px; text-decoration: none; white-space: nowrap; box-shadow: var(--dk-cta-glow); }
.dklist__new:hover { filter: brightness(1.05); color: var(--dk-white); text-decoration: none; }
.dklist__search { width: 100%; max-width: 460px; margin-bottom: 16px; border: 1px solid var(--dk-line); border-radius: 14px; padding: 12px 16px; font-size: 14px; background: var(--dk-white); }
.dklist__search:focus { outline: none; border-color: var(--dk-brand); box-shadow: 0 0 0 4px var(--dk-brand-ring); }
.dklist__rows { background: var(--dk-white); border: 1px solid var(--dk-line); border-radius: var(--dk-radius); overflow: hidden; box-shadow: var(--dk-elev-1); }
.dklist__row { display: flex; align-items: center; gap: 14px; padding: 14px 18px; text-decoration: none; color: inherit; }
.dklist__row + .dklist__row { border-top: 1px solid var(--dk-line-soft); }
.dklist__row:hover { background: var(--dk-row-hover); text-decoration: none; }
.dklist__name { font-weight: 600; color: var(--dk-ink); font-size: 14px; }
.dklist__meta { color: var(--dk-muted); font-size: 12.5px; margin-top: 1px; }
.dklist__tag { margin-left: auto; font-size: 12.5px; color: var(--dk-muted); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dklist__empty { padding: 48px 16px; text-align: center; color: var(--dk-faint); font-size: 14px; }

/* ============================ Today dashboard ============================
   Rebuilt (2026-07) to the product-owner-approved elevated-dashboard direction:
   a rich espresso→amber hero with the greeting + a reorder reminder + quick-
   action pills, a 4-up stat-card row on layered elevation, a main row of a
   premium amber bar chart + a payment-mix donut, a 3-column "Recent activity"
   row, and a "Needs attention" low/out-of-stock strip. Light ground, hair-
   off-white cards, soft-tinted icon squares, DUKA amber as the single accent
   (plus the one sanctioned hero exception below). Whitespace is a feature;
   calm and expensive over dense.
   ============================================================================ */
.dktoday { padding-bottom: 8px; display: flex; flex-direction: column; gap: 16px; }

/* ── Hero — the rich espresso→amber wash. Deliberately the one place this app
   uses a saturated brand gradient as a full surface (every other card stays
   flat/white): it's the page's single "welcome" moment, not a repeated
   ornament, so it doesn't violate the "amber is a precise accent" rule
   elsewhere. Cream/amber text tokens (--dk-hero-ink*) are picked to clear AA
   against the dark (visible 0–100%) portion of the gradient. ────────────── */
.dkhero {
	position: relative; overflow: hidden; border-radius: var(--dk-radius-xl);
	padding: 26px 28px 24px; color: var(--dk-hero-ink); background: var(--dk-hero);
	box-shadow: var(--dk-elev-card), var(--dk-hero-hi);
}
.dkhero::after {
	content: ""; position: absolute; inset: 0; pointer-events: none;
	background: radial-gradient(560px 240px at 88% -30%, var(--dk-hero-glow), transparent 70%);
}
.dkhero__top { position: relative; display: flex; align-items: center; gap: 12px; }
.dkhero__date {
	font-size: 12px; color: var(--dk-hero-ink-dim); border: 1px solid var(--dk-hero-border);
	border-radius: 999px; padding: 5px 12px; display: inline-flex; gap: 6px; align-items: center;
}
.dkhero__date svg { width: 13px; height: 13px; flex: 0 0 auto; }
.dkhero__greet { position: relative; font-size: 27px; letter-spacing: -0.02em; margin: 16px 0 4px; font-weight: 700; color: var(--dk-hero-ink); }
.dkhero__sub { position: relative; margin: 0; color: var(--dk-hero-ink-soft); font-size: 14px; }
.dkhero__remind {
	position: relative; margin-top: 14px; font-size: 12.5px; color: var(--dk-hero-ink-soft);
	display: inline-flex; align-items: center; gap: 8px;
}
.dkhero__remind svg { width: 14px; height: 14px; flex: 0 0 auto; }
.dkhero__remind b { color: var(--dk-hero-ink); font-weight: 600; }

/* Hero text color — DEFENSIVE hardening, not a targeted fix. In production the
   greeting <h1>, sub <p> and date <span> rendered DARK instead of --dk-hero-ink
   even though `.dkhero { color: <ink> }` should cascade and an explicit
   `.dkhero__greet { color: <ink> }` was served — while the <a>/<button> pills
   (same ink) stayed cream. The exact winning rule was NEVER isolated: a
   repo-wide sweep of every shipped CSS bundle found no `h1` color rule at all,
   and no `.prose` ancestor exists on this page, so the frappe-ui typography
   plugin's `.prose :where(h1)` cannot be the cause. Leaving the mechanism
   undiagnosed (candidates not ruled out: a stale cached bundle at the time of
   observation, or an injected/overlay style). This block ancestor-qualifies to
   (0,2,0) AND uses !important so the hero ink wins over any normal-weight rule
   regardless of source — colour only, so the mobile font-size overrides below
   are untouched. Scoped to `.dkhero` (Today-only) so it cannot leak elsewhere.
   If the dark text recurs, instrument the element's computed `color` in a live
   browser to find the real winning declaration before trusting this note. */
.dkhero .dkhero__greet { color: var(--dk-hero-ink) !important; }
.dkhero .dkhero__sub { color: var(--dk-hero-ink-soft) !important; }
.dkhero .dkhero__date { color: var(--dk-hero-ink-dim) !important; }
.dkhero .dkhero__remind { color: var(--dk-hero-ink-soft) !important; }
.dkhero .dkhero__remind b { color: var(--dk-hero-ink) !important; }

/* Quick-action pills — icon + label inline so nothing wraps and every action
   reads as obviously tappable; wraps to a second row as actions grow. "New
   sale" is the one solid-amber primary pill; the rest are translucent ghost
   pills over the hero. */
.dkquick { position: relative; display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.dkqpill {
	display: inline-flex; align-items: center; gap: 9px; padding: 9px 16px 9px 13px; border-radius: 999px;
	font-size: 13px; font-weight: 600; color: var(--dk-hero-ink); background: var(--dk-hero-pill-bg);
	border: 1px solid var(--dk-hero-pill-border); white-space: nowrap; cursor: pointer;
	transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
.dkqpill svg { width: 17px; height: 17px; flex: 0 0 auto; }
.dkqpill:hover {
	background: var(--dk-hero-pill-bg-hover); border-color: var(--dk-hero-pill-border-hover);
	color: var(--dk-hero-ink); text-decoration: none; transform: translateY(-1px);
}
.dkqpill--primary { background: var(--dk-brand); border-color: var(--dk-brand); color: var(--dk-on-brand); }
.dkqpill--primary:hover { background: var(--dk-brand-600); border-color: var(--dk-brand-600); color: var(--dk-on-brand); }

/* Buttons — a neutral ghost + an amber primary, shared across every page's
   PageHeader actions slot (ItemsList "+ New item", CustomersList "+ New
   customer", the /today error banner's Retry, etc.). */
.dkbtn {
	display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; border-radius: 999px; cursor: pointer;
	font-size: 13px; font-weight: 600; font-family: var(--dk-sans); letter-spacing: 0.005em; text-decoration: none;
	transition: transform .14s ease, box-shadow .14s ease, filter .14s ease, background .12s ease, border-color .12s ease;
}
.dkbtn--ghost { background: var(--dk-white); border: 1px solid var(--dk-line); color: var(--dk-ink-soft); box-shadow: var(--dk-elev-1); }
.dkbtn--ghost:hover { border-color: var(--dk-scroll); color: var(--dk-ink); box-shadow: var(--dk-elev-2); text-decoration: none; }
.dkbtn--primary { background: var(--dk-grad-brand); border: 1px solid transparent; color: var(--dk-white); box-shadow: var(--dk-cta-glow); }
.dkbtn--primary:hover { transform: translateY(-1px); filter: brightness(1.04); box-shadow: 0 10px 22px -8px rgba(217, 119, 6, 0.7); color: var(--dk-white); text-decoration: none; }
.dkbtn--primary svg { transition: transform .16s ease; }
.dkbtn--primary:hover svg { transform: translateX(1px); }

.dktoday__noscript {
	background: var(--dk-brand-bg); border: 1px solid var(--dk-brand-200); border-radius: var(--dk-radius);
	padding: 16px 18px; color: var(--dk-brand-ink); font-size: 13.5px;
}
.dktoday__noscript-stats { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; font-weight: 600; color: var(--dk-ink); }

.dktoday__err {
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	background: var(--dk-red-bg); border: 1px solid var(--dk-red-line); color: var(--dk-red);
	border-radius: 14px; padding: 11px 16px; font-size: 13px; font-weight: 500;
}
.dktoday__err[hidden] { display: none; }
.dktoday__err button {
	background: var(--dk-white); border: 1px solid var(--dk-red-line); color: var(--dk-red); font-weight: 600;
	font-size: 12.5px; border-radius: 999px; padding: 5px 13px; cursor: pointer; white-space: nowrap;
}
.dktoday__err button:hover { background: var(--dk-red-bg); }

/* ── Stat cards — Prodex 4-up row. Clean white sheets, generous padding, a
   soft-tinted rounded-square icon on the left, then a muted label over a big
   tabular-mono numeral. A small delta chip appears only where it's real (the
   three money cards); restock shows a context sub-line instead. ───────────── */
.dkkpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.dkkpi__card {
	background: var(--dk-card-bg); border: 1px solid var(--dk-line);
	border-radius: var(--dk-radius-lg); padding: 20px; box-shadow: var(--dk-elev-card), var(--dk-inset-hi);
	transition: box-shadow .2s ease, border-color .2s ease, transform .2s ease;
	display: flex; align-items: center; gap: 15px; min-height: 92px;
}
.dkkpi__card:hover { box-shadow: var(--dk-elev-2), var(--dk-inset-hi); border-color: var(--dk-scroll); }
.dkkpi__ico {
	width: 44px; height: 44px; border-radius: 12px; flex: 0 0 44px;
	display: inline-flex; align-items: center; justify-content: center;
	box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.04);
}
.dkkpi__ico[data-tone="amber"] { background: var(--dk-brand-50); color: var(--dk-brand-600); }
.dkkpi__ico[data-tone="green"] { background: var(--dk-green-50); color: var(--dk-green-600); }
.dkkpi__ico[data-tone="red"] { background: var(--dk-red-bg); color: var(--dk-red); }
.dkkpi__ico[data-tone="blue"] { background: var(--dk-blue-bg); color: var(--dk-blue); }
.dkkpi__text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dkkpi__label { font-size: 12px; font-weight: 500; color: var(--dk-muted); letter-spacing: 0.005em; }
.dkkpi__value {
	font-size: 27px; font-weight: 600; letter-spacing: -0.035em; color: var(--dk-ink);
	font-family: var(--dk-mono); font-variant-numeric: tabular-nums; line-height: 1.05; display: flex; align-items: baseline;
}
.dkkpi__value small { font-size: 12px; font-weight: 500; color: var(--dk-muted); margin-right: 4px; letter-spacing: 0; }
.dkkpi__sub { font-size: 11.5px; color: var(--dk-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dkkpi__delta {
	display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600;
	white-space: nowrap; font-family: var(--dk-mono); font-variant-numeric: tabular-nums;
}
.dkkpi__delta small { font-family: var(--dk-sans); font-weight: 500; color: var(--dk-muted); font-size: 11px; letter-spacing: 0; }
.dkkpi__delta[data-dir="up"] { color: var(--dk-green); }
.dkkpi__delta[data-dir="down"] { color: var(--dk-red); }

/* Main split — chart (wide) + donut (narrow) */
.dkgrid-main { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 18px; align-items: stretch; }
/* Bottom split — the 3-column "Recent activity" row (Recent sales / Stock
   movements / Top customers), even thirds. */
.dkgrid-bottom { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; align-items: stretch; }

/* Cards — a hair-off-white sheet on layered elevation with a fine top highlight. */
.dkcard { background: var(--dk-surface-tint); border: 1px solid var(--dk-line); border-radius: var(--dk-radius); box-shadow: var(--dk-elev-card), var(--dk-inset-hi); }
.dkcard__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 15px 18px 13px; border-bottom: 1px solid var(--dk-line-soft); }
.dkcard__title { font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; color: var(--dk-ink); }
.dkcard__sub { font-size: 12px; color: var(--dk-muted); margin-top: 3px; letter-spacing: 0.005em; }
.dkcard__head-right { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.dkcard__count {
	display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 20px; padding: 0 7px;
	border-radius: 999px; background: var(--dk-chip-bg); color: var(--dk-chip-fg);
	font-size: 11.5px; font-weight: 600; font-family: var(--dk-mono);
}
.dkcard__link { font-size: 12.5px; font-weight: 500; color: var(--dk-muted); text-decoration: none; white-space: nowrap; transition: color .12s ease; }
.dkcard__link:hover { color: var(--dk-brand-ink); text-decoration: none; }
.dkcard__body { padding: 16px 18px; }
.dkcard__body--flush { padding: 6px 22px 10px; }

/* ── Sales bar chart — rounded amber columns over a faint quartered y-grid.
   The last column ("today") is emphasized with the deep-amber gradient + a soft
   ring; other days sit in a lighter amber. Zero-sales days show a 3px baseline
   nub so the week's shape stays legible without faking volume. Each bar is a
   focusable button carrying a hover/focus tooltip with the day's full RWF. ── */
.dkchart__legend { display: inline-flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.dkchart__key { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--dk-muted); font-weight: 500; }
.dkchart__dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.dkchart__dot--reg { background: var(--dk-brand-200); }
.dkchart__dot--today { background: var(--dk-brand-600); }

.dkbars { position: relative; height: 206px; padding-left: 46px; }
.dkbars__grid { position: absolute; left: 46px; right: 2px; top: 0; bottom: 0; pointer-events: none; }
.dkbars__gl { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--dk-chart-grid); }
.dkbars__gl.is-base { border-top-style: solid; border-color: var(--dk-line); }
.dkbars__yl { position: absolute; left: -46px; top: -0.62em; width: 40px; text-align: right; font-size: 10px; font-weight: 500; color: var(--dk-muted); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; }
.dkbars__cols { position: relative; height: 100%; display: flex; align-items: flex-end; gap: 4%; }
.dkbars__col { flex: 1 1 0; height: 100%; display: flex; align-items: flex-end; justify-content: center; min-width: 0; }
.dkbars__bar {
	position: relative; width: 100%; max-width: 46px; border: 0; padding: 0; cursor: pointer;
	background: linear-gradient(180deg, var(--dk-brand-200) 0%, var(--dk-brand) 100%);
	border-radius: 7px 7px 3px 3px; transition: filter .14s ease, transform .14s ease;
}
.dkbars__bar.is-today {
	background: var(--dk-grad-brand-deep);
	box-shadow: 0 4px 12px -4px rgba(217, 119, 6, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.dkbars__bar.is-zero {
	background: var(--dk-scroll); border-radius: 3px; cursor: default;
}
.dkbars__bar:not(.is-zero):hover { filter: brightness(1.05); transform: translateY(-1px); }
.dkbars__tip {
	position: absolute; left: 50%; bottom: calc(100% + 9px); transform: translateX(-50%); white-space: nowrap; z-index: 4;
	background: var(--dk-ink); color: var(--dk-white); border-radius: 9px; padding: 7px 11px; box-shadow: var(--dk-elev-3);
	opacity: 0; visibility: hidden; transition: opacity .14s ease; pointer-events: none;
	display: flex; flex-direction: column; gap: 1px; text-align: center;
}
.dkbars__tip::after { content: ""; position: absolute; left: 50%; top: 100%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--dk-ink); }
/* Near-ceiling bars flip the tooltip below the bar top so it never clips out of
   the card; the arrow flips to point up from the tooltip's top edge. */
.dkbars__bar.is-tall .dkbars__tip { bottom: auto; top: 8px; }
.dkbars__bar.is-tall .dkbars__tip::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--dk-ink); }
.dkbars__bar:hover .dkbars__tip, .dkbars__bar:focus-visible .dkbars__tip { opacity: 1; visibility: visible; }
.dkbars__tip-day { font-size: 10px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: rgba(255,255,255,0.72); }
.dkbars__tip-val { font-size: 12.5px; font-weight: 600; font-family: var(--dk-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.dkbars__xaxis { display: flex; gap: 4%; margin: 11px 0 0 46px; }
.dkbars__xl { flex: 1 1 0; text-align: center; font-size: 11px; color: var(--dk-muted); font-weight: 500; }
.dkbars__xl.is-today { color: var(--dk-brand-ink); font-weight: 600; }
.dkchart__foot { display: flex; align-items: baseline; gap: 16px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--dk-line-soft); flex-wrap: wrap; }
.dkchart__foot-total { font-size: 15px; font-weight: 600; color: var(--dk-ink); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.dkchart__foot-total small { font-family: var(--dk-sans); font-weight: 500; color: var(--dk-muted); font-size: 11.5px; margin-left: 6px; letter-spacing: 0; }
.dkchart__foot-note { margin-left: auto; font-size: 11.5px; color: var(--dk-muted); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── Payment mix — a refined donut with the collected total in the centre over
   a rich legend list: a coloured dot + method name on the left, the RWF amount
   and a bold % on the right (the Prodex "Top Categories" pattern). ── */
.dkmix__chart { position: relative; width: 150px; height: 150px; margin: 4px auto 22px; }
.dkmix__ring { display: block; filter: drop-shadow(0 4px 10px rgba(15, 23, 42, 0.06)); }
.dkmix__track { stroke: var(--dk-line-soft); }
.dkmix__seg { transition: stroke-width .18s ease; }
.dkmix__center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; pointer-events: none; }
.dkmix__center-val { font-size: 18px; font-weight: 600; letter-spacing: -0.02em; color: var(--dk-ink); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; line-height: 1.02; }
.dkmix__center-label { font-size: 10px; font-weight: 500; color: var(--dk-muted); margin-top: 4px; }
.dkmix__legend { display: flex; flex-direction: column; }
.dkmix__row { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; column-gap: 12px; padding: 11px 2px; }
.dkmix__row + .dkmix__row { border-top: 1px solid var(--dk-line-soft); }
.dkmix__dot { width: 11px; height: 11px; border-radius: 4px; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.08); }
.dkmix__name { color: var(--dk-ink-soft); font-weight: 500; font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dkmix__amt { color: var(--dk-muted); font-weight: 500; font-family: var(--dk-mono); font-variant-numeric: tabular-nums; font-size: 12.5px; white-space: nowrap; }
.dkmix__pct { color: var(--dk-ink); font-weight: 700; font-family: var(--dk-mono); font-variant-numeric: tabular-nums; font-size: 13px; min-width: 42px; text-align: right; }

/* ── Recent activity — a feed of rows: a soft-tinted icon circle, the customer
   name + time, and a status pill (payment method / Return) on the right. ── */
.dkactivity__list { display: flex; flex-direction: column; }
.dkactivity__row { display: flex; align-items: center; gap: 13px; padding: 12px; margin: 0 -12px; border-radius: 10px; transition: background .12s ease; }
.dkactivity__row + .dkactivity__row { border-top: 1px solid var(--dk-line-soft); }
.dkactivity__row:hover { background: var(--dk-row-hover); }
.dkactivity__row:hover + .dkactivity__row { border-top-color: transparent; }
.dkactivity__ico {
	width: 38px; height: 38px; border-radius: 50%; flex: 0 0 38px; background: var(--dk-brand-50); color: var(--dk-brand-600);
	display: inline-flex; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.04);
}
.dkactivity__ico--return { background: var(--dk-red-bg); color: var(--dk-red); }
/* A third tone for the "Stock movements" column's Transfer rows (neither the
   default amber "incoming" read nor the red "removed" read fits a same-shop
   move) — reuses the KPI strip's existing blue tone, not a new hue. */
.dkactivity__ico--transfer { background: var(--dk-blue-bg); color: var(--dk-blue); }
.dkactivity__body { flex: 1; min-width: 0; }
/* display:block is load-bearing: in CashBankPage the name is a <span> (inline by
   default), and overflow/ellipsis/white-space are all inert on an inline box — the
   label renders at full width and spills onto the right-aligned amount at ≤390px.
   Today.vue's sales rows override this with the more-specific .dktoday__sales
   .dkactivity__name (display:flex), so they are unaffected. */
.dkactivity__name { display: block; font-size: 13.5px; font-weight: 600; color: var(--dk-ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dkactivity__meta { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--dk-muted); margin-top: 2px; }
.dkactivity__meta svg { color: var(--dk-muted); flex: 0 0 auto; }
.dkactivity__right { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; flex: 0 0 auto; }
.dkactivity__amount { flex: none; font-size: 14px; font-weight: 600; color: var(--dk-ink); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; white-space: nowrap; text-align: right; }
.dkactivity__amount--return { color: var(--dk-red); }
.dkmix__skel { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.dkmix__skel-legend { width: 100%; display: flex; flex-direction: column; gap: 10px; }

/* Status pills — reused by the activity feed and the table. */
.dkpill { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; white-space: nowrap; letter-spacing: 0.005em; }
.dkpill--paid { background: var(--dk-green-50); color: var(--dk-green); box-shadow: inset 0 0 0 1px var(--dk-green-line); }
.dkpill--return { background: var(--dk-red-bg); color: var(--dk-red); box-shadow: inset 0 0 0 1px var(--dk-red-line); }

/* Initial-letter chip — used by the "Needs attention" strip below. (The 3-col
   "Recent activity" row layout it used to share with a data-table version of
   this same content now reuses .dkactivity__* above instead; the table markup
   itself is retired, but this chip lives on for the attention strip's rows.) */
.dktable__init {
	width: 28px; height: 28px; border-radius: 8px; flex: 0 0 28px; background: var(--dk-hover-bg); color: var(--dk-ink-soft);
	display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 650; box-shadow: inset 0 0 0 1px var(--dk-line);
}
.dktable__init--return { background: var(--dk-red-bg); color: var(--dk-red); box-shadow: inset 0 0 0 1px var(--dk-red-line); }
.dktable__init--warn { background: var(--dk-brand-50); color: var(--dk-brand-ink); box-shadow: inset 0 0 0 1px var(--dk-brand-200); }

/* ── Needs attention — a flat panel (not a bordered-header card) listing the
   items list_stock_levels(low_only=1) returns: an initial chip, the item name
   + a status line, and the on-hand quantity right-aligned with its unit. ── */
.dkattn { background: var(--dk-card-bg); border: 1px solid var(--dk-line); border-radius: var(--dk-radius); box-shadow: var(--dk-elev-card), var(--dk-inset-hi); padding: 17px 18px; }
.dkattn__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.dkattn__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 11px; margin-top: 14px; }
.dkattn__item { border: 1px solid var(--dk-line); border-radius: var(--dk-radius); padding: 11px 12px; display: flex; align-items: center; gap: 10px; background: var(--dk-surface-tint); }
.dkattn__body { min-width: 0; flex: 1; }
.dkattn__name { font-size: 13px; font-weight: 600; color: var(--dk-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dkattn__sub { font-size: 11px; color: var(--dk-muted); margin-top: 1px; }
.dkattn__q { flex: 0 0 auto; text-align: right; }
.dkattn__q b { display: block; font-size: 14px; font-weight: 700; color: var(--dk-brand-ink); font-family: var(--dk-mono); font-variant-numeric: tabular-nums; }
.dkattn__q b.dkattn__q--out { color: var(--dk-red); }
.dkattn__q span { display: block; font-size: 10.5px; color: var(--dk-muted); }
.dkattn__empty { padding: 18px 4px 4px; text-align: center; color: var(--dk-muted); font-size: 12.5px; }

/* Empty / error states inside cards — deliberate, not broken: a framed glyph
   disc, a clear line, and a single amber CTA. Near-zero data reads as calm. */
.dkempty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 34px 12px; color: var(--dk-muted); }
.dkempty__icon { color: var(--dk-faint); margin-bottom: 14px; padding: 12px; border-radius: 50%; background: var(--dk-hover-bg); box-shadow: inset 0 0 0 1px var(--dk-line-soft); }
.dkempty__title { font-size: 14px; font-weight: 600; color: var(--dk-ink-soft); }
.dkempty__sub { font-size: 12.5px; margin-top: 4px; line-height: 1.5; max-width: 34ch; }
.dkempty__cta {
	display: inline-block; margin-top: 16px; font-size: 12.5px; font-weight: 600; color: var(--dk-brand-ink);
	text-decoration: none; padding: 8px 18px; border-radius: 999px; border: 1px solid var(--dk-brand-200); background: var(--dk-brand-50);
	transition: background .12s ease, border-color .12s ease;
}
.dkempty__cta:hover { background: var(--dk-brand-100); border-color: var(--dk-brand); text-decoration: none; }

/* Skeletons */
.is-skeleton { pointer-events: none; }
.dkskel {
	background: linear-gradient(100deg, var(--dk-skeleton) 30%, var(--dk-skeleton-shine) 50%, var(--dk-skeleton) 70%);
	background-size: 220% 100%; animation: dkshimmer 1.3s ease-in-out infinite; border-radius: 8px; display: block;
}
@keyframes dkshimmer { 0% { background-position: 120% 0; } 100% { background-position: -20% 0; } }
.dkkpi__card.is-skeleton .dkskel--kpiico { width: 44px; height: 44px; border-radius: 12px; flex: 0 0 44px; }
.dkkpi__card.is-skeleton .dkkpi__text { gap: 8px; }
.dkkpi__card.is-skeleton .dkskel--label { width: 76px; height: 10px; }
.dkkpi__card.is-skeleton .dkskel--value { width: 108px; height: 20px; }
.dkkpi__card.is-skeleton .dkskel--sub { width: 60px; height: 10px; }
.dkcard.is-skeleton .dkskel--chart { width: 100%; height: 240px; }
.dkcard.is-skeleton .dkskel--ring { width: 150px; height: 150px; border-radius: 50%; margin: 4px auto 22px; }
.dkcard.is-skeleton .dkskel--row { width: 100%; height: 14px; margin: 9px 0; }
.dkactivity__row--skel { align-items: center; }
.dkskel--avatar { width: 38px; height: 38px; border-radius: 50%; flex: 0 0 38px; }
.dkskel--line { flex: 1; height: 12px; }
.dkskel--amt { width: 64px; height: 12px; flex: 0 0 auto; }

/* ============================ Focus states ============================ */
.dksb__link:focus-visible, .dksb__desk:focus-visible, .dksb__logout:focus-visible,
.dksb__collapse:focus-visible, .dksb__mark:focus-visible,
.dkchip:focus-visible, .dkmenu__item:focus-visible, .dkapp-top__menu:focus-visible,
.dklist__row:focus-visible, .dksec__card:focus-visible,
.dkbtn:focus-visible, .dkcard__link:focus-visible, .dkbars__bar:focus-visible,
.dkempty__cta:focus-visible, .dktoday__err button:focus-visible {
	outline: 2px solid var(--dk-brand); outline-offset: 2px; border-radius: 12px;
}
.dkbars__bar:focus-visible { border-radius: 7px; }
/* Hero quick-action pills sit ON the dark hero wash — the plain amber outline
   above would nearly disappear against the deep-brown end of the gradient, so
   these get a cream ring instead (still 2px/2px-offset, same treatment,
   different colour so it's visible over both ends of the hero gradient). */
.dkqpill:focus-visible { outline: 2px solid var(--dk-hero-ink); outline-offset: 2px; border-radius: 999px; }
/* Search keeps its custom focus ring (box-shadow on :focus, which also fires
   for keyboard focus) — no default outline needed on top of it. */
.dksearch input:focus-visible { box-shadow: 0 0 0 4px var(--dk-brand-ring); border-color: var(--dk-brand); }

/* ============================ Mobile ============================ */
@media (max-width: 980px) {
	.dkgrid-main { grid-template-columns: 1fr; }
	.dkgrid-bottom { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.dkkpi { grid-template-columns: repeat(2, 1fr); }
	.dkattn__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
	.dkgrid-bottom { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
	.dkkpi { grid-template-columns: 1fr; }
	.dkquick { width: 100%; }
	.dkqpill { flex: 1 1 auto; justify-content: center; }
	.dkchart__foot-note { margin-left: 0; width: 100%; }
}
@media (max-width: 880px) {
	.dksb { transform: translateX(-100%); transition: transform .2s ease; box-shadow: 0 0 40px rgba(15,23,42,.15); width: var(--dk-sb-w); }
	.dksb__collapse { display: none; }
	.dkapp-layout.is-collapsed .dksb { width: var(--dk-sb-w); }
	.dksb.is-open { transform: translateX(0); }
	.dkapp-main, .dkapp-layout.is-collapsed .dkapp-main { margin-left: 0; }
	.dkapp-top { padding: 11px 16px; }
	.dkapp-top__menu { background: none; border: 0; color: var(--dk-ink); display: inline-flex; padding: 4px; }
	.dkapp-top__brand { display: inline-flex; }
	.dkapp-top__brand img { height: 24px; }
	.dksearch { display: none; }
	.dkapp-content { padding: 18px 16px 64px; }
}
@media (max-width: 480px) {
	.dkhero { padding: 20px 18px 20px; }
	.dkhero__greet { font-size: 21px; }
	.dkgrid-bottom, .dkattn__grid { grid-template-columns: 1fr; }
	.dkkpi { grid-template-columns: 1fr; gap: 12px; }
	.dkkpi__value { font-size: 25px; }
	.dkbars { height: 176px; }
	.dkcard__body { padding: 16px; }
	.dkcard__head { padding: 15px 16px; }
}

/* Motion, restrained — honour a user's reduced-motion preference across every
   dashboard transition/animation added above. */
@media (prefers-reduced-motion: reduce) {
	.dkkpi__card, .dkbtn, .dkbtn svg, .dkbars__bar, .dkbars__tip,
	.dkactivity__row, .dkqpill, .dkmix__seg {
		transition: none !important;
	}
	.dkkpi__card:hover, .dkbtn--primary:hover, .dkbars__bar:not(.is-zero):hover, .dkqpill:hover { transform: none; }
	.dkskel { animation-duration: 2.6s; }
}
