/*
 * BizzFlow design tokens.
 *
 * Every colour, size and shadow in the product resolves from here. Nothing
 * downstream may write a raw hex value — that is what keeps light and dark
 * honest, and what makes a rebrand a single-file edit. This file has now been
 * rebranded three times on that promise.
 *
 * The palette is burnt orange on warm off-white. Five things follow from that:
 *
 *  - **Light is the reference design.** Business software is read in daylight,
 *    printed, and looked at for eight hours; warm white is easier to sit with
 *    than a dark canvas. Dark mode is a companion, not the starting point.
 *
 *  - **Neutrals are warm.** A cool grey next to orange reads as two unrelated
 *    design decisions. Every neutral here carries a little brown.
 *
 *  - **Orange needs two tokens, not one.** The bright orange the brand is built
 *    on (--bzf-brand-500) carries white text at only 3.3:1, which fails AA for
 *    button labels. So filled things use --bzf-brand-solid — a deeper burnt
 *    orange that clears 4.6:1 on white — and brand-coloured *text* on the canvas
 *    uses --bzf-brand-600, deeper again. The bright orange stays for borders,
 *    focus rings, hover states and washes, where 3:1 is the bar. Never put
 *    --bzf-on-brand on anything but a solid brand fill.
 *
 *  - **Green is no longer the brand — it is money.** Success, profit and "paid"
 *    stay green precisely because the brand left. Green now means one thing.
 *
 *  - **The sidebar has its own tokens.** It is white here, but it keeps its own
 *    set: it is the one surface that must not follow the theme flip blindly.
 */

:root,
.bizzflow-body {
	/* ------------------------------------------------------------------
	   Brand — burnt orange
	   50-200 are washes for selected rows and quiet backgrounds. 300-500 are
	   borders, focus and accents. 600-900 are INK: brand-coloured text.
	   ------------------------------------------------------------------ */
	--bzf-brand-50:  #FFF2E9;
	--bzf-brand-100: #FFE2CE;
	--bzf-brand-200: #FDC49E;
	--bzf-brand-300: #FA9D64;
	--bzf-brand-400: #F57C33;
	--bzf-brand-500: #EA6412;
	--bzf-brand-600: #B34309;
	--bzf-brand-700: #8E3507;
	--bzf-brand-800: #6B2705;
	--bzf-brand-900: #4A1B03;

	/* Solid fills, and the only text colour allowed on top of them. */
	--bzf-brand-solid:       #C94C0C;
	--bzf-brand-solid-hover: #A93E09;
	--bzf-on-brand:          #FFFFFF;

	/* Accent for money-positive states — growth, profit, paid. Stays green. */
	--bzf-accent-400: #4E9A63;
	--bzf-accent-500: #2F7D46;
	--bzf-accent-600: #1F5E33;

	/* ------------------------------------------------------------------
	   Sidebar — white, with an orange wash on the active row
	   Its own set because it does not flip with the rest of the interface.
	   ------------------------------------------------------------------ */
	--bzf-sidebar-bg:        #FFFFFF;
	--bzf-sidebar-border:    #E6E6EA;
	--bzf-sidebar-text:      #5E6068;
	/* Same correction as --bzf-text-subtle: the sidebar keeps its own tokens,
	   so it needed the same fix separately or the tagline stayed at 3.35:1.
	   Darkened again in 1.44.0: #6F717A measured 4.48:1 once the sidebar became
	   GLASS, because the real background is the composite, not #FFFFFF. */
	--bzf-sidebar-text-soft: #64666E;
	--bzf-sidebar-active-bg: #FFF2E9;
	--bzf-sidebar-active-fg: #1F2024;
	--bzf-sidebar-hover-bg:  #F3F3F5;

	/* ------------------------------------------------------------------
	   Semantic status
	   Paired with an icon or label everywhere — never colour alone, so the
	   meaning survives colour-vision deficiency and greyscale printing.

	   Danger is pushed toward crimson and warning toward gold on purpose: a
	   brick red and an amber both sit too close to a burnt-orange brand to be
	   read as different states at a glance.
	   ------------------------------------------------------------------ */
	--bzf-success:    #2F7D46;
	--bzf-success-bg: #DFF3E5;
	--bzf-success-fg: #1F5E33;

	--bzf-warning:    #C79A1F;
	--bzf-warning-bg: #FCF3DA;
	--bzf-warning-fg: #7A5A0E;

	--bzf-danger:     #C22B3E;
	--bzf-danger-bg:  #FCE9EC;
	--bzf-danger-fg:  #971F2E;

	--bzf-info:       #3E7773;
	--bzf-info-bg:    #E2EFEE;
	--bzf-info-fg:    #2C5B58;

	/* ------------------------------------------------------------------
	   Surfaces — light
	   ------------------------------------------------------------------ */
	/*
	 * Neutrals cooled on 2026-08-15, at the owner's request for a better
	 * combination.
	 *
	 * They were warm cream (#F7F5F2, borders #E7E1D9). Warm neutrals plus a
	 * burnt-orange brand meant every surface sat on the same side of the
	 * colour wheel, and the whole product read brown — the orange stopped
	 * being an accent because nothing contrasted with it. These are near
	 * neutral with a trace of warmth, so the brand is the only warm thing on
	 * screen and therefore reads as the accent. The brand itself is untouched.
	 */
	--bzf-canvas:      #F6F6F7;   /* Page behind everything */
	--bzf-surface:     #FFFFFF;   /* Cards, panels */
	--bzf-surface-2:   #F4F1ED;   /* Nested / hover */
	--bzf-surface-3:   #EBE6E0;   /* Pressed, table headers */
	--bzf-overlay:     rgba(35, 28, 24, .45);

	--bzf-border:      #E3E3E6;
	--bzf-border-soft: #EDEDF0;
	--bzf-border-strong: #C9C9CF;

	/* ------------------------------------------------------------------
	   Text — light
	   ------------------------------------------------------------------ */
	--bzf-text:        #1F2024;
	--bzf-text-muted:  #5E6068;   /* 6.2:1 on canvas */
	/*
	 * Darkened until it passed. A sweep of every text node found nine places
	 * using this as real copy at 11.5px — the sidebar tagline, the account
	 * role, menu section labels, field hints — where the old #8A8C95 measured
	 * 3.35:1. The token was wrong, not the nine rules, so the token moved.
	 */
	--bzf-text-subtle: #6F717A;
	--bzf-text-invert: #FFFFFF;

	/*
	 * The free plan's locked menu rows, and nothing else.
	 *
	 * The owner asked for these to read as dimmer than the rest of the menu —
	 * "taky feel ay band haii". They were on --bzf-text-muted, which is correct
	 * for body copy but far too present for thirteen rows you cannot open.
	 *
	 * Its own token rather than a change to --bzf-text-muted, because that one
	 * is real copy in nine other places (field hints, the account role, table
	 * captions) and dimming all of them was not what was asked for.
	 *
	 * How far it can go is a measured number, not a taste one, and the surface
	 * is NOT #FFFFFF: the sidebar is glass — rgba(255,255,255,.62) over the
	 * --bzf-ground gradient — so the real background is the composite. Sampled
	 * down the sidebar (its top catches the orange radial at 6% -8%) that is
	 * #FCF4EE, #FAFAFC, #F8F7FA, plus #F3F3F5 on a hovered row. Worst of those:
	 *
	 *   #55575F  6.50   what these rows were on (--bzf-text-muted)
	 *   #62646D  5.32
	 *   #6A6C74  4.73   <- this. AA needs 4.50, so 0.23 of headroom.
	 *   #6E7079  4.45   fails, on the hovered row
	 *
	 * In 1.45.0 these rows measured 2.31:1 and five releases of contrast sweeps
	 * never saw it, because desktop sweeps ran the paid plan (which renders no
	 * sidebar) and phone sweeps hide the labels. Do not push this lighter
	 * without re-running the sweep on the FREE plan at desktop width.
	 */
	--bzf-nav-locked:  #6A6C74;

	/* ------------------------------------------------------------------
	   The app bar — 1.49.0
	   ------------------------------------------------------------------
	   One dark bar replaced the free plan's sidebar AND the paid plan's two
	   stacked light rows. It is chrome, not a dark theme: the page under it
	   stays light, and rule 9 is untouched.

	   NOT the reference product's navy. A blue bar would put a second brand
	   colour into a product that has just been moved off blue and onto burnt
	   orange, and the two would fight for the eye. This is the warm near-black
	   the dark block already uses for the sidebar, so the orange reads as a
	   relative of the ground rather than a clash with it.

	   Measured against #1B1612, AA floor 4.50 for normal text:

	     --bzf-appbar-fg      #F2EDE7   15.42:1
	     --bzf-appbar-dim     #ADA298    7.18:1
	     --bzf-appbar-locked  #948A80    5.30:1

	   And the active pill: white on --bzf-brand-solid is 4.64:1 and the pill
	   itself sits at 3.87:1 against the bar. White on --bzf-brand-500 is only
	   3.32:1, which FAILS — do not "brighten" the pill to brand-500.
	   ------------------------------------------------------------------ */
	/*
	 * The bar's height, as a token.
	 *
	 * Anything that hangs off the bar has to know how tall it is, and hardcoding
	 * it is how the support panel ended up tucked 8px UNDERNEATH the bar: it
	 * said `top: 64px`, which was right for the old top bar and wrong the moment
	 * this one became 72.
	 */
	--bzf-appbar-h:       72px;
	--bzf-appbar-h-phone: 64px;

	--bzf-appbar-bg:     #1B1612;
	--bzf-appbar-raised: #221B16;
	--bzf-appbar-fg:     #F2EDE7;
	--bzf-appbar-dim:    #ADA298;
	--bzf-appbar-locked: #948A80;

	/* ------------------------------------------------------------------
	   Elevation — five rungs, and each one means a height

	   This used to be "soft only, business software should look printed". That
	   read as flat: every card carried a 4%-opacity shadow AND a border, so the
	   border did all the work and the page had no depth at all — white
	   rectangles outlined on a white-ish canvas.

	   The border was the crutch. Now the shadow separates the card from the
	   canvas and the border comes off, which is what gives a layered surface.
	   Pick the rung by how far off the page the thing is meant to sit:

	     xs  flush     inputs, chips, a pressed button
	     sm  resting   cards, panels, table wrappers — the default
	     md  raised    a card under the cursor
	     lg  lifted    dropdowns, popovers
	     xl  floating  modals, toasts — things over a scrim

	   Warm-tinted rather than neutral black: a grey shadow under a white card on
	   a warm canvas turns the edge faintly blue.
	   ------------------------------------------------------------------ */
	--bzf-shadow-xs: 0 1px 2px rgba(38, 32, 25, .05);
	--bzf-shadow-sm: 0 1px 3px rgba(38, 32, 25, .09), 0 1px 2px -1px rgba(38, 32, 25, .06);
	--bzf-shadow:    0 4px 10px -2px rgba(38, 32, 25, .10), 0 2px 5px -2px rgba(38, 32, 25, .07);
	--bzf-shadow-md: 0 10px 20px -6px rgba(38, 32, 25, .13), 0 4px 9px -4px rgba(38, 32, 25, .09);
	--bzf-shadow-lg: 0 16px 32px -10px rgba(38, 32, 25, .17), 0 6px 14px -6px rgba(38, 32, 25, .11);
	--bzf-shadow-xl: 0 24px 48px -12px rgba(38, 32, 25, .22), 0 10px 20px -8px rgba(38, 32, 25, .14);
	/*
	 * Brand channels, so translucent brand colours can be built in CSS.
	 *
	 * rgba() cannot take a hex variable, so the focus ring and the brand glow
	 * used to hardcode `rgba(234, 100, 18, …)`. A shop that picked blue got a
	 * blue button with an ORANGE focus ring around it, which is exactly the kind
	 * of leftover that makes customisation look broken. applyBranding() sets
	 * this alongside the hex tokens.
	 */
	--bzf-brand-rgb: 234, 100, 18;

	--bzf-shadow-brand: 0 4px 14px -2px rgba(var(--bzf-brand-rgb), .32);

	/* Focus ring — one definition, used everywhere. */
	--bzf-ring: 0 0 0 3px rgba(var(--bzf-brand-rgb), .26);

	/* ------------------------------------------------------------------
	   Geometry — cards 12-18px, per the brand spec.
	   ------------------------------------------------------------------ */
	--bzf-radius-xs: 5px;
	--bzf-radius-sm: 8px;
	--bzf-radius:    10px;
	--bzf-radius-lg: 14px;
	--bzf-radius-xl: 18px;
	--bzf-radius-full: 999px;

	/* 4px rhythm. Everything spatial is a multiple of this. */
	--bzf-1: 4px;   --bzf-2: 8px;   --bzf-3: 12px;  --bzf-4: 16px;
	--bzf-5: 20px;  --bzf-6: 24px;  --bzf-7: 28px;  --bzf-8: 32px;
	--bzf-10: 40px; --bzf-12: 48px; --bzf-16: 64px; --bzf-20: 80px;

	/* ------------------------------------------------------------------
	   Typography

	   One sans, two voices. Headings were Georgia until 2026-08-15; a serif
	   title over a data table reads like a newspaper column, and the owner
	   asked for something cleaner. Headings now differ from body by WEIGHT and
	   TRACKING rather than by family, which is what modern product interfaces
	   do and what keeps a 21px title and a 13px label looking related.

	   Inter first because it is the reference face for this style and is
	   installed on a lot of machines; "Segoe UI Variable Text" next because
	   this product's shopkeepers are overwhelmingly on Windows and it is the
	   best thing already on their machine.

	   STILL SYSTEM FONTS ONLY. No webfont request: the theme ships as a zip
	   with no build step, and a till that waits on fonts.googleapis.com is a
	   till that stops working when the shop's connection does.

	   "Noto Nastaliq Urdu" stays in the stack — it is the only reason Urdu
	   renders correctly rather than as disconnected Arabic glyphs.
	   ------------------------------------------------------------------ */
	--bzf-font: Inter, "Segoe UI Variable Text", "Segoe UI", system-ui,
		-apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial,
		"Noto Sans", "Noto Nastaliq Urdu", sans-serif;

	/* Same family. The difference is made in app.css by weight and tracking. */
	--bzf-font-heading: Inter, "Segoe UI Variable Display", "Segoe UI Variable Text",
		"Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, Roboto, Arial,
		"Noto Sans", "Noto Nastaliq Urdu", sans-serif;

	/* Tabular figures so money columns align. Non-negotiable in a POS. */
	--bzf-font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
		"Liberation Mono", monospace;

	--bzf-text-xs:   11.5px;
	--bzf-text-sm:   12.5px;
	--bzf-text-base: 13.5px;
	--bzf-text-md:   15px;
	--bzf-text-lg:   17px;
	--bzf-text-xl:   21px;
	--bzf-text-2xl:  26px;
	--bzf-text-3xl:  32px;

	/* Serif headings need less negative tracking than a sans does. */
	--bzf-track-tight: -0.011em;
	--bzf-track-snug:  -0.005em;
	--bzf-track-wide:  0.04em;

	/* ------------------------------------------------------------------
	   Motion
	   Fast enough to feel instant, slow enough to be perceived.
	   ------------------------------------------------------------------ */
	--bzf-ease: cubic-bezier(.32, .72, 0, 1);
	--bzf-fast: 120ms var(--bzf-ease);
	--bzf-base: 180ms var(--bzf-ease);
	--bzf-slow: 280ms var(--bzf-ease);

	/* Layout constants the JS also relies on. */
	--bzf-sidebar-w: 248px;
	--bzf-topbar-h: 68px;
}

/* ------------------------------------------------------------------
   Dark
   A companion, not the reference — nothing in the shipped app reaches it, since
   the theme toggle was removed. It is kept correct so a future toggle is a
   feature rather than a rewrite.

   Surfaces get lighter as they rise, matching how physical materials catch
   light; borders lighten too, or panels lose their edges. The brand ink flips:
   the deep burnt orange that reads on off-white disappears on a dark canvas, so
   the bright oranges take over.
   ------------------------------------------------------------------ */

.bizzflow-body[data-theme="dark"],
.bizzflow-app[data-theme="dark"] {
	--bzf-canvas:      #16120F;
	--bzf-surface:     #1E1915;
	--bzf-surface-2:   #27201B;
	--bzf-surface-3:   #332A23;
	--bzf-overlay:     rgba(0, 0, 0, .66);

	--bzf-border:      #362D26;
	--bzf-border-soft: #2A231D;
	--bzf-border-strong: #4A3E34;

	--bzf-text:        #F2EDE7;
	--bzf-text-muted:  #ADA298;
	--bzf-text-subtle: #7A7066;
	/* One step down from text-muted, matching the light side's intent. Unswept:
	   nothing in the shipped app reaches dark, so this is kept plausible rather
	   than measured. Measure it the day a theme toggle returns. */
	--bzf-nav-locked:  #948A80;

	/* Washes become dark tints; the ink becomes the readable bright orange. */
	--bzf-brand-50:  #2A1A10;
	--bzf-brand-100: #351F12;
	--bzf-brand-200: #472817;
	--bzf-brand-300: #6B3A1D;
	--bzf-brand-400: #C25A1A;
	--bzf-brand-500: #EA6412;
	--bzf-brand-600: #F98B45;
	--bzf-brand-700: #FFAE79;

	/* The fill stays a real orange so a primary button looks the same colour in
	   both themes; only what sits around it changes. */
	--bzf-brand-solid:       #C94C0C;
	--bzf-brand-solid-hover: #E05A11;
	--bzf-on-brand:          #FFFFFF;

	/* The sidebar goes dark with everything else, keeping the orange wash. */
	--bzf-sidebar-bg:        #1B1612;
	--bzf-sidebar-border:    #322A23;
	--bzf-sidebar-text:      #ADA298;
	--bzf-sidebar-text-soft: #7A7066;
	--bzf-sidebar-active-bg: #351F12;
	--bzf-sidebar-active-fg: #FFFFFF;
	--bzf-sidebar-hover-bg:  #27201B;

	--bzf-success-bg: #16301F;
	--bzf-success-fg: #79C68F;
	--bzf-warning-bg: #332809;
	--bzf-warning-fg: #E3BC57;
	--bzf-danger-bg:  #35161C;
	--bzf-danger-fg:  #E88C97;
	--bzf-info-bg:    #16302E;
	--bzf-info-fg:    #6FB2AD;

	/* Dark surfaces separate by getting lighter as they rise, not by shadow — a
	   black shadow on a black canvas is invisible. The rungs still exist so the
	   same rules apply, they just do less of the work. */
	--bzf-shadow-xs: 0 1px 2px rgba(0, 0, 0, .45);
	--bzf-shadow-sm: 0 1px 3px rgba(0, 0, 0, .5), 0 1px 2px -1px rgba(0, 0, 0, .38);
	--bzf-shadow:    0 4px 10px -2px rgba(0, 0, 0, .5), 0 2px 5px -2px rgba(0, 0, 0, .4);
	--bzf-shadow-md: 0 10px 20px -6px rgba(0, 0, 0, .55), 0 4px 9px -4px rgba(0, 0, 0, .42);
	--bzf-shadow-lg: 0 16px 32px -10px rgba(0, 0, 0, .62), 0 6px 14px -6px rgba(0, 0, 0, .48);
	--bzf-shadow-xl: 0 24px 48px -12px rgba(0, 0, 0, .7), 0 10px 20px -8px rgba(0, 0, 0, .55);
	--bzf-shadow-brand: 0 4px 14px -2px rgba(234, 100, 18, .38);

	--bzf-ring: 0 0 0 3px rgba(234, 100, 18, .32);
}

/* ==================================================================
   Touch type scale
   ==================================================================

   The scale above is a DESKTOP scale — 13.5px body, 11.5px table headers —
   and it is deliberate density for a shopkeeper reading a full-width ledger
   on a monitor.

   On a phone it is the single biggest reason the product reads as a website
   rather than an app. Measured at 375px before this existed: every table
   header 11.5px, the account role 11.5px, the till's key hints 10.5px.

   Raised here as TOKENS rather than as rules, so every component follows
   without being touched one at a time — and so the desktop scale stays
   exactly as it was.

   `pointer: coarse`, not a width breakpoint: a 1024px tablet propped on a
   counter is read at arm's length; a 700px desktop window is not.
   ================================================================== */

@media (pointer: coarse) {
	:root,
	.bizzflow-body {
		--bzf-text-xs:   13px;
		--bzf-text-sm:   14px;
		--bzf-text-base: 15.5px;
		--bzf-text-md:   16.5px;
		--bzf-text-lg:   19px;
		--bzf-text-xl:   23px;
		--bzf-text-2xl:  28px;
		--bzf-text-3xl:  34px;
	}
}

/* ==================================================================
   Materials — the 1.37.0 redesign
   ==================================================================

   Two ideas, and the split between them is the whole design:

   GLASS is for CHROME — the top bar, the sidebar, the search field, filter
   chips, sheets and modals. Things that sit OVER content and should feel like
   a layer above it.

   SOLID is for anything carrying a number. Prices, totals, table rows, the
   Charge button. Translucency puts whatever is behind a figure into the figure,
   and this product's contrast is measured on every release — a value that
   changes with what it happens to be floating over cannot be measured at all.

   This is how iOS itself works: its nav bar and tab bar are materials, its
   primary buttons are not.
   ================================================================== */

:root,
.bizzflow-body {
	/*
	 * The ground.
	 *
	 * Glass is only glass if there is something behind it — a frosted pane on
	 * flat #FFFFFF is a grey rectangle, because the blur has nothing to pick
	 * up. So the canvas carries a warm-to-cool wash and two soft blooms.
	 *
	 * GRADIENTS, not blurred shapes. The Figma design draws the blooms as
	 * ellipses under a 200px blur; a 200px `filter: blur()` on a large element
	 * is one of the most expensive things a phone GPU can be asked for, and
	 * this runs on a shop's cheap Android. Radial gradients paint the same
	 * thing for free.
	 */
	--bzf-ground:
		radial-gradient(900px 520px at 6% -8%, rgba(234, 100, 18, .13) 0%, rgba(234, 100, 18, 0) 62%),
		radial-gradient(760px 480px at 96% 88%, rgba(47, 111, 208, .09) 0%, rgba(47, 111, 208, 0) 60%),
		linear-gradient(152deg, #F8F4F0 0%, #F3F1F6 55%, #ECE9F1 100%);

	/* The material. One opacity, one blur, one edge — used everywhere so the
	   chrome reads as a single pane of the same stuff. */
	--bzf-glass-bg:      rgba(255, 255, 255, .62);
	--bzf-glass-bg-2:    rgba(255, 255, 255, .74);
	--bzf-glass-edge:    rgba(255, 255, 255, .85);
	--bzf-glass-shadow:  0 1px 14px rgba(28, 28, 30, .06);

	/*
	 * 18px, not the 32–40px the mockup uses.
	 *
	 * Backdrop-blur cost scales with radius and with the area behind it. The
	 * sidebar and top bar are large and always on screen, so this is the one
	 * number in the design that is chosen for the till's hardware rather than
	 * for the screenshot.
	 */
	--bzf-glass-blur:    blur(18px);

	/*
	 * Where a browser has no backdrop-filter the panes fall back to nearly
	 * solid — see the @supports block in app.css. Frosted-but-not-blurred is
	 * just muddy, and a cashier reading through it is worse off than with a
	 * plain white bar.
	 */
	--bzf-glass-solid:   rgba(255, 255, 255, .94);
}

/*
 * Rounder, the way an app is rounder than a web page. The old ramp topped out
 * at 18px; cards and sheets now carry 20–28px, and pills stay pills.
 */
:root,
.bizzflow-body {
	--bzf-radius-xs: 6px;
	--bzf-radius-sm: 10px;
	--bzf-radius:    14px;
	--bzf-radius-lg: 20px;
	--bzf-radius-xl: 28px;
}

/*
 * Ink, re-tuned for the ground.
 *
 * These were derived against a flat #F6F6F7 canvas. The redesign put a
 * gradient underneath, whose dark end is #E8E5EE, and a sweep that composites
 * the glass down onto it found the muted greys landing at 4.32–4.48 against a
 * 4.5 requirement — the account role, the breadcrumb separator, the POS stock
 * line, the active settings tab.
 *
 * Darkened at the TOKEN, not at the nine rules that use it. That is the same
 * call the 1.21.0 notes record: when every failure shares one variable, the
 * variable is what was wrong.
 */
:root,
.bizzflow-body {
	--bzf-text-muted:  #55575F;
	--bzf-text-subtle: #62646D;
}
