/* =============================================================================
   GLOBAL TYPE SCALE — one place that decides how big text is, app-wide
   -----------------------------------------------------------------------------
   The app had 1128 hardcoded `font-size` declarations spread over 36
   stylesheets (base was 14px in desktop-app.css), so changing the base alone
   changed almost nothing. This layer is loaded LAST on every page and
   normalises all of them onto one scale.

   Body text is 12px. Everything else is a deliberate exception: a totals
   figure, a page title and a micro caption are NOT the same size as a table
   cell, and flattening them to 12px is what makes a screen look dead.

   HOW IT WORKS
   ------------
   1. The blanket rule below is wrapped in :where(), so it carries almost no
      specificity (0,0,1) even though it uses !important.
   2. Every exception underneath is a normal class selector (0,1,0+), so it
      beats the blanket rule without needing tricks.
      => To make anything bigger, just add a line to the right block. You do
         not need to hunt down the original declaration.

   TUNING
   ------
   Change the variables in :root and the whole app follows. Settings ->
   Project fonts (includes/project_fonts.php) also rewrites these variables at
   runtime, so an admin can rescale the app without touching this file.
   ============================================================================= */

:root {
    /* Body text — table cells, labels, inputs, buttons, nav, everything plain */
    /* ONE font stack for the whole app.
       Five competing stacks had grown up - desktop-app.css, riosoft-theme (three
       of its own) and the POS stylesheets each declared one - so purchase.php
       read in Tajawal, sale.php in IBM Plex Sans Arabic and
       purchase_manual_return.php in Noto Sans Arabic, none matching the
       dashboard. They all resolve here now.
       Settings -> Project fonts overrides this at runtime: that CSS is emitted
       after this file and carries !important, so it still wins. */
    --app-font-family: 'Vazirmatn', 'Noto Sans Arabic', 'IBM Plex Sans Arabic',
                       'Tajawal', 'Inter', 'Segoe UI Variable', 'Segoe UI',
                       system-ui, -apple-system, Tahoma, Arial, sans-serif;

    --app-font-size: 12px;

    /* Micro: uppercase captions, hints, footnotes */
    --app-font-xs: 10px;
    --app-font-sm: 11px;

    /* Emphasis: figures that must read at a glance, section heads */
    --app-font-md: 13px;
    --app-font-lg: 15px;

    /* Display: grand totals, KPI/stat numbers */
    --app-font-xl: 18px;
    --app-font-display: 22px;

    /* Data grids. Settings -> Project fonts "Table" size drives this one; the
       header and dense tiers are derived from it so a grid keeps its internal
       hierarchy at any setting instead of flattening to one size. */
    --app-font-table: var(--app-font-size);
    --app-font-table-head: max(9px, calc(var(--app-font-table) - 1px));

    /* Compact ERP grids (the sales-orders workspace) sit a step below a normal
       table: they show 15+ columns at once and were authored at 11px cells /
       10px headers against this scale. */
    --app-font-table-dense: max(11px, calc(var(--app-font-table) - 2px));
    --app-font-table-dense-head: max(10px, calc(var(--app-font-table) - 3px));

    /* The summary strip under a dense grid: a reading size, not a hero figure. */
    --app-font-grid-stat: var(--app-font-md);
}

@media screen {

    /* NOTE: the root font-size is deliberately left alone. Setting `html` to
       12px would rescale every `rem` in the app (164 of them across 9
       stylesheets) by 0.75 and silently shrink paddings and heights that have
       nothing to do with type. Body text is set on `body` instead. */
    body {
        font-size: var(--app-font-size) !important;
        font-family: var(--app-font-family) !important;
    }

    /* -------------------------------------------------------------------------
       FAMILY - same shape as the size rule below: a :where() blanket so it stays
       trivial to override, with the same icon exclusions. Font Awesome /
       Bootstrap Icons / Material render their glyphs THROUGH font-family, so
       forcing the text face onto them turns every icon into a stray letter.
       Monospace is preserved too: a figure lined up in a code or number column
       is deliberate, not an accident.
       ---------------------------------------------------------------------- */
    body *:where(:not(
        i, svg, svg *, canvas,
        .fa, .fas, .far, .fal, .fab,
        [class*="fa-"], [class*="bi-"],
        [class*="icon"], [class*="logo"], [class*="close"],
        .material-icons, .material-symbols-outlined,
        pre, code, kbd, samp, pre *, code *,
        .mono, [class*="mono"],
        [style*="monospace"], [style*="Consolas"], [style*="Courier"],
        [data-keep-font], [data-keep-font] *,
        .keep-font, .keep-font *
    )) {
        font-family: var(--app-font-family) !important;
    }

    /* -------------------------------------------------------------------------
       ICON FONTS - restore them explicitly.
       Bootstrap Icons declare their face on ::before, so the blanket above never
       touched them. Font Awesome declares it on the ELEMENT (.fas, .far, ...),
       which the `:lang(ku) { ... !important }` rule in riosoft-theme.css has been
       overriding since long before this layer existed - every FA glyph on a
       Kurdish page was rendering as a stray letter. These selectors carry the
       same specificity as :lang() and load later, so they win.
       ---------------------------------------------------------------------- */
    .fa, .fas, .far, .fal, .fad,
    [class^="fa-"], [class*=" fa-"] {
        font-family: "Font Awesome 6 Free", "Font Awesome 6 Pro",
                     "Font Awesome 5 Free", "FontAwesome" !important;
    }
    .fab, [class^="fa-brands"], [class*=" fa-brands"] {
        font-family: "Font Awesome 6 Brands", "Font Awesome 5 Brands" !important;
    }
    .bi, [class^="bi-"], [class*=" bi-"],
    .bi::before, [class^="bi-"]::before, [class*=" bi-"]::before {
        font-family: "bootstrap-icons" !important;
    }
    .material-icons, .material-symbols-outlined {
        font-family: "Material Icons", "Material Symbols Outlined" !important;
    }

    /* -------------------------------------------------------------------------
       BASELINE — every text element lands on 12px.
       Wrapped in :where() so it is trivially easy to override (see exceptions).
       Icon glyphs are skipped: Font Awesome / Bootstrap Icons / Material size
       their glyphs with font-size, so forcing 12px would shrink every icon,
       close button and empty-state illustration in the UI.
       ---------------------------------------------------------------------- */
    body *:where(:not(
        i, svg, svg *, canvas,
        .fa, .fas, .far, .fal, .fab,
        [class*="fa-"], [class*="bi-"],
        [class*="icon"], [class*="logo"], [class*="close"],
        .material-icons, .material-symbols-outlined,
        [data-keep-font-size], [data-keep-font-size] *,
        .keep-font-size, .keep-font-size *
    )) {
        font-size: var(--app-font-size) !important;
    }

    /* -------------------------------------------------------------------------
       DISPLAY — the number the user actually came to read.
       Grand totals, KPI tiles, stat cards.
       ---------------------------------------------------------------------- */
    /* The headline figure of a screen: invoice grand total, dashboard KPI. */
    .sp-row.grand .sp-row-value,
    .pos-totals-row.grand .pos-totals-value,
    .stat-value,
    .hr-stat-value {
        font-size: var(--app-font-display) !important;
        line-height: 1.15;
    }

    /* Supporting figures: summary tiles, per-zone counts, secondary totals. */
    .purchase-summary-metric.tp-grand .tp-grand-value,
    .ws-stat .ws-stat-value,
    .win-stat-card .value,
    .summary-tile .value,
    .zone-stat .value,
    .dispatch-summary .summary-value,
    .win-summary-item .count,
    .stat-info h3,
    .tile h3 {
        font-size: var(--app-font-xl) !important;
        line-height: 1.2;
    }

    /* -------------------------------------------------------------------------
       TITLES — page, panel, card, modal.
       ---------------------------------------------------------------------- */
    .page-title,
    .page-header .page-title,
    .page-title-bar h1,
    .cashvan-page-title h1,
    .content-header .title,
    .modal-title,
    .price-error-title,
    .panel-title,
    .card-header,
    .card-title,
    .section-title,
    .empty-state-title,
    .hr-hero h1,
    .hr-profile-title,
    .brand-text h1,
    .sidebar-brand h1,
    .topbar .title,
    .pos-empty h4,
    .win-input.large,
    .win-numpad button,
    .sp-payment .sp-row input,
    #paidAmountInput {
        font-size: var(--app-font-lg) !important;
    }

    /* -------------------------------------------------------------------------
       EMPHASIS — secondary headings, money cells in a row, primary actions.
       Big enough to anchor the eye, small enough to stay in the layout.
       ---------------------------------------------------------------------- */
    /* Top navigation. The blanket flattened it to body size, which made the
       menu read noticeably smaller than the rest of the chrome around it - the
       bar is the one thing on screen the user aims at from every page, so it
       gets the emphasis tier. Listed here rather than in topnav.css so the whole
       type scale still moves from one place. */
    .tn-txt,
    .tn-link,
    .tn-brand-text,
    .tn-brand-name,

    .van-bar-stat .value,
    .sp-head,
    .sp-row.grand .sp-row-label,
    .sp-btn.primary,
    .pos-line-total,
    .pos-qty-value,
    .pos-btn-save,
    .pos-btn-del,
    .pos-search-item-price .main,
    .sp-disc-row input,
    #totalBaseDisplay,
    .remaining-value,
    .brand-text p,
    h2, h3 {
        font-size: var(--app-font-md) !important;
    }

    /* -------------------------------------------------------------------------
       MICRO — captions above a field, hints, footnotes. These read as noise at
       12px next to real content, so they stay deliberately quiet.
       ---------------------------------------------------------------------- */
    .cashvan-page-subtitle,
    .sp-notes-label,
    .sp-print-label,
    .sp-print-hint,
    .form-hint,
    .field-hint,
    .text-muted small,
    .status-bar,
    .status-item,
    figcaption,
    small {
        font-size: var(--app-font-sm) !important;
    }

    /* -------------------------------------------------------------------------
       DATA TABLES — cells follow the "Table" size setting, headers sit one
       step below so a grid never reads as one flat block of text.
       ---------------------------------------------------------------------- */
    table,
    .data-table,
    .table,
    .report-table,
    table td,
    .data-table td,
    .table td {
        font-size: var(--app-font-table) !important;
    }

    table th,
    .data-table th,
    .table th,
    .report-table th {
        font-size: var(--app-font-table-head) !important;
    }

    /* Whatever sits inside a cell (the order-number link, the bold customer
       name, a wrapping span) takes the cell's size. Without this the baseline
       rule caught those descendants directly and a "11px" grid still rendered
       its links and names at body size. `td *` scores 0,0,2 so it beats the
       baseline (0,0,1) but loses to every class tier below, which is how
       badges and amounts keep their own sizes. */
    td *:where(:not(i, svg, svg *, [class*="fa-"], [class*="bi-"], [class*="icon"], [data-keep-font-size], .keep-font-size, .keep-font-size *)),
    th *:where(:not(i, svg, svg *, [class*="fa-"], [class*="bi-"], [class*="icon"], [data-keep-font-size], .keep-font-size, .keep-font-size *)) {
        font-size: inherit !important;
    }

    /* -------------------------------------------------------------------------
       DENSE WORKSPACE GRIDS — the sales-orders workspace packs a toolbar, a
       15-column grid and a stats strip into one viewport. Flattening it to body
       size made it read as "large text" and cost about three rows of data.
       Everything here is derived from the same Table setting, so it still moves
       with Settings -> Project fonts.
       ---------------------------------------------------------------------- */
    body.so-workspace .data-table,
    body.so-workspace .data-table td,
    .vo-table,
    .vo-table td {
        font-size: var(--app-font-table-dense) !important;
    }
    body.so-workspace .data-table th,
    .vo-table th {
        font-size: var(--app-font-table-dense-head) !important;
    }
    body.so-workspace .search-bar input,
    body.so-workspace .search-input-wrapper input,
    body.so-workspace .filter-select,
    body.so-workspace .filter-check,
    body.so-workspace .so-filter-delegate .ss-toggle,
    body.so-workspace .filter-chip,
    body.so-workspace .clear-all-btn,
    body.so-workspace .load-note,
    body.so-workspace .search-count,
    body.so-workspace .bulk-actions-bar,
    body.so-workspace .bulk-actions-bar .btn,
    body.so-workspace .status-badge,
    body.so-workspace .amount-secondary {
        font-size: var(--app-font-sm) !important;
    }
    /* The bottom stats strip is a summary bar, not a dashboard hero: it stays a
       reading size rather than jumping to the display tier. */
    body.so-workspace .stats-after-table .stat-value {
        font-size: var(--app-font-grid-stat) !important;
    }
    body.so-workspace .stats-after-table .stat-label {
        font-size: var(--app-font-sm) !important;
    }

    /* Van Orders (modules/van_orders/index.php) is the same kind of screen as the
       sales-orders workspace — toolbar, dense grid, stats strip — but it ships
       its own `.vo-*` component set sized in rem, so it needs the same tiers
       named explicitly. Both screens now move with the one Table setting. */
    .vo-toolbar select,
    .vo-toolbar .vo-search input,
    .vo-toolbar .vo-results-label,
    .vo-badge,
    .vo-pill,
    .vo-meta,
    .vo-doc-type,
    .vo-risk-tag,
    .vo-btn,
    .vo-chip,
    .vo-page-header .vo-count-badge,
    .vo-page-header .vo-breadcrumb,
    .vo-settlement-btn,
    .vo-settlement-status,
    .vo-rep-row,
    .vo-rep-actions a,
    .vo-rep-card-head strong,
    .vo-rep-card-head span,
    .vo-mix-context,
    .vo-mix-meta-line,
    .vo-mix-doc-links,
    .vo-modal-header .vo-meta {
        font-size: var(--app-font-sm) !important;
    }
    .vo-stat-value,
    .vo-ops-metric .value,
    .vo-mix-net {
        font-size: var(--app-font-grid-stat) !important;
    }
    .vo-stat-label,
    .vo-ops-metric .label,
    .vo-ops-head span {
        font-size: var(--app-font-xs) !important;
    }
    .vo-page-header h1,
    .vo-modal-header h3,
    .vo-ops-head h2 {
        font-size: var(--app-font-lg) !important;
    }
    .vo-btn-submit,
    .vo-btn-clear,
    .vo-btn-cancel,
    .vo-modal-body textarea,
    .vo-alert,
    .vo-empty p,
    .vo-disabled-panel {
        font-size: var(--app-font-md) !important;
    }

    /* -------------------------------------------------------------------------
       SEARCH RESULT DROPDOWNS — product/customer/invoice pickers.
       Roughly a dozen screens each rolled their own dropdown with its own
       hardcoded px (10 / 10.5 / 11 / 12 / 13 / 14), which is why the code line
       under a product name used to ignore the font settings entirely. They all
       share the same three roles, so they all bind to the same variables:
         name / primary line -> md
         code, meta, badges  -> sm
         price figure        -> md
       ---------------------------------------------------------------------- */
    .pos-search-item-info h4,
    .tv-search-item .pname,
    .psearch .pname,
    .do-search-item-info h4,
    .adj-search-item .s-name,
    .search-item .item-name,
    .invoice-search-item .inv-number,
    .ss-option,
    .psearch .pnm,
    .psearch .pprice,
    .do-search-item-price .main,
    .invoice-search-item .inv-total,
    .search-item .item-prices .main-price {
        font-size: var(--app-font-md) !important;
    }

    .pos-search-item-info .meta,
    .tv-search-item .pmeta,
    .tv-search-item .pstock,
    .psearch .pmeta,
    .adj-search-item .s-code,
    .adj-search-item .s-stock,
    .adj-search-item .s-added,
    .search-item .item-code,
    .search-item .item-unit,
    .invoice-search-item .inv-date,
    .invoice-search-item .inv-supplier,
    .do-search-item-price .sub,
    .pos-search-item-price .sub,
    .pos-search-item-price .cost-price,
    .cs-meta,
    .dsr-meta,
    .er-customer-item .er-cs-meta,
    .rv-customer-item .rv-cs-meta,
    .psearch .pright,
    .psearch .pstock,
    .psearch .pempty,
    .stock-badge,
    .unit-badge,
    .qty-badge {
        font-size: var(--app-font-sm) !important;
    }

    /* Escape hatch: `class="keep-font-size"` or `data-keep-font-size` on an
       element leaves that element AND its whole subtree on their own sizes.
       Used by the live type preview in Settings -> Project fonts, which has to
       render the admin's chosen sizes rather than the app's. */
}

/* Printing keeps the original per-page sizes — receipts, invoices and report
   sheets are laid out for paper, not for the screen. That is why every block
   above sits inside @media screen. */

/* iOS zooms the viewport whenever a focused text field is under 16px. Touch
   devices keep 16px on the fields themselves so tapping an input does not jump
   the page. Delete this block if you want a literal 12px there too. */
@media screen and (pointer: coarse) {
    body input[type="text"],
    body input[type="number"],
    body input[type="search"],
    body input[type="tel"],
    body input[type="email"],
    body input[type="password"],
    body input[type="date"],
    body textarea,
    body select {
        font-size: 16px !important;
    }
}
