/* Harbor admin UI — generated by scripts/build-admin-harbor.mjs; edit resources/css/admin-harbor/, never this file. */
/* ==== tokens.css ==== */
/* Design tokens — light theme on .hb-root, dark theme on .hb-root[data-theme="dark"].
   Change a value here and every screen follows.
   Ported 1:1 from Harbor b29e1fa (approved 22 Oct 2026) for the Laravel admin: every class carries the hb-
   prefix and every global selector is scoped to .hb-root, so this file cannot reach Bootstrap pages or other
   panels. scripts/build-admin-harbor.mjs concatenates the files in this order: tokens, base, components,
   layout, widgets, integration. */

/* ---------- 1. TOKENS ------------------------------------------------ */
.hb-root {
  --scrim: rgba(7, 24, 21, .45);   /* the dimmed page behind the phone sidebar drawer */
  /* surfaces */
  --c-bg: #eff2f1;            /* app background */
  --c-surface: #ffffff;       /* cards, sidebar, inputs */
  --c-surface-2: #f7f9f8;     /* table heads, search field */
  --c-sunken: #eaefed;        /* neutral fills, hover, tracks, skeleton */
  --c-canvas: #e1e6e4;        /* backdrop behind device mockups and spec boards */
  --c-line: #dee5e2;
  --c-line-strong: #bfcac5;   /* input borders, dashed drop zones */

  /* text */
  --c-text: #15241e;
  --c-text-2: #35473f;        /* nav items, secondary values */
  --c-text-muted: #54645d;    /* labels, help text (5.5:1 on bg) */
  --c-text-subtle: #586a62;   /* placeholders (≥ 4.5:1 on every light surface and tint; A4) */

  /* brand */
  --c-accent: #136050;        /* links, active text, focus */
  --c-accent-fill: #136050;   /* primary button fill */
  --c-accent-hover: #0f4f42;
  --c-accent-soft: #ddefe9;   /* active nav, soft badges */
  --c-accent-line: #b7ddd1;
  --c-accent-2: #7cbfac;      /* second chart series */
  --c-on-accent: #ffffff;
  --c-accent-tint: #f3f8f6;   /* unread / highlighted rows */

  /* fixed accents (same in both themes) */
  --c-stripe-1: #e9b44c;      /* hazard / pine stripe on sign-in, sign-up, error and print pages */
  --c-stripe-2: #0f4137;
  --c-control-line: #86968f;  /* checkbox / radio outlines, drag grips (≥ 3:1 non-text; A5) */
  --c-text-disabled: #909d98; /* text on disabled buttons and days */
  --c-ok-strong: #065f46;     /* text in success callouts */
  --c-info-strong: #1e40af;   /* text in info callouts */
  --c-info-line: #bfdbfe;     /* border of info callouts */
  --c-media-placeholder: #73847d;   /* stand-in for a photo in illustrations (same in both themes) */

  /* status tones: text / soft background / border / strong text */
  --c-ok: #047857;   --c-ok-soft: #dcf5ea;   --c-ok-line: #a7f3d0;
  --c-warn: #b45309; --c-warn-soft: #fef3e2; --c-warn-line: #fed7aa; --c-warn-strong: #92400e; --c-warn-tint: #fffaf2;
  --c-bad: #be123c;  --c-bad-soft: #ffe9ed;  --c-bad-line: #fecdd3;  --c-bad-strong: #9f1239; --c-bad-tint: #fff7f8; --c-bad-fill: #be123c; --c-bad-fill-hover: #9f1239;
  --c-info: #1d4ed8; --c-info-soft: #e5eeff;
  --c-neutral: #54645d; --c-neutral-soft: #eaefed;
  --c-purple: #6d28d9;  --c-purple-soft: #ede9fe;

  /* type */
  --font-sans: 'Readex Pro', 'Segoe UI', system-ui, sans-serif;
  --fs-2xs: 11px;  --fs-xs: 12px;  --fs-sm: 13px;  --fs-md: 14px;  --fs-lg: 16px;
  --fs-xl: 18px;   --fs-2xl: 20px; --fs-3xl: 24px; --fs-h1: 26px;  --fs-stat: 28px; --fs-display: 32px;
  --lh-tight: 1.3; --lh-body: 1.6;

  /* spacing (4px base) */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-7: 28px; --sp-8: 32px;

  /* radii */
  --r-xs: 2px; --r-sm: 3px; --r-md: 4px; --r-lg: 4px; --r-xl: 6px; --r-2xl: 8px; --r-pill: 999px;

  /* elevation */
  --sh-1: 0 1px 2px rgba(20,32,27,.08);
  --sh-2: 0 8px 22px rgba(20,32,27,.14);
  --sh-3: 0 14px 36px rgba(20,32,27,.2);
  --ring: 0 0 0 3px rgba(19,96,80,.22);

  /* control sizes */
  --h-sm: 32px; --h-md: 40px; --h-lg: 48px;
  --sidebar-w: 264px;

  /* UI scale: the whole app is zoomed by this factor (same result as browser zoom), so every size above
     shrinks together and the design keeps its proportions. Applied on html in base.css. 1 = as designed. */
  --ui-zoom: 1;
  --vh-full: calc(100vh / var(--ui-zoom));   /* a full screen height inside the zoomed page */
}
/* desktop renders at 90%; phones keep the designed size */
@media (min-width: 721px) { .hb-root { --ui-zoom: .9; } }

.hb-root[data-theme="dark"] {
  --c-bg: #0e1713; --c-surface: #15201b; --c-surface-2: #1a2722; --c-sunken: #1f2e28; --c-canvas: #090e0c;
  --c-line: #2a3d35; --c-line-strong: #6a8379;
  --c-text: #ebf2ef; --c-text-2: #c9d7d1; --c-text-muted: #9cafa7; --c-text-subtle: #8ea29a;
  --c-accent: #7cbfac; --c-accent-fill: #1a7a64; --c-accent-hover: #1e856d;
  --c-accent-soft: rgba(124,191,172,.13); --c-accent-line: rgba(124,191,172,.32); --c-accent-2: #7cbfac; --c-on-accent: #ffffff; --c-accent-tint: rgba(124,191,172,.06);
  --c-ok: #6ee7b7;   --c-ok-soft: rgba(16,185,129,.16);  --c-ok-line: rgba(16,185,129,.30);
  --c-warn: #fdba74; --c-warn-soft: rgba(249,115,22,.16); --c-warn-line: rgba(249,115,22,.30); --c-warn-strong: #fed7aa; --c-warn-tint: rgba(249,115,22,.07);
  --c-bad: #fda4af;  --c-bad-soft: rgba(244,63,94,.16);   --c-bad-line: rgba(244,63,94,.30);  --c-bad-strong: #fecdd3; --c-bad-tint: rgba(244,63,94,.08); --c-bad-fill: #be123c; --c-bad-fill-hover: #9f1239;
  --c-info: #93c5fd; --c-info-soft: rgba(59,130,246,.16);
  --c-neutral: #c9d7d1; --c-neutral-soft: rgba(161,161,170,.14);
  --c-purple: #c4b5fd;  --c-purple-soft: rgba(139,92,246,.16);
  /* decision: no shadows on dark — layers separate by border and surface step */
  --c-ok-strong: #a7f3d0; --c-info-strong: #bfdbfe; --c-info-line: rgba(59,130,246,.35);
  --c-stripe-2: #ebf2ef;   /* the stripe reads on dark pages */
  --ring: 0 0 0 3px rgba(124,191,172,.3);
  --sh-1: none; --sh-2: 0 0 0 1px var(--c-line); --sh-3: 0 0 0 1px var(--c-line);
}

/* ---------- SEMANTIC COMPONENT TOKENS ------------------------------------
   What each shared component uses. Defaults point at the palette and scales above (values identical to
   the verified design), so a theme can restyle a component family without touching component CSS or
   screens. Declared on every [data-theme] element too, so nested light/dark regions recompute them. */
.hb-root {
  /* type */
  --font-heading: var(--font-sans);
  --weight-heading: 600;            /* page, card and section titles (Readex Pro is sturdy; 600 reads as a heading) */
  --weight-strong: 600;             /* buttons, active nav, table heads, chips on */

  /* surfaces & chrome */
  --app-bg: var(--c-bg);
  --sidebar-bg: #0f4137;            --sidebar-line: #0f4137;      /* the pine operations rail, in both modes */
  --topbar-bg: var(--c-surface);    --topbar-line: var(--c-line);
  --card-bg: var(--c-surface);      --card-line: var(--c-line);
  --card-shadow: none;
  --card-border-width: 1px;
  --c-overlay: rgba(20,32,27,.5);   /* modal backdrop */
  --c-knob: #fff;                   /* switch knob */
  --c-device: #0f4137;              /* bezel of the phone preview */

  /* shape */
  --radius-control: var(--r-md);    /* buttons, inputs, choices, search, nav items */
  --radius-card: var(--r-xl);       /* cards, alerts, popovers */
  --radius-tile: var(--r-lg);       /* action items, count tiles, large buttons, drop zones */
  --radius-chip: var(--r-sm);       /* chips, badges, account pill: square signage-like tags */
  --radius-modal: var(--r-2xl);

  /* density */
  --page-pad: var(--sp-7);
  --page-gap: var(--sp-5);
  --card-pad: var(--sp-5);
  --card-gap: 14px;
  --control-pad-x: var(--sp-4);
  --cell-py: 12px;   --cell-px: 14px;    /* table body cells */
  --work-main-min: 620px;  --work-panel-w: 340px;   /* work split: list + side panel */
  --cell-text-max: 22em;   /* a wrapping text column never grows wider than this */
  --head-py: 11px;                      /* table header cells */
  --chip-h: 32px;
  --badge-h: 24px;   --badge-px: 9px;
  --nav-item-h: 36px;
  --topbar-py: 14px;
  --stat-pad: 20px;
  --search-min-w: 0;      /* the search field may shrink with the topbar (P5, approved) */

  /* layout gaps — space between the children of page-level flex/grid containers.
     One ladder, scaled together by --gap-scale so a brand can change density without touching pages.
     Grids of cards use --card-gap and gaps between page sections use --page-gap (above). */
  --gap-scale: 1;
  --gap-2xs: calc(4px * var(--gap-scale));    /* stacked text lines: title over sub-line */
  --gap-xs:  calc(6px * var(--gap-scale));    /* icon + label, badge clusters */
  --gap-sm:  calc(8px * var(--gap-scale));    /* inline controls, action rows */
  --gap-md:  calc(10px * var(--gap-scale));   /* list items, fields in a column */
  --gap-lg:  calc(12px * var(--gap-scale));   /* control groups, blocks inside a card */
  --gap-xl:  calc(14px * var(--gap-scale));   /* rows of an item with an avatar or icon tile */
  --gap-2xl: calc(16px * var(--gap-scale));   /* panels side by side */
  --gap-3xl: calc(20px * var(--gap-scale));   /* sections inside a padded panel */
  --gap-4xl: calc(24px * var(--gap-scale));   /* large columns: settings, profile, legal */

  /* inner padding of recurring boxes */
  --note-pad: 12px 14px;        /* hint / note box inside a card */
  --note-pad-sm: 10px 12px;     /* compact note line */
  --callout-pad: 12px 16px;     /* warning / info callout across a page */
  --tile-pad: 14px;             /* bordered option tile, mini stat tile */
  --tile-pad-sm: 12px;          /* small count tile */
  --section-pad: 16px 20px;     /* header row / section inside a card */
  --control-pad-x-sm: 12px;     /* compact control (32–36 px high) */

  /* buttons */
  --btn-bg: var(--c-surface);       --btn-fg: var(--c-text);      --btn-line: var(--c-line);
  --btn-pri-bg: var(--c-accent-fill); --btn-pri-fg: var(--c-on-accent); --btn-pri-hover: var(--c-accent-hover);

  /* navigation (sidebar text has its own roles so the rail can be dark on a light app) */
  --sidebar-fg: #ffffff;            --sidebar-muted: #9ab3a9;     --sidebar-divider: rgba(255,255,255,.12);
  /* nav items on a page surface (menus, popovers, reference boards) … */
  --nav-fg: var(--c-text);          --nav-hover-bg: var(--c-sunken);
  --nav-active-bg: var(--c-accent-soft); --nav-active-fg: var(--c-accent);
  /* … and on the navy rail (applied to .side below) */
  --rail-nav-fg: #cfddd7;           --rail-nav-hover-bg: rgba(255,255,255,.06);
  --rail-nav-active-bg: rgba(255,255,255,.09); --rail-nav-active-fg: #ffffff;

  /* account pill in the topbar */
  --account-bg: var(--c-surface); --account-fg: var(--c-text); --account-line: var(--c-line-strong);

  /* selection (chips, choices, switches, selected tab) */
  --select-bg: var(--c-accent-fill); --select-fg: var(--c-on-accent);

  /* tables */
  --table-head-bg: var(--c-sunken); --table-head-fg: var(--c-text-2);   /* a solid steel header band */
  --table-line: var(--c-line);

  /* Harbor component character */
  --table-head-rule: 1px solid var(--c-line-strong);   /* line under the table header */
  --nav-active-mark: #7cbfac;  --nav-active-mark-w: 3px;   /* mint "you are here" bar on the active nav item */
  --badge-dot: '';                 /* status tags carry a dot, so colour is never the only signal; none turns it off */
  --badge-weight: 500;
  --stat-weight: 600;              /* KPI values */
  --input-bg: var(--c-surface);    --input-line: var(--c-line-strong);
  --search-bg: var(--c-surface-2); --search-line: var(--c-line-strong);
  --sidebar-inset: 0px;  --sidebar-radius: 0px;  --sidebar-shadow: none;   /* a floating sidebar panel */
  --kpi-bg: var(--card-bg);  --kpi-line: var(--card-line);  --kpi-shadow: var(--card-shadow);  --kpi-radius: var(--radius-card);
  --kpi-rule: var(--card-border-width) solid var(--card-line);   /* top edge of KPI tiles (stat and metric cards) */

  /* sidebar logo — which artwork the sidebar shows follows the sidebar's own surface, not the page theme.
     logo-light.png = dark ink for a light surface; logo-dark.png = white for a dark surface. */
  --sidebar-logo-for-light: none;    /* the rail is pine in both modes: white artwork */
  --sidebar-logo-for-dark: block;
  /* the same choice for a logo placed on the page surface (login, sign-up, previews): follows the page theme */
  --page-logo-for-light: block;
  --page-logo-for-dark: none;
}

/* the navigation rail uses the rail roles for its nav items */
.hb-side { --nav-fg: var(--rail-nav-fg); --nav-hover-bg: var(--rail-nav-hover-bg); --nav-active-bg: var(--rail-nav-active-bg); --nav-active-fg: var(--rail-nav-active-fg); }

/* dark mode: logos placed on the page surface switch to the white artwork; the rail steps down to the dark canvas */
.hb-root[data-theme="dark"] { --page-logo-for-light: none;    --page-logo-for-dark: block;
                      --sidebar-bg: #081b17;          --sidebar-line: var(--c-line);   /* the rail steps down to the dark canvas */ }

/* ==== base.css ==== */
/* Base — app root, icon sizing and text helpers.
   Ported 1:1 from Harbor b29e1fa (approved 22 Oct 2026) for the Laravel admin: every class carries the hb-
   prefix and every global selector is scoped to .hb-root, so this file cannot reach Bootstrap pages or other
   panels. scripts/build-admin-harbor.mjs concatenates the files in this order: tokens, base, components,
   layout, widgets, integration. */

/* Product typeface: Readex Pro (Arabic + Latin), self-hosted variable font, SIL OFL 1.1 (fonts/ReadexPro-OFL.txt).
   The customer-site preview names the same family, so it renders in it too. */
@font-face { font-family: 'Readex Pro'; src: url('fonts/ReadexPro-variable.woff') format('woff'); font-weight: 160 700; font-display: swap; }

/* ---------- 2. BASE -------------------------------------------------- */
.hb-app { font-family: var(--font-sans); color: var(--c-text); background: var(--app-bg); box-sizing: border-box; min-height: 100%; font-size: var(--fs-md); }
.hb-app *, .hb-app *::before, .hb-app *::after { box-sizing: border-box; }
.hb-app a { color: inherit; text-decoration: none; }
.hb-app h1, .hb-app h2, .hb-app h3 { margin: 0; }
.hb-app :focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.hb-ic { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.hb-ic.hb-sm { width: 14px; height: 14px; } .hb-ic.hb-lg { width: 20px; height: 20px; }
.hb-ic-line { display: block; }   /* icon box = one line of the parent font (icon macro); added for the file-based project */
.hb-note { font-size: var(--fs-xs); color: var(--c-text-muted); line-height: 1.7; }
.hb-muted { color: var(--c-text-muted); }
.hb-link { color: var(--c-accent); font-weight: 600; }
.hb-num { font-variant-numeric: tabular-nums; }
.hb-strong { font-weight: 600; }
.hb-ltr { direction: ltr; }   /* Latin values inside RTL text: e-mails, phone numbers, URLs, codes */

/* Document — added for the file-based project. In the canvas these rules came from the
   preview runtime (html/body height and margin); the backdrop uses the canvas token. */
.hb-root, .hb-root body { height: 100%; margin: 0; }
.hb-root { background: var(--c-canvas); zoom: var(--ui-zoom); }   /* UI scale: see --ui-zoom in tokens.css */

/* Component reference pages (sidebar.html, stat-card.html …) show one shared component inside
   the app root, so it renders exactly as it does on the screens that use it. */
.hb-component-board { min-height: 100%; }

/* ==== components.css ==== */
/* Primitives — button, badge, card, alert, field/input, seg, switch, chip, choices, tabs,
   table + row states, skeleton, avatar, modal, key/value, action item.
   Ported 1:1 from Harbor b29e1fa (approved 22 Oct 2026) for the Laravel admin: every class carries the hb-
   prefix and every global selector is scoped to .hb-root, so this file cannot reach Bootstrap pages or other
   panels. scripts/build-admin-harbor.mjs concatenates the files in this order: tokens, base, components,
   layout, widgets, integration. */

/* ---------- 3. PRIMITIVES ------------------------------------------- */

/* Button — variants: (default) | .pri | .ink | .soft | .ghost | .danger ; sizes: .sm | (md) | .lg ; .block ; .icon */
.hb-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); height: var(--h-md); padding: 0 var(--control-pad-x); border-radius: var(--radius-control); font: var(--weight-strong) var(--fs-md)/1 var(--font-sans); border: 1px solid var(--btn-line); background: var(--btn-bg); color: var(--btn-fg); cursor: pointer; white-space: nowrap; text-decoration: none; }
.hb-btn:hover, .hb-btn.hb-is-hover { background: var(--c-sunken); }
.hb-btn.hb-is-focus { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.hb-btn.hb-pri { background: var(--btn-pri-bg); border-color: var(--btn-pri-bg); color: var(--btn-pri-fg); }
.hb-btn.hb-pri:hover, .hb-btn.hb-pri.hb-is-hover { background: var(--btn-pri-hover); border-color: var(--btn-pri-hover); }
.hb-btn.hb-ghost { background: transparent; border-color: transparent; color: var(--c-accent); }
.hb-btn.hb-ink { background: var(--c-text); border-color: var(--c-text); color: var(--c-bg); }
.hb-btn.hb-soft { background: var(--c-accent-soft); border-color: transparent; color: var(--c-accent); }
.hb-btn.hb-danger { color: var(--c-bad); }
.hb-btn.hb-danger.hb-pri { background: var(--c-bad-fill); border-color: var(--c-bad-fill); color: var(--c-on-accent); }
.hb-btn.hb-danger.hb-pri:hover, .hb-btn.hb-danger.hb-pri.hb-is-hover { background: var(--c-bad-fill-hover); border-color: var(--c-bad-fill-hover); }
.hb-btn.hb-danger.hb-pri.hb-is-focus { outline-color: var(--c-bad); }
.hb-btn.hb-ghost:hover, .hb-btn.hb-ghost.hb-is-hover { background: var(--c-accent-soft); }
.hb-btn.hb-sm { height: var(--h-sm); padding: 0 var(--sp-3); font-size: var(--fs-sm); }
.hb-btn.hb-lg { height: var(--h-lg); font-size: var(--fs-lg); border-radius: var(--radius-tile); }
.hb-btn.hb-block { display: flex; }   /* block-level: fills stretch stacks, sizes to content in align-start stacks and rows */
.hb-btn.hb-xl { height: 56px; font-size: var(--fs-lg); font-weight: 700; border-radius: var(--r-xl); }
.hb-btn.hb-xs { height: 30px; padding: 0 10px; }   /* compact row action (tables, lists) */
.hb-btn.hb-icon { padding: 0; width: var(--h-md); }
.hb-btn.hb-icon.hb-lg { width: var(--h-lg); }
/* Row actions in a table cell: Details on top, the small "..." menu below it */
.hb-row-actions { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
.hb-row-actions .hb-btn.hb-dots { width: 28px; height: 28px; }
.hb-btn[disabled], .hb-btn.hb-is-disabled { opacity: .5; cursor: not-allowed; }
.hb-btn.hb-is-loading { opacity: .8; cursor: progress; }

/* Badge — tones: .ok .warn .bad .info .acc .neutral .purple .off .plain .solid .bad-solid .ink ; .sm */
.hb-badge { display: inline-flex; align-items: center; gap: var(--sp-1); height: var(--badge-h); padding: 0 var(--badge-px); border-radius: var(--radius-chip); font-size: var(--fs-xs); font-weight: var(--badge-weight); white-space: nowrap; background: var(--c-neutral-soft); color: var(--c-neutral); }
.hb-badge.hb-wrap { height: auto; min-height: var(--badge-h); white-space: normal; max-width: 100%; }   /* long sentence badges may wrap on narrow screens */
.hb-badge.hb-is-status::before { content: var(--badge-dot); width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.hb-badge.hb-sm { height: 20px; padding: 0 var(--sp-2); font-size: var(--fs-2xs); }
.hb-badge.hb-ok { background: var(--c-ok-soft); color: var(--c-ok); }
.hb-badge.hb-warn { background: var(--c-warn-soft); color: var(--c-warn); }
.hb-badge.hb-bad { background: var(--c-bad-soft); color: var(--c-bad); }
.hb-badge.hb-info { background: var(--c-info-soft); color: var(--c-info); }
.hb-badge.hb-acc { background: var(--c-accent-soft); color: var(--c-accent); }
.hb-badge.hb-neutral { background: var(--c-neutral-soft); color: var(--c-neutral); }
.hb-badge.hb-purple { background: var(--c-purple-soft); color: var(--c-purple); }
.hb-badge.hb-off { background: var(--c-sunken); color: var(--c-text-muted); }     /* inactive, closed, hidden, draft */
.hb-badge.hb-plain { background: var(--c-sunken); color: var(--c-text-2); }       /* neutral categories (plan tier, ad type) */
.hb-badge.hb-solid { background: var(--c-accent-fill); color: var(--c-on-accent); }
.hb-badge.hb-bad-solid { background: var(--c-bad-fill); color: var(--c-on-accent); }
.hb-badge.hb-ink { background: var(--c-text); color: var(--c-bg); }

/* Card — padded column by default; .flush removes padding/flow for tables & custom layouts */
.hb-card { background: var(--card-bg); border: var(--card-border-width) solid var(--card-line); border-radius: var(--radius-card); box-shadow: var(--card-shadow); padding: var(--card-pad); display: flex; flex-direction: column; gap: var(--card-gap); }
.hb-card.hb-flush { padding: 0; display: block; }
.hb-card.hb-clip { overflow: hidden; }
.hb-card h2, .hb-card-title { margin: 0; font-family: var(--font-heading); font-size: var(--fs-lg); font-weight: var(--weight-heading); }
.hb-card-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--sp-2); }
.hb-card.hb-flush > .hb-card-head { padding: 18px var(--sp-5); }
.hb-flush-head { padding: 18px 20px 0; }   /* title block above a table inside a .card.flush */
.hb-card.hb-tone-warn { background: var(--c-warn-soft); border-color: var(--c-warn-line); }
.hb-card.hb-tone-bad { background: var(--c-bad-tint); border-color: var(--c-bad-line); }
.hb-card.hb-tone-acc { background: var(--c-accent-soft); border-color: var(--c-accent-line); }
.hb-card.hb-tone-muted { background: var(--c-sunken); }
.hb-card.hb-tone-warn .hb-stat-value, .hb-card.hb-tone-warn .hb-stat-note { color: var(--c-warn-strong); }
.hb-card.hb-tone-bad .hb-stat-value, .hb-card.hb-tone-bad .hb-stat-note { color: var(--c-bad-strong); }
.hb-nav-i.hb-is-hover { background: var(--c-sunken); }
.hb-spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-inline-end-color: transparent; display: inline-block; flex: none; }

/* Alert — inline message row */
.hb-alert { display: flex; gap: var(--sp-3); align-items: flex-start; padding: 14px var(--sp-4); border-radius: var(--radius-card); border: 1px solid var(--c-line); background: var(--c-surface); font-size: var(--fs-md); line-height: var(--lh-body); }
.hb-alert.hb-warn { background: var(--c-warn-soft); border-color: var(--c-warn-line); color: var(--c-warn-strong); }
.hb-alert.hb-bad { background: var(--c-bad-tint); border-color: var(--c-bad-line); color: var(--c-bad); }
.hb-alert.hb-ok { background: var(--c-ok-soft); border-color: var(--c-ok-line); color: var(--c-ok); }
.hb-alert.hb-info { background: var(--c-info-soft); border-color: transparent; color: var(--c-info); }

/* Field + Input / Select / Textarea */
.hb-field { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-muted); min-width: 0; }
.hb-field .hb-hint { font-weight: 400; }
.hb-field .hb-error { font-weight: 400; color: var(--c-bad); }
.hb-input { height: var(--h-md); border-radius: var(--radius-control); padding: 0 var(--sp-3); font: 400 var(--fs-md)/1.2 var(--font-sans); display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); background: var(--input-bg); border: 1px solid var(--input-line); color: var(--c-text); min-width: 0; max-width: 100%; }   /* never wider than its container (a wide font widens a native <input>) */
.hb-input.hb-textarea { height: 72px; align-items: flex-start; padding-top: 10px; }
.hb-input.hb-is-error { border-color: var(--c-bad); box-shadow: 0 0 0 3px var(--c-bad-soft); }
.hb-input.hb-is-focus { border-color: var(--c-accent); box-shadow: var(--ring); }
.hb-input.hb-is-disabled { background: var(--c-sunken); color: var(--c-text-subtle); }
.hb-input.hb-is-error { background: var(--c-bad-tint); }
.hb-input.hb-ltr { direction: ltr; justify-content: flex-end; }   /* phone, e-mail, URL fields */
.hb-input.hb-is-readonly { border-style: dashed; background: var(--c-surface-2); font-weight: 700; }
.hb-field .hb-warn { font-weight: 400; color: var(--c-warn); }
.hb-placeholder { color: var(--c-text-subtle); }
.hb-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 14px; }
.hb-form-grid.hb-wide { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--sp-4); }
.hb-drop { border: 1.5px dashed var(--c-line-strong); border-radius: var(--radius-tile); padding: 22px; text-align: center; color: var(--c-text-muted); font-size: var(--fs-md); }

/* Segmented control */
.hb-seg { display: flex; gap: 6px; background: var(--c-sunken); padding: var(--sp-1); border-radius: var(--radius-tile); }
.hb-seg > span, .hb-seg > button { flex: 1; text-align: center; padding: var(--sp-2) 0; border-radius: var(--radius-control); font: 400 var(--fs-sm)/1.4 var(--font-sans); color: var(--c-text-muted); background: transparent; border: 0; cursor: pointer; }
.hb-seg > .hb-on { background: var(--c-surface); color: var(--c-text); font-weight: 600; box-shadow: var(--sh-1); }

/* Switch + toggle row */
.hb-sw { width: 40px; height: 22px; border-radius: var(--r-pill); background: var(--c-line-strong); position: relative; flex: none; display: inline-block; }
.hb-sw::after { content: ""; position: absolute; top: 3px; inset-inline-start: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--c-knob); }
.hb-sw.hb-on { background: var(--select-bg); }
.hb-sw.hb-on::after { inset-inline-start: auto; inset-inline-end: 3px; }
.hb-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-md); }

/* Chip / filter tab */
.hb-chip, .hb-chips > span { display: inline-flex; align-items: center; gap: 6px; flex: none; height: var(--chip-h); padding: 0 var(--sp-3); border-radius: var(--radius-chip); border: 1px solid var(--btn-line); background: var(--btn-bg); font: 400 var(--fs-sm)/1 var(--font-sans); color: var(--c-text); cursor: pointer; white-space: nowrap; }
.hb-chip.hb-on, .hb-chips > span.hb-on { background: var(--select-bg); border-color: var(--select-bg); color: var(--select-fg); font-weight: var(--weight-strong); }
.hb-chips.hb-nowrap { flex-wrap: nowrap; overflow-x: auto; }

/* Choices — option buttons inside forms and filter rows (container type, payment method, status filter) */
.hb-choices { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.hb-choices > span, .hb-choices > button, .hb-choices > label > span { display: inline-flex; align-items: center; justify-content: center; height: var(--h-md); padding: 0 var(--control-pad-x); border-radius: var(--radius-control); border: 1px solid var(--c-line-strong); background: var(--c-surface); font: 500 var(--fs-md)/1 var(--font-sans); color: var(--c-text); white-space: nowrap; cursor: pointer; }
.hb-choices > .hb-on, .hb-choices > label > input:checked + span { background: var(--select-bg); border-color: var(--select-bg); color: var(--select-fg); font-weight: var(--weight-strong); }
.hb-choices.hb-fill > span, .hb-choices.hb-fill > button, .hb-choices.hb-fill > label { flex: 1; }
.hb-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* Report section tabs (finance reports): roomier than filter chips, rows breathe when they wrap */
.hb-chips.hb-report-tabs { gap: var(--sp-3) var(--sp-3); }
.hb-chips.hb-report-tabs > a.hb-chip { height: calc(var(--chip-h) + 8px); padding: 0 var(--sp-4); }

/* Tabs (underline) */
.hb-tabs { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--c-line); overflow-x: auto; }
.hb-tab, .hb-tabs > a { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: 44px; padding: 0 14px; font-size: var(--fs-md); color: var(--c-text-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; background: none; border-top: 0; border-inline: 0; font-family: inherit; cursor: pointer; }
.hb-tab.hb-on, .hb-tabs > a.hb-on { color: var(--c-accent); border-bottom-color: var(--c-accent); font-weight: 600; }
.hb-tabs.hb-wrap { flex-wrap: wrap; overflow: visible; }

/* Phone tab bar item (inside a bottom bar) */
.hb-tabbar-i { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: var(--sp-2) 0; font-size: var(--fs-2xs); color: var(--c-text-muted); min-height: 44px; justify-content: center; }
.hb-tabbar-i.hb-on { color: var(--c-accent); font-weight: 700; }

/* Table */
.hb-table-wrap { overflow-x: auto; }
.hb-table { width: 100%; border-collapse: collapse; }
.hb-th { font-size: var(--fs-xs); font-weight: var(--weight-strong); color: var(--table-head-fg); text-align: start; padding: var(--head-py) var(--cell-px); background: var(--table-head-bg); border-bottom: var(--table-head-rule); white-space: nowrap; }
.hb-td { font-size: var(--fs-md); padding: var(--cell-py) var(--cell-px); border-bottom: 1px solid var(--table-line); white-space: nowrap; vertical-align: middle; }
.hb-table tr:last-child > .hb-td { border-bottom: 0; }
/* Client-side table (x-harbor.table enhance, table.js): the search / page-size bar above, the info + pager below */
.hb-table-tools { display: flex; flex-wrap: wrap; align-items: end; gap: var(--sp-3) var(--sp-5); padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--c-line); }
.hb-table-tools[hidden], .hb-table-foot[hidden], .hb-table-nomatch[hidden] { display: none; }
.hb-table-search { flex: 1 1 220px; max-width: 360px; }
.hb-table-size { flex: 0 0 auto; min-width: 96px; }
.hb-th-sort { display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer; }
.hb-sort-mark::before { content: "↕"; opacity: .45; }
.hb-th[aria-sort="ascending"] .hb-sort-mark::before { content: "↑"; opacity: 1; }
.hb-th[aria-sort="descending"] .hb-sort-mark::before { content: "↓"; opacity: 1; }
/* 24 px touch targets (WCAG 2.5.8, owner decision 26 Oct 2026): a sort heading and a link in a cell get an invisible hit
   area at least 24 screen px tall (divided by --ui-zoom: the desktop UI renders at 90 %); nothing moves, rows keep their height */
.hb-th-sort, .hb-td a.hb-link { position: relative; }
.hb-th-sort::after, .hb-td a.hb-link::after { content: ""; position: absolute; inset-inline: 0; inset-block: min(0px, calc((100% - 24px / var(--ui-zoom, 1)) / 2)); }
.hb-table-nomatch > .hb-td { text-align: center; padding-block: var(--sp-6); white-space: normal; }
.hb-table-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--c-line); }
/* row states */
.hb-row-late > .hb-td { background: var(--c-bad-tint); }
.hb-row-new > .hb-td { background: color-mix(in srgb, var(--c-accent-soft) 45%, var(--c-surface)); }
.hb-row-cancelled > .hb-td { background: var(--c-surface-2); color: var(--c-text-subtle); text-decoration: line-through; }
.hb-row-selected > .hb-td { background: var(--c-accent-soft); }
.hb-row-muted > .hb-td { color: var(--c-text-subtle); }

/* Long content. Policy: identity and description text wraps (never truncated); codes, dates, money, statuses
   and actions never wrap; the actions column stays in view at the inline end while the table scrolls.
   Text cells: data_table columns of kind wrap, and any hand-written name cell (<b> over a .note sub-line).
   A table scrolls below its min_width (set per table); above it, long text wraps instead of widening the table. */
.hb-td.hb-text, .hb-td:has(> b + .hb-note) { white-space: normal; max-width: var(--cell-text-max); overflow-wrap: break-word; }   /* break-word: whole words wrap, a word only splits when it alone is too wide */
.hb-td.hb-text .hb-note, .hb-td:has(> b + .hb-note) .hb-note { white-space: normal; }
.hb-td.hb-col-action, .hb-table > tbody > tr > .hb-td:last-child:has(> .hb-btn), .hb-th.hb-col-action, .hb-table:has(> tbody > tr > .hb-td:last-child > .hb-btn) > thead > tr > .hb-th:last-child {
  position: sticky; inset-inline-end: 0; z-index: 1; border-inline-start: 1px solid var(--table-line); }
:where(.hb-td.hb-col-action, .hb-table > tbody > tr > .hb-td:last-child:has(> .hb-btn)) { background-color: var(--card-bg); }   /* :where = no specificity, so row states below win */
:where(.hb-table > tbody > tr[style*="background"] > .hb-td:last-child:has(> .hb-btn)) { background-color: inherit; }
.hb-row-late > .hb-td.hb-col-action { background: linear-gradient(var(--c-bad-tint), var(--c-bad-tint)), var(--card-bg); }
.hb-row-new > .hb-td.hb-col-action { background: linear-gradient(color-mix(in srgb, var(--c-accent-soft) 45%, var(--c-surface)), color-mix(in srgb, var(--c-accent-soft) 45%, var(--c-surface))), var(--card-bg); }
.hb-row-cancelled > .hb-td.hb-col-action { background: var(--c-surface-2); }
.hb-row-selected > .hb-td.hb-col-action { background: linear-gradient(var(--c-accent-soft), var(--c-accent-soft)), var(--card-bg); }

/* Skeleton + placeholder art */
.hb-skeleton { height: 12px; border-radius: var(--r-sm); background: var(--c-sunken); }
.hb-ph { background: repeating-linear-gradient(135deg, var(--c-sunken) 0 8px, var(--c-line) 8px 16px); border: 1px dashed var(--c-line-strong); border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center; font-size: var(--fs-2xs); color: var(--c-text-muted); font-weight: 600; }

/* Avatar */
.hb-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--c-accent-soft); color: var(--c-accent); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; flex: none; }
.hb-avatar.hb-sm { width: 30px; height: 30px; font-size: var(--fs-sm); }
.hb-avatar.hb-solid { background: var(--btn-pri-bg); color: var(--btn-pri-fg); }

/* Modal frame (content stays per screen) */
.hb-overlay { background: var(--c-overlay); display: flex; align-items: center; justify-content: center; padding: var(--sp-6); }
.hb-modal { background: var(--card-bg); border-radius: var(--radius-modal); box-shadow: var(--sh-3); width: min(560px, 100%); display: flex; flex-direction: column; }
.hb-modal-head { padding: var(--sp-5) var(--sp-6) 0; display: flex; justify-content: space-between; gap: var(--sp-3); }
.hb-modal-body { padding: var(--sp-4) var(--sp-6); display: flex; flex-direction: column; gap: 14px; }
.hb-modal-foot { padding: var(--sp-4) var(--sp-6); border-top: 1px solid var(--c-line); display: flex; gap: var(--sp-2); justify-content: flex-start; }
.hb-popover { background: var(--card-bg); border: 1px solid var(--card-line); border-radius: var(--radius-card); box-shadow: var(--sh-2); }

/* Facts grid — label above value, auto columns (order and vendor-order details) */
.hb-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); gap: 14px; }
.hb-facts div { display: flex; flex-direction: column; gap: 3px; font-size: var(--fs-md); }
.hb-facts span { font-size: var(--fs-xs); color: var(--c-text-muted); }

/* Check box (static checklist mark) */
.hb-check-box { width: 18px; height: 18px; border-radius: var(--r-sm); border: 1.5px solid var(--c-line-strong); flex: none; }
.hb-check-box.hb-on { background: var(--c-accent-fill); border-color: var(--c-accent-fill); }

/* Hazard stripe — brand band on sign-in, sign-up, error and print pages */
.hb-stripe { height: 10px; background: repeating-linear-gradient(135deg, var(--c-stripe-1) 0 14px, var(--c-stripe-2) 14px 28px); }

/* Key/value row */
.hb-kv { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); font-size: var(--fs-md); }
.hb-kv > :first-child { color: var(--c-text-muted); font-size: var(--fs-sm); }

/* Action item ("needs action" rows) — tone on the count tile */
.hb-action-item { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3); border: 1px solid var(--card-line); border-radius: var(--radius-tile); background: var(--card-bg); }
.hb-action-item .hb-count { width: 40px; height: 40px; border-radius: var(--radius-tile); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: var(--fs-lg); flex: none; background: var(--c-neutral-soft); color: var(--c-neutral); }
.hb-action-item .hb-count.hb-warn { background: var(--c-warn-soft); color: var(--c-warn); }
.hb-action-item .hb-count.hb-info { background: var(--c-info-soft); color: var(--c-info); }
.hb-action-item .hb-count.hb-bad { background: var(--c-bad-soft); color: var(--c-bad); }
.hb-action-item .hb-count.hb-acc { background: var(--c-accent-soft); color: var(--c-accent); }
.hb-action-item .hb-body { flex: 1; line-height: 1.4; min-width: 0; }
.hb-action-item .hb-title { font-size: var(--fs-md); font-weight: 600; }

/* Filter bar: the "more filters" disclosure (native <details>, closed unless a hidden filter is set) */
.hb-filter-more > summary { list-style: none; cursor: pointer; width: fit-content; }
.hb-filter-more > summary::-webkit-details-marker { display: none; }
.hb-filter-more[open] > summary .hb-ic { transform: rotate(180deg); }
.hb-filter-more > .hb-grid-auto { margin-top: var(--sp-4); }

/* ==== layout.css ==== */
/* Layout patterns — app shell, page header, grids/splits, spec boards, doc, device mockups.
   Ported 1:1 from Harbor b29e1fa (approved 22 Oct 2026) for the Laravel admin: every class carries the hb-
   prefix and every global selector is scoped to .hb-root, so this file cannot reach Bootstrap pages or other
   panels. scripts/build-admin-harbor.mjs concatenates the files in this order: tokens, base, components,
   layout, widgets, integration. */

/* ---------- 4. LAYOUT PATTERNS -------------------------------------- */
/* App shell: sidebar + main. Wraps to a stack on narrow screens. */
.hb-shell { display: flex; flex-wrap: wrap; width: 100%; min-height: var(--vh-full); }   /* sidebar column always reaches the bottom */
.hb-shell-side { flex: 0 0 var(--sidebar-w); background: var(--sidebar-bg); border-inline-end: 1px solid var(--sidebar-line); margin: var(--sidebar-inset); border-radius: var(--sidebar-radius); box-shadow: var(--sidebar-shadow); }
@media (min-width: 721px) {
  /* desktop: the navigation scrolls on its own and stays in place while the page scrolls */
  .hb-shell > .hb-shell-side { position: sticky; top: 0; height: var(--vh-full); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--sidebar-divider) transparent; }
}
.hb-shell-main { flex: 999 1 560px; min-width: 0; display: flex; flex-direction: column; }
.hb-page { padding: var(--page-pad); display: flex; flex-direction: column; gap: var(--page-gap); }

/* Page header: crumbs, title, subtitle, actions */
.hb-page-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.hb-page-head > .hb-titles { flex: 1 1 300px; min-width: 0; }
.hb-page-title { margin: 2px 0 0; font-family: var(--font-heading); font-size: var(--fs-h1); font-weight: var(--weight-heading); line-height: var(--lh-tight); }
.hb-crumbs { font-size: var(--fs-xs); color: var(--c-text-muted); }
.hb-page-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* Grids & splits */
.hb-grid-auto { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: var(--sp-4); }
.hb-grid-auto.hb-sm { grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); gap: var(--sp-3); }
.hb-split { display: flex; flex-wrap: wrap; gap: var(--sp-5); align-items: flex-start; }
.hb-split.hb-stretch { align-items: stretch; gap: var(--sp-4); }
.hb-col-main { flex: 2 1 560px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-5); }
.hb-col-side { flex: 1 1 320px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
/* Work split: a list (the work) beside the panel that adds to it. The list takes the spare width; the panel keeps
   its width and stays in view while the list scrolls; below the panel's width the panel moves under the list. */
.hb-work-split { display: flex; flex-wrap: wrap; gap: var(--page-gap); align-items: flex-start; }
.hb-work-split > .hb-work-main { flex: 999 1 var(--work-main-min); min-width: 0; }
.hb-work-split > .hb-work-panel { flex: 1 1 var(--work-panel-w); min-width: 0; position: sticky; top: var(--page-pad); }
.hb-stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.hb-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }

/* Device mockups (phone artboards) */
/* Spec boards: mockups and states laid out on the canvas backdrop */
.hb-board { padding: 40px; display: flex; flex-wrap: wrap; gap: 40px; justify-content: center; align-items: flex-start; background: var(--c-canvas); width: 100%; min-height: var(--vh-full); }
.hb-board.hb-col { flex-direction: column; flex-wrap: nowrap; justify-content: flex-start; align-items: stretch; gap: var(--sp-8); padding: 36px; }
.hb-board.hb-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); gap: var(--sp-6); padding: var(--sp-8); align-items: stretch; }
.hb-doc { padding: 32px 28px 48px; display: flex; flex-direction: column; gap: var(--sp-5); background: var(--c-bg); width: 100%; }

/* Device mockups — one frame spec, two sizes; .mini = bezelled app preview */
.hb-phone { width: 390px; height: 844px; border-radius: 28px; border: 1px solid var(--c-line); background: var(--c-bg); overflow: hidden; display: flex; flex-direction: column; position: relative; flex: none; }
.hb-phone.hb-sm { width: 320px; height: 700px; border-radius: 26px; }
.hb-phone.hb-mini { width: 300px; height: 600px; border-radius: 30px; border: 8px solid var(--c-device); }
.hb-phone-cap { font-size: var(--fs-sm); color: var(--c-text-muted); text-align: center; margin-top: 14px; max-width: 390px; line-height: var(--lh-body); }
.hb-bn { position: absolute; inset-inline: 0; bottom: 0; height: 68px; background: var(--c-surface); border-top: 1px solid var(--c-line); display: flex; }
.hb-bn a { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: var(--fs-2xs); color: var(--c-text-muted); min-height: 44px; }
.hb-bn a.hb-on { color: var(--c-accent); font-weight: 600; }
.hb-bn .hb-ic { width: 20px; height: 20px; }
.hb-tabbar { display: flex; background: var(--c-surface); border-top: 1px solid var(--c-line); padding: 4px 8px 10px; }   /* phone bottom bar holding .tabbar-i */
.hb-phone-body { flex: 1; overflow: hidden; padding: 16px; display: flex; flex-direction: column; gap: 12px; }   /* scroll area of a phone mock-up */
.hb-phone-body.hb-tight { padding: 14px; gap: 10px; }

/* Calendar of deliveries and pickups (screens/schedule/calendar.blade.php): a six-week grid, Saturday first. */
.hb-cal-main { flex: 2 1 520px; min-width: 0; }
.hb-cal-agenda { flex: 1 1 280px; min-width: 0; }
.hb-cal-bar { flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.hb-cal-month { font-size: var(--fs-lg); min-width: 9em; text-align: center; }
.hb-cal-legend { display: inline-flex; flex-wrap: wrap; gap: var(--sp-2); margin-inline-start: auto; }
.hb-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--sp-2); padding: var(--sp-3); }
.hb-cal-head { font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-muted); text-align: center; padding: 6px 0; }
.hb-cal-day { display: flex; flex-direction: column; gap: 3px; min-width: 0; min-height: 104px; padding: 6px; border: 1px solid var(--c-line); border-radius: var(--radius-control); background: var(--c-surface); color: var(--c-text); text-decoration: none; font-size: var(--fs-xs); }
.hb-cal-day:hover { border-color: var(--c-accent-line); }
.hb-cal-day.hb-out { background: var(--c-bg); color: var(--c-text-disabled); }
.hb-cal-day.hb-today { border-color: var(--c-accent); box-shadow: inset 0 0 0 1px var(--c-accent); }
.hb-cal-day.hb-picked { background: var(--c-accent-soft); border-color: var(--c-accent); }
.hb-cal-ev { display: block; padding: 2px 6px; border-radius: var(--r-sm); font-size: var(--fs-2xs); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: var(--c-info-soft); color: var(--c-info); }
.hb-cal-pickup { background: var(--c-ok-soft); color: var(--c-ok); }
.hb-cal-ev.hb-cal-unassigned { background: var(--c-warn-soft); color: var(--c-warn); }
.hb-cal-item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); padding: var(--sp-3); border: 1px solid var(--c-line); border-radius: var(--radius-control); }
.hb-cal-item > span { flex: 1 1 140px; min-width: 0; }
@media (max-width: 720px) {
  .hb-cal { gap: 2px; padding: var(--sp-2); }
  .hb-cal-head { font-size: var(--fs-2xs); }
  .hb-cal-day { min-height: 56px; padding: 4px; }
  .hb-cal-ev { font-size: 0; height: 6px; padding: 0; }
  .hb-cal-ev > bdi { display: none; }
  .hb-cal-legend { margin-inline-start: 0; }
}

/* ==== widgets.css ==== */
/* Shared widgets — sidebar, topbar, stat card, empty state, bars, and the phone-width shell.
   Ported 1:1 from Harbor b29e1fa (approved 22 Oct 2026) for the Laravel admin: every class carries the hb-
   prefix and every global selector is scoped to .hb-root, so this file cannot reach Bootstrap pages or other
   panels. scripts/build-admin-harbor.mjs concatenates the files in this order: tokens, base, components,
   layout, widgets, integration. */

/* Sidebar navigation (used by Sidebar.dc.html) */
.hb-side { padding: var(--sp-5) var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-4); }
.hb-side-brand { display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-1); height: 44px; }
.hb-side-brand img { height: 38px; width: auto; display: block; }
.hb-side-brand .hb-logo-light { display: var(--sidebar-logo-for-light); }
.hb-side-brand .hb-logo-dark { display: var(--sidebar-logo-for-dark); }
.hb-page-logo img { height: 44px; width: auto; }
.hb-page-logo.hb-sm img { height: 34px; }
.hb-page-logo .hb-logo-light { display: var(--page-logo-for-light); }   /* a logo on the page surface: both artworks, one shown */
.hb-page-logo .hb-logo-dark { display: var(--page-logo-for-dark); }
.hb-side-brand span { font-size: var(--fs-xs); color: var(--sidebar-muted); border-inline-start: 1px solid var(--sidebar-divider); padding-inline-start: 10px; line-height: var(--lh-tight); }
.hb-side-group { display: flex; flex-direction: column; gap: 2px; }
.hb-side-group-title { display: flex; align-items: center; justify-content: space-between; width: 100%; font: 600 var(--fs-2xs)/1 var(--font-sans); color: var(--sidebar-muted); padding: 6px var(--sp-3); background: none; border: 0; cursor: pointer; text-align: start; border-radius: var(--r-sm); }
.hb-side-group-title:hover { background: var(--nav-hover-bg); }
.hb-nav-i { display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-3); height: var(--nav-item-h); border-radius: var(--radius-control); font-size: var(--fs-md); color: var(--nav-fg); }
.hb-side .hb-nav-i:not(.hb-on) { color: var(--nav-fg); }   /* beats `.app a { color: inherit }` so the token applies */
.hb-nav-i:hover { background: var(--nav-hover-bg); }
.hb-nav-i.hb-on { background: var(--nav-active-bg); color: var(--nav-active-fg); font-weight: var(--weight-strong); }
.hb-nav-i { position: relative; }
.hb-nav-i.hb-on::before { content: ""; position: absolute; inset-block: 8px; inset-inline-start: 0; width: var(--nav-active-mark-w); border-start-end-radius: 3px; border-end-end-radius: 3px; background: var(--nav-active-mark); }
.hb-nav-i > .hb-label { flex: 1; }
.hb-side-user .hb-note { color: var(--sidebar-muted); }
.hb-side-user { border-top: 1px solid var(--sidebar-divider); padding-top: 14px; display: flex; align-items: center; gap: 10px; }

/* Topbar (used by Topbar.dc.html) */
.hb-topbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); padding: var(--topbar-py) var(--page-pad); background: var(--topbar-bg); border-bottom: 1px solid var(--topbar-line); }
.hb-search { flex: 1 1 320px; min-width: var(--search-min-w); max-width: 460px; display: flex; align-items: center; gap: 10px; height: var(--h-md); border: 1px solid var(--c-line); border-radius: var(--radius-control); padding: 0 var(--sp-3); background: var(--search-bg); color: var(--c-text-muted); font-size: var(--fs-md); border-color: var(--search-line); }
.hb-search input { border: 0; background: transparent; font: inherit; color: var(--c-text); flex: 1; min-width: 0; outline: none; }
.hb-search input::placeholder { color: var(--c-text-muted); }
.hb-search:focus-within { border-color: var(--c-accent); box-shadow: var(--ring); }
.hb-account { display: flex; align-items: center; gap: var(--sp-2); height: var(--h-md); padding: 0 6px 0 10px; border: 1px solid var(--account-line); border-radius: var(--radius-chip); background: var(--account-bg); color: var(--account-fg); font-size: var(--fs-sm); font-weight: 600; }

/* KPI tiles: stat and metric cards share one look, set by the --kpi-* tokens */
.hb-stat, .hb-metric { background: var(--kpi-bg); border-color: var(--kpi-line); border-top: var(--kpi-rule); box-shadow: var(--kpi-shadow); border-radius: var(--kpi-radius); }

/* Stat card (used by StatCard.dc.html) */
.hb-stat { padding: var(--stat-pad); gap: 10px; height: 100%; }
.hb-stat-label { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-muted); }
.hb-stat-value { font-family: var(--font-heading); font-size: var(--fs-stat); font-weight: var(--stat-weight); letter-spacing: -.01em; line-height: 1.2; }
.hb-stat-value small { font-size: var(--fs-sm); font-weight: 500; color: var(--c-text-muted); }
.hb-stat-note { font-size: var(--fs-xs); color: var(--c-text-muted); }
.hb-stat.hb-compact { padding: 14px; gap: 4px; }
.hb-stat.hb-compact .hb-stat-value { font-size: var(--fs-2xl); }

/* Metric card (used by components/metric_card.html) */
.hb-metric { gap: 6px; }
.hb-metric > b { font-family: var(--font-heading); font-size: var(--fs-3xl); }
.hb-metric.hb-lg > b { font-size: var(--fs-h1); }
.hb-metric.hb-warn { background: var(--c-warn-soft); border-color: var(--c-warn-line); }
.hb-metric.hb-warn > b { color: var(--c-warn-strong); }
.hb-metric.hb-bad, .hb-metric.hb-bad-strong { background: var(--c-bad-soft); border-color: var(--c-bad-line); }
.hb-metric.hb-bad > b { color: var(--c-bad); }
.hb-metric.hb-bad-strong > b { color: var(--c-bad-strong); }
.hb-metric.hb-acc { background: var(--c-accent-soft); border-color: var(--c-accent-line); }
.hb-metric.hb-acc > b { color: var(--c-accent); }
/* text tones */
.hb-t-ok { color: var(--c-ok); } .hb-t-warn { color: var(--c-warn); } .hb-t-bad { color: var(--c-bad); } .hb-t-info { color: var(--c-info); } .hb-t-muted { color: var(--c-text-muted); } .hb-t-acc { color: var(--c-accent); }
.hb-t-warn-strong { color: var(--c-warn-strong); } .hb-t-bad-strong { color: var(--c-bad-strong); } .hb-t-subtle { color: var(--c-text-subtle); }

/* Empty / error / loading state (used by EmptyState.dc.html) */
.hb-empty { align-items: center; text-align: center; gap: 10px; }
.hb-empty-icon { width: 44px; height: 44px; border-radius: var(--radius-card); background: var(--c-accent-soft); color: var(--c-accent); display: flex; align-items: center; justify-content: center; }
.hb-empty-icon.hb-neutral { background: var(--c-sunken); color: var(--c-text-muted); }
.hb-empty-icon.hb-bad { background: var(--c-bad-soft); color: var(--c-bad); }
.hb-empty-title { font-weight: 600; }
.hb-card.hb-dense { padding: 14px; gap: var(--sp-2); }
.hb-bar { background: var(--c-surface); border-bottom: 1px solid var(--c-line); padding: 14px var(--sp-4); display: flex; align-items: center; gap: 10px; }
.hb-between { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); }

/* Sidebar menu wrapper (desktop: the groups stack as before) */
.hb-side-menu { display: flex; flex-direction: column; gap: var(--sp-4); }
.hb-side-toggle, .hb-side-close, .hb-side-menu-head { display: none; }

/* Phones: the sidebar is a bar with a menu button. The menu is a drawer that slides in from the page's start side
   (right in Arabic) over a dimmed page; sidebar.js toggles .hb-side-open on the nav. */
@media (max-width: 720px) {
  .hb-shell-side { position: relative; z-index: 60; flex-basis: 100%; min-width: 0; max-width: 100%; border-inline-end: 0; border-bottom: 1px solid var(--c-line); }
  .hb-shell-side > * { min-width: 0; max-width: 100%; }
  .hb-side { flex-direction: column; align-items: stretch; gap: 0; padding: var(--sp-2) var(--sp-3); min-height: 0 !important; }
  .hb-side-brand { flex: none; height: 44px; }
  .hb-side-brand img { height: 30px; }
  .hb-side-toggle { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 40px; height: 40px; margin-inline-start: auto; border: 1px solid var(--sidebar-divider); border-radius: var(--radius-control); background: none; color: var(--sidebar-fg); cursor: pointer; }
  .hb-side-toggle[aria-expanded="true"] { background: var(--rail-nav-hover-bg); }
  .hb-side-menu-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: 44px; padding-inline-start: var(--sp-2); border-bottom: 1px solid var(--sidebar-divider); font: 600 var(--fs-md)/1 var(--font-sans); color: var(--sidebar-fg); }
  .hb-side-close { display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; border: 0; border-radius: var(--radius-control); background: none; color: var(--sidebar-fg); cursor: pointer; }
  .hb-side .hb-side-close .hb-ic { width: 26px; height: 26px; }
  .hb-side .hb-side-close:hover { background: var(--rail-nav-hover-bg); }
  .hb-side-menu { display: flex; position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 70; width: min(300px, 85vw); flex-direction: column; gap: var(--sp-3); padding: 0 var(--sp-3) var(--sp-4); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--sidebar-divider) transparent; background: var(--sidebar-bg); transform: translateX(-100%); visibility: hidden; transition: transform .2s ease, visibility .2s; }
  .hb-root[dir="rtl"] .hb-side-menu { transform: translateX(100%); }
  .hb-side.hb-side-open > .hb-side-menu { transform: none; visibility: visible; box-shadow: 0 0 0 100vmax var(--scrim); }
  .hb-side-group { flex-direction: column; flex: none; gap: 2px; }
  .hb-side-group-title { display: flex; }
  .hb-side-user { display: none; }
  .hb-nav-i { flex: none; width: 100%; height: 40px; white-space: nowrap; }
  .hb-topbar { padding: var(--sp-3) var(--sp-4); }
  .hb-page { padding: var(--sp-4); }
}

/* Collapsed sidebar group (sidebar.js sets [hidden] on its items) — added for the file-based project */
.hb-side [hidden] { display: none; }

/* ==== integration.css ==== */
/* Integration layer — what a working Laravel page needs beyond the drawn Harbor boards: live states of native
   controls, the dropdown menu, the native dialog, flash messages, pagination and form helpers.
   Everything here is built from the Harbor tokens and reproduces the look of the boards it comes from
   (header-menus: account/notification popovers; export-dialog: modal frame; data-table: pager; forms: fields).
   No new colours, sizes or radii: tokens only. Contract: docs/admin-harbor/UI_CONTRACT.md §2, §4. */

/* ---------- Live control states (the boards draw them with .hb-is-* classes) ---------------------- */
.hb-btn:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.hb-btn.hb-danger.hb-pri:focus-visible { outline-color: var(--c-bad); }
.hb-btn:disabled, .hb-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; pointer-events: none; }
.hb-btn.hb-is-loading .hb-spinner { animation: hb-spin .8s linear infinite; }
@keyframes hb-spin { to { transform: rotate(360deg); } }

/* native input / select / textarea carry .hb-input */
input.hb-input, select.hb-input, textarea.hb-input { width: 100%; outline: none; appearance: none; -webkit-appearance: none; }
textarea.hb-input { height: auto; min-height: 96px; padding: 10px var(--sp-3); line-height: var(--lh-body); resize: vertical; display: block; }
input.hb-input[type="file"] { padding: 7px var(--sp-2); height: auto; min-height: var(--h-md); }
.hb-input::placeholder { color: var(--c-text-subtle); }
.hb-input:focus, .hb-input:focus-within { border-color: var(--c-accent); box-shadow: var(--ring); }
.hb-input[aria-invalid="true"] { border-color: var(--c-bad); background: var(--c-bad-tint); box-shadow: 0 0 0 3px var(--c-bad-soft); }
.hb-input:disabled { background: var(--c-sunken); color: var(--c-text-subtle); cursor: not-allowed; }
.hb-input[readonly] { border-style: dashed; background: var(--c-surface-2); }
.hb-input[multiple] { height: auto; min-height: 96px; padding: var(--sp-1); }
.hb-select { position: relative; display: block; min-width: 0; }
.hb-select > select.hb-input { padding-inline-end: calc(var(--sp-3) * 2 + 14px); cursor: pointer; }
.hb-select > select[multiple] + .hb-select-caret { display: none; }
.hb-select-caret { position: absolute; inset-inline-end: var(--sp-3); top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--c-text-muted); }
.hb-field .hb-req { color: var(--c-bad); margin-inline-start: 2px; }
.hb-field > .hb-hint, .hb-field > .hb-error { font-size: var(--fs-xs); }

/* checkbox, radio and switch */
.hb-check { display: inline-flex; align-items: center; gap: var(--gap-sm); font-size: var(--fs-md); font-weight: 400; color: var(--c-text); cursor: pointer; }
.hb-check > input[type="checkbox"], .hb-check > input[type="radio"] { width: 18px; height: 18px; margin: 0; accent-color: var(--c-accent-fill); flex: none; cursor: pointer; }
.hb-check > input.hb-switch { appearance: none; -webkit-appearance: none; width: 40px; height: 22px; border-radius: var(--r-pill); background: var(--c-line-strong); position: relative; flex: none; cursor: pointer; transition: background .15s; }
.hb-check > input.hb-switch::after { content: ""; position: absolute; top: 3px; inset-inline-start: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--c-knob); transition: inset-inline-start .15s; }
.hb-check > input.hb-switch:checked { background: var(--select-bg); }
.hb-check > input.hb-switch:checked::after { inset-inline-start: 21px; }
.hb-check > input:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.hb-check > input:disabled { cursor: not-allowed; opacity: .5; }

/* chips, tabs and links used as controls */
a.hb-chip, a.hb-tab { text-decoration: none; }
.hb-chip:focus-visible, .hb-tab:focus-visible, .hb-nav-i:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; }
.hb-chip > .hb-count { opacity: .75; }

/* ---------- Dropdown menu (header-menus board: account and notification popovers) ------------------- */
.hb-dropdown { position: relative; display: inline-flex; }
.hb-menu { position: absolute; top: calc(100% + var(--sp-2)); inset-inline-end: 0; z-index: 30; min-width: 240px; padding: var(--sp-2); display: flex; flex-direction: column; gap: 2px; }
.hb-menu[hidden] { display: none; }
.hb-menu.hb-floating, .hb-menu.hb-start.hb-floating { position: fixed; inset: auto; margin: 0; z-index: 60; width: max-content; max-width: calc(100vw / var(--ui-zoom) - var(--sp-4)); max-height: calc(var(--vh-full) - var(--sp-7)); overflow-y: auto; }   /* placed by dropdown.js (R3) */
.hb-menu.hb-start { inset-inline-end: auto; inset-inline-start: 0; }
.hb-menu > .hb-nav-i, .hb-menu > form > .hb-nav-i { height: auto; min-height: var(--nav-item-h); white-space: nowrap; background: none; border: 0; width: 100%; font: inherit; font-size: var(--fs-md); text-align: start; cursor: pointer; color: var(--nav-fg); }
.hb-menu > .hb-nav-i:hover, .hb-menu > form > .hb-nav-i:hover { background: var(--nav-hover-bg); }
.hb-menu > .hb-nav-i.hb-danger, .hb-menu > form > .hb-nav-i.hb-danger { color: var(--c-bad); }
.hb-menu > .hb-sep { border-top: 1px solid var(--c-line); margin: var(--sp-1) 0; }
.hb-menu > form { display: contents; }
.hb-menu-head { display: flex; align-items: center; gap: var(--gap-md); padding: 10px 10px 12px; border-bottom: 1px solid var(--c-line); margin-bottom: 6px; }

/* ---------- Dialog (export-dialog board: modal frame on the overlay) -------------------------------- */
dialog.hb-modal, dialog.hb-modal * { box-sizing: border-box; }   /* the shared confirm dialog sits outside .hb-app */
dialog.hb-modal { border: 0; padding: 0; color: var(--c-text); font-family: var(--font-sans); max-height: calc(var(--vh-full) - 2 * var(--sp-6)); overflow: auto; }
dialog.hb-modal::backdrop { background: var(--c-overlay); }
dialog.hb-modal:not([open]) { display: none; }   /* Harbor's .modal sets display:flex, which would override the closed dialog's UA display:none */
.hb-modal-head > .hb-card-title { flex: 1; }
.hb-modal-foot > form { display: contents; }

/* ---------- Flash messages (session success / warning / error) --------------------------------------- */
.hb-flash { display: flex; flex-direction: column; gap: var(--gap-sm); }
.hb-alert > .hb-alert-body { flex: 1; min-width: 0; }
.hb-alert-close { background: none; border: 0; padding: 0; color: inherit; cursor: pointer; opacity: .7; display: inline-flex; }
.hb-alert-close:hover { opacity: 1; }
.hb-alert ul { margin: var(--sp-1) 0 0; padding-inline-start: var(--sp-5); }

/* ---------- Pagination (data-table board footer) ----------------------------------------------------- */
.hb-pager { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-xs); }
.hb-pager .hb-btn[aria-current="page"] { pointer-events: none; }

/* ---------- Form layout helpers ---------------------------------------------------------------------- */
.hb-form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-sm); }
.hb-root [hidden] { display: none !important; }   /* data-hb-when: a hidden field stays hidden inside its grid or flex row */
.hb-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

/* ---------- Shell helpers ---------------------------------------------------------------------------- */
.hb-topbar .hb-spacer { flex: 1; }
.hb-icon-badge { position: relative; }
.hb-icon-badge > .hb-badge { position: absolute; top: -6px; inset-inline-end: -6px; }
.hb-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.hb-skip { position: absolute; inset-inline-start: var(--sp-2); top: -100px; z-index: 50; }
.hb-skip:focus { top: var(--sp-2); }
button.hb-account { font-family: var(--font-sans); cursor: pointer; }   /* the account pill is the dropdown trigger */
.hb-side-user > .hb-who { line-height: var(--lh-tight); flex: 1; min-width: 0; }
.hb-side-user .hb-who-name { font-size: var(--fs-md); font-weight: 600; }
.hb-side-group-title > .hb-chev { display: inline-flex; transition: transform .15s; }
.hb-side-group-title[aria-expanded="false"] > .hb-chev { transform: rotate(90deg); }

/* ---------- Harbor macro styles as classes ----------------------------------------------------------
   The Jinja macros carried these as inline styles; in Laravel they are classes so pages never write style="". */
.hb-side { color: var(--sidebar-fg); background: var(--sidebar-bg); min-height: 100%; }                 /* sidebar.html */
.hb-table { min-width: var(--hb-table-min, 0px); }                                                       /* table.html min_width */
.hb-card-head > .hb-link, .hb-card-head .hb-row > .hb-link { font-size: var(--fs-sm); }                 /* data_table.html "more" link */
.hb-filter-bar { gap: var(--sp-4); }                                                                     /* filter_bar.html */
.hb-filter-card { padding: var(--sp-4); gap: var(--sp-3); }
.hb-action-item .hb-note { display: block; }                                                             /* action_item.html */
.hb-empty { height: 100%; }                                                                              /* empty_state.html */
.hb-empty-loading { align-items: stretch; }
.hb-empty-loading > .hb-skeleton:nth-child(1) { width: 60%; }
.hb-empty-loading > .hb-skeleton:nth-child(2) { width: 90%; }
.hb-empty-loading > .hb-skeleton:nth-child(3) { width: 75%; }
.hb-empty-loading > .hb-note { text-align: center; }
.hb-inline-form { display: inline-flex; margin: 0; }

/* ---------- Bar chart (main board: sales vs collected) ------------------------------------------------ */
.hb-chart { display: flex; flex-direction: column; gap: var(--gap-sm); }
.hb-chart-key { display: flex; flex-wrap: wrap; gap: var(--gap-xl); }
.hb-chart-key-i { display: inline-flex; align-items: center; gap: var(--gap-xs); }
.hb-chart-swatch { width: 10px; height: 10px; border-radius: var(--r-sm); display: inline-block; }
.hb-chart-bars { display: flex; align-items: flex-end; gap: min(18px, 3%); height: 220px; padding: 8px 8px 0; border-bottom: 1px solid var(--c-line); }
.hb-chart-col { flex: 1; min-width: 0; display: flex; align-items: flex-end; justify-content: center; gap: 5px; height: 100%; }
.hb-chart-bar { width: 34%; max-width: 30px; height: var(--hb-v, 0%); border-radius: var(--r-xs) var(--r-xs) 0 0; }
.hb-chart-single .hb-chart-bar { width: 60%; max-width: 40px; }   /* one series: the bar takes the room of the pair */
.hb-chart-labels { display: flex; gap: min(18px, 3%); padding: 0 8px; }
.hb-chart-labels > * { flex: 1; min-width: 0; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* a chart never widens its card */
@media (max-width: 1100px) { .hb-chart-dense .hb-chart-labels > :nth-child(even) { visibility: hidden; } }
.hb-s1 { background: var(--c-accent-2); }
.hb-s2 { background: var(--c-accent-fill); }

/* ---------- Page patterns (contract §3) --------------------------------------------------------------- */
/* P1 Dashboard (main board): roomier section gap, greeting head aligned to the bottom, the date as crumbs */
/* Latest-orders head: search box + button stay on one row so the head wraps at most once (title / actions) */
.hb-dash-search { flex-wrap: nowrap; }
.hb-dash-search .hb-input { width: 14rem; max-width: 100%; }
.hb-dashboard { display: flex; flex-direction: column; gap: var(--sp-6); }
/* Page content ~5% larger: every font-size token scales with --dash-scale (sidebar and topbar keep their size).
   Set on .hb-page, so every screen gets it and the dashboard inherits it. */
.hb-page {
  --dash-scale: 1.05;
  --fs-2xs: calc(11px * var(--dash-scale)); --fs-xs: calc(12px * var(--dash-scale)); --fs-sm: calc(13px * var(--dash-scale));
  --fs-md: calc(14px * var(--dash-scale)); --fs-lg: calc(16px * var(--dash-scale)); --fs-xl: calc(18px * var(--dash-scale));
  --fs-2xl: calc(20px * var(--dash-scale)); --fs-3xl: calc(24px * var(--dash-scale)); --fs-h1: calc(26px * var(--dash-scale));
  --fs-stat: calc(28px * var(--dash-scale)); --fs-display: calc(32px * var(--dash-scale));
}
.hb-dashboard > .hb-page-head { align-items: flex-end; }
.hb-dashboard > .hb-page-head .hb-crumbs { font-size: var(--fs-sm); }
.hb-dashboard .hb-tasks { flex: 1 1 340px; min-width: 0; }
.hb-dashboard .hb-trend { flex: 2 1 520px; min-width: 0; }   /* like .hb-col-main: never wider than the page */

/* ---------- Semantic variants added for the page patterns ---------------------------------------------
   One shared answer for what the boards drew with inline styles, so every page draws it the same way. */
.hb-toggle-row.hb-check { display: flex; justify-content: space-between; width: 100%; }               /* settings board toggle rows */
.hb-block-note { display: block; }
.hb-pre-line { white-space: pre-line; overflow-wrap: anywhere; }                                        /* free text keeping its line breaks (contact messages) */
.hb-row-total > .hb-td { font-weight: var(--weight-strong); background: var(--c-surface-2); }          /* report board totals rows */
.hb-num-end { text-align: end; }                                                                         /* money columns in reports */
.hb-toggle-list { display: flex; flex-direction: column; gap: var(--gap-lg); }

/* ---------- Choices as real radio inputs (order-new board) -------------------------------------------- */
.hb-choices > label { position: relative; display: inline-flex; }
.hb-choices > label > input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.hb-choices.hb-fill > label > span { width: 100%; }
.hb-choices > label > input:focus-visible + span { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* ---------- Password with show / hide (login board) ---------------------------------------------------- */
.hb-reveal { position: relative; display: grid; }
.hb-reveal > .hb-input { padding-inline-end: 72px; }
.hb-reveal-toggle { position: absolute; inset-inline-end: 12px; inset-block: 0; display: flex; align-items: center; background: none; border: 0; padding: 0; color: var(--c-accent); font: 600 var(--fs-sm)/1 var(--font-sans); cursor: pointer; }

/* ---------- P10 Auth (login board): form side + brand side, no shell ------------------------------------ */
.hb-auth { display: flex; flex-wrap: wrap; width: 100%; min-height: var(--vh-full); }
.hb-auth-form { flex: 1 1 440px; min-width: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 40px 24px; background: var(--c-surface); }
.hb-auth-box { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 18px; }
.hb-auth-box .hb-page-logo { display: flex; align-items: center; gap: var(--gap-lg); }
.hb-auth-box .hb-page-title + .hb-note { margin-top: 6px; font-size: var(--fs-md); }
.hb-auth-links { display: flex; justify-content: space-between; align-items: center; gap: var(--gap-sm); font-size: var(--fs-sm); }
.hb-auth-brand { flex: 1 1 440px; min-width: 0; min-height: 360px; display: flex; flex-direction: column; justify-content: space-between; background: var(--c-accent-fill); color: var(--c-on-accent); }
.hb-auth-pitch { padding: 48px 40px; display: flex; flex-direction: column; gap: var(--gap-xl); max-width: 520px; }
.hb-auth-pitch > img { height: 56px; width: auto; display: block; margin-bottom: 6px; }
.hb-auth-kicker { font-size: var(--fs-sm); font-weight: 600; opacity: .8; }
.hb-auth-headline { font-size: var(--fs-display); font-weight: 700; line-height: 1.3; }
.hb-auth-sub { font-size: var(--fs-lg); line-height: 1.9; opacity: .9; }
.hb-auth-photo { width: 100%; height: 300px; object-fit: cover; display: block; }

/* ---------- Real admin navigation (App\Support\AdminHarbor\Navigation) -------------------------------
   The legacy menu has second-level links; they open under their item in the same rail language. */
.hb-nav-node { display: flex; flex-direction: column; gap: 2px; }
.hb-nav-parent { width: 100%; background: none; border: 0; font: inherit; font-size: var(--fs-md); text-align: start; cursor: pointer; }
.hb-nav-parent > .hb-chev { display: inline-flex; margin-inline-start: auto; transition: transform .15s; opacity: .7; }
.hb-nav-parent[aria-expanded="false"] > .hb-chev { transform: rotate(90deg); }
.hb-nav-sub { display: flex; flex-direction: column; gap: 2px; padding-inline-start: calc(var(--sp-3) + 18px + var(--sp-3)); }   /* aligned with the parent's label */
.hb-nav-sub[hidden] { display: none; }
.hb-nav-child { height: auto; min-height: 32px; font-size: var(--fs-sm); }
.hb-nav-child.hb-on::before { inset-block: 6px; }
.hb-side-search { display: flex; align-items: center; gap: var(--gap-sm); height: var(--h-sm); padding: 0 var(--sp-3); border-radius: var(--radius-control); background: var(--rail-nav-hover-bg); color: var(--sidebar-muted); }
.hb-side-search > input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--sidebar-fg); font: inherit; font-size: var(--fs-sm); outline: none; }
.hb-side-search > input::placeholder { color: var(--sidebar-muted); }
.hb-side-search:focus-within { box-shadow: var(--ring); }

/* ---------- Topbar notification menu (header-menus board) --------------------------------------------- */
.hb-notifications > .hb-menu { width: min(380px, 92vw); }
.hb-panels { display: flex; flex-direction: column; gap: var(--gap-sm); }
.hb-panels > .hb-chips { padding: 0 var(--sp-1); }
.hb-panels [role="tabpanel"] { display: flex; flex-direction: column; gap: 2px; }
.hb-panels [role="tabpanel"][hidden] { display: none; }
.hb-menu > .hb-panels .hb-nav-i, .hb-panels .hb-nav-i { height: auto; min-height: var(--nav-item-h); white-space: normal; line-height: var(--lh-tight); padding-block: var(--sp-2); }
.hb-menu-empty { padding: var(--sp-3); }

/* ---------- Linked KPI (a stat card that opens its list, dashboard) ----------------------------------- */
a.hb-stat { color: inherit; text-decoration: none; transition: border-color .15s; }
a.hb-stat:hover { border-color: var(--c-accent-line); }
a.hb-stat:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* phones: the menu drops down as a list; a parent's sub-links are indented under it */
@media (max-width: 720px) {
  .hb-nav-node { display: flex; flex-direction: column; flex: none; }
  .hb-nav-sub { display: flex; flex-direction: column; padding-inline-start: var(--sp-4); }
  .hb-nav-child { height: 36px; white-space: nowrap; }
}

.hb-app .hb-input:focus-visible { outline: none; }   /* border + ring is the focus mark; .hb-app :focus-visible (base) outranks input.hb-input's outline: none and drew a second frame */
.hb-ajax-alert { grid-column: 1 / -1; }   /* the AJAX form alert (forms.js): spans a grid form, spaced from what follows */
form:not(.hb-stack):not(.hb-form-grid) > .hb-ajax-alert { margin-block-end: var(--sp-3); }

.hb-row.hb-nowrap { flex-wrap: nowrap; }   /* row actions stay on one line in a narrow table cell (the menu trigger does not drop below the button) */

/* ==== selection.css ==== */
/* Selection — the searchable customer picker (x-harbor.select remote, R1), row selection and its toolbar
   (x-harbor.bulk, x-harbor.bulk-cell, R2) and conditional fields (data-hb-when). Built from the Harbor tokens and the
   existing popover / menu / row-state looks; no new colours, sizes or radii. Contract: docs/admin-harbor/UI_CONTRACT.md §2. */

/* ---------- Combobox: a text box over a listbox popover (the menu items' look) ---------------------------- */
.hb-combo { position: relative; display: block; min-width: 0; }
.hb-combo > input.hb-input { padding-inline-end: calc(var(--sp-3) * 2 + 14px); }
.hb-combo-list { position: absolute; top: calc(100% + var(--sp-1)); inset-inline: 0; z-index: 30; display: flex; flex-direction: column; gap: 2px; padding: var(--sp-2); max-height: 280px; overflow-y: auto; }
.hb-combo-list[hidden] { display: none; }
.hb-combo-opt { display: flex; align-items: center; min-height: var(--nav-item-h); padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-control); font: 400 var(--fs-md)/var(--lh-tight) var(--font-sans); color: var(--nav-fg); cursor: pointer; overflow-wrap: anywhere; }
.hb-combo-opt:hover { background: var(--nav-hover-bg); }
.hb-combo-opt.hb-on { background: var(--c-accent-soft); color: var(--c-accent); font-weight: 600; }
.hb-combo-msg { padding: var(--sp-2) var(--sp-3); font-size: var(--fs-sm); color: var(--c-text-muted); }

/* ---------- Bulk selection: checkbox column and the toolbar above the table -------------------------------- */
.hb-th.hb-col-select, .hb-td.hb-col-select { width: 1%; padding-inline-end: 0; }
.hb-col-select > .hb-check { min-width: 24px; min-height: 24px; justify-content: center; }
/* on the selected row's tint the plain tones fall under 4.5:1 (e.g. "Remaining" in --c-warn, 4.2:1): use the strong ones */
.hb-row-selected .hb-t-warn { color: var(--c-warn-strong); }
.hb-row-selected .hb-t-bad { color: var(--c-bad-strong); }
.hb-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-sm); padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--c-line); background: var(--c-accent-soft); }
.hb-bulk[hidden] { display: none; }
.hb-bulk-count { font-size: var(--fs-sm); font-weight: 600; color: var(--c-accent); }
.hb-bulk > .hb-error { flex-basis: 100%; font-size: var(--fs-sm); color: var(--c-bad); }
.hb-bulk > .hb-error[hidden] { display: none; }

/* ---------- Conditional fields: hidden wins over the display of grids and stacks ---------------------------- */
.hb-root [data-hb-when][hidden] { display: none; }

/* ==== richtext.css ==== */
/* Rich text — x-harbor.rich-text (richtext.js). The TinyMCE frame takes the inputs' border, radius, focus ring and error
   state; its own skin (oxide / oxide-dark, chosen from the page theme) draws the toolbar and the editing area. The plain
   textarea (no JavaScript, or the editor failed to load) is a tall code-like box. Contract: docs/admin-harbor/UI_CONTRACT.md §4. */
.hb-root textarea.hb-richtext { min-height: 240px; }
.hb-root .tox.tox-tinymce { width: 100%; max-width: 100%; border: 1px solid var(--input-line); border-radius: var(--radius-control); }
.hb-root .tox.tox-tinymce:focus-within { border-color: var(--c-accent); box-shadow: var(--ring); }
.hb-root .tox.tox-tinymce.hb-richtext-invalid { border-color: var(--c-bad); box-shadow: 0 0 0 3px var(--c-bad-soft); }

/* ==== menubuilder.css ==== */
/* Menu builder (menubuilder.js, screen admin.menu-builder): the website menu as a list of rows with one sub-level, the
   built-in menus list of the side panel, and the drag-and-drop marks. Tokens only; logical properties (RTL and LTR). */
.hb-menu-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.hb-menu-node > .hb-menu-list { margin-block-start: var(--sp-2); margin-inline-start: var(--sp-6); padding-inline-start: var(--sp-3);
  border-inline-start: 2px solid var(--c-line); }
.hb-menu-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; min-height: var(--h-md);
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-line); border-radius: var(--radius-control); background: var(--c-surface); }
.hb-menu-text { flex: 1 1 10em; min-width: 0; overflow-wrap: anywhere; display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.hb-menu-tools { display: inline-flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap; }
.hb-menu-tools .hb-inline-form { display: inline-flex; }
.hb-menu-handle { display: inline-flex; color: var(--c-text-muted); cursor: grab; }
.hb-menu-node[draggable="true"] > .hb-menu-row { cursor: grab; }
.hb-menu-up .hb-icon, .hb-menu-up svg { transform: rotate(180deg); }
.hb-menu-node.hb-dragging > .hb-menu-row { opacity: .5; }
.hb-menu-row.hb-drop-before { box-shadow: inset 0 3px 0 var(--c-accent-fill); }
.hb-menu-row.hb-drop-after { box-shadow: inset 0 -3px 0 var(--c-accent-fill); }
.hb-menu-node.hb-menu-editing > .hb-menu-row { border-color: var(--c-accent-line); background: var(--c-accent-soft); }

/* ==== media.css ==== */
/* Media — x-harbor.gallery (gallery.js: the multi-image uploader of the service and product forms), x-harbor.map-picker
   (mappicker.js: the inline Google map of the service forms) and stored rich text shown read-only (a ticket and its
   replies: .hb-rich-view, a conversation list .hb-thread), and .hb-narrow for a short number typed in a table cell (the order
   numbers of the withdraw form builder). Tiles are square-cornered like every Harbor tile; the drop zone
   is the dashed box the tokens reserve for it; the map takes a fixed height inside its card. Contract:
   docs/admin-harbor/batch-16.md (proposed UI_CONTRACT rows). */
.hb-gallery { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.hb-gallery-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: var(--sp-3); }
.hb-gallery-list:empty { display: none; }
.hb-gallery-item { position: relative; display: flex; flex-direction: column; border: 1px solid var(--c-line); border-radius: var(--radius-tile); background: var(--c-surface-2); overflow: hidden; }
.hb-gallery-item img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--c-sunken); }
.hb-gallery-item .hb-btn { position: absolute; inset-block-start: var(--sp-1); inset-inline-end: var(--sp-1); }
.hb-gallery-state { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-xs); color: var(--c-text-muted); overflow-wrap: anywhere; }
.hb-gallery-item.hb-is-busy img { opacity: .55; }
.hb-gallery-item.hb-is-error { border-color: var(--c-bad); }
.hb-gallery-item.hb-is-error .hb-gallery-state { color: var(--c-bad); }
.hb-gallery-drop { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-1); min-height: 120px; padding: var(--sp-6) var(--sp-4); border: 1px dashed var(--c-line-strong); border-radius: var(--radius-tile); background: var(--c-surface-2); color: var(--c-text-2); font-size: var(--fs-sm); font-weight: 600; text-align: center; cursor: pointer; }
.hb-gallery-drop:hover, .hb-gallery-drop.hb-is-over { border-color: var(--c-accent); background: var(--c-accent-soft); }
.hb-gallery-drop:focus-within { border-color: var(--c-accent); box-shadow: var(--ring); }
.hb-gallery-drop .hb-note { font-weight: 400; }

.hb-map { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.hb-map-canvas { width: 100%; height: 360px; border: 1px solid var(--c-line); border-radius: var(--radius-tile); background: var(--c-sunken); }
.hb-map-canvas[hidden] { display: none; }

.hb-rich-view { min-width: 0; line-height: var(--lh-body); overflow-wrap: anywhere; }
.hb-rich-view > :first-child { margin-block-start: 0; }
.hb-rich-view > :last-child { margin-block-end: 0; }
.hb-rich-view img, .hb-rich-view iframe { max-width: 100%; height: auto; }
.hb-rich-view table { max-width: 100%; border-collapse: collapse; }
.hb-thread { list-style: none; margin: 0; padding: 0; }
.hb-input.hb-narrow { inline-size: 6em; max-inline-size: 100%; }
