/* ============================================================================
   INNOVOTE INVENTORY — VIEW 3 OF 3: «كمبيوتر بالماوس» · THE MOUSE DESKTOP

   A 1440 px window, a mouse, a chair, and a person who wants to see more than
   eleven rows at a time. This is the view PR #20 built; every number in this
   file arrived there and is UNCHANGED, including the reasoning, which is
   reproduced verbatim so a reviewer can diff the two files and account for
   every line. What changed is only where it lives and how it is switched on —
   see tokens.css §4b for the three-view rule and the link contract.

   WHEN THIS FILE IS LOADED. The server writes exactly one of two things:

     · nobody has chosen a view      <link media="screen and (((pointer: fine)
                                            and (hover: hover)) or (pointer: none))">
     · this person chose «كمبيوتر»   <link media="screen">

   In the first case the condition below is the whole of the detection. In the
   second there is no condition, because the person has already answered the
   question the condition exists to guess at. Either way the answer is in the
   FIRST BYTE of the response: no media query can be overridden by a preference,
   and no preference applied by JavaScript can avoid painting the wrong size
   first.

   `screen` is on the link in BOTH cases, and it is not decoration. Without it a
   count sheet printed from the desk and the same sheet printed from the phone
   would come out at different type sizes, because the print tokens in
   tokens.css §5 override colour and never touched the scale. One document, one
   rendering.

   THE CONDITION, AND WHY IT IS THIS ONE.

     screen and (((pointer: fine) and (hover: hover)) or (pointer: none))

   Read it as the rule it states: THE COARSE POINTER NEVER GETS THIS FILE.
   `pointer` and `hover` describe the PRIMARY input — the device the operating
   system believes the person is actually using. It is the only signal CSS has
   about intent, and it is the signal this feature was added to CSS for.

   Width was considered and rejected as the condition. A 1024 px tablet on a
   forklift is still touched. Some rugged Android tablets report 1280 logical
   pixels in landscape and are still touched, with a glove. A 1280 px laptop
   with a trackpad is not. Sizing on width alone would have handed a mouse's
   accuracy to a glove, and would have been invisible in review because the
   reviewer has a mouse.

   HYBRIDS, DECIDED DELIBERATELY. `not (any-pointer: coarse)` was considered and
   rejected. Nearly every Windows laptop sold since about 2019 has a
   touchscreen, so `any-pointer: coarse` is true on them; adding it to the
   condition would mean this file almost never loads on the machines it exists
   for. What matters is which device is PRIMARY:

     · rugged phone, warehouse tablet, forklift terminal
       -> primary is coarse -> this file does not load, at ANY width.
     · touchscreen laptop with a trackpad, iPad with a keyboard case
       -> primary is fine -> this file loads. Somebody attached a pointing
          device; that is a statement of intent. If they then reach up and touch
          the screen, the smallest control is 32 px — a bare finger on a desk at
          40 cm, and still 33 % above the 24 px WCAG 2.2 AA minimum (SC 2.5.8).
          And if that is the wrong call for them, «لابتوب باللمس» is one tap
          away and it sticks: see /screen.
     · desktop, laptop with a trackpad, any browser window at any width
       -> primary is fine -> this file loads.
     · a device with NO pointing device at all — `(pointer: none)` — a
       keyboard-only kiosk, an assistive setup driving the page from the
       keyboard, or a headless renderer. Nothing is being aimed at anything, so
       a 48 px target buys nobody anything and a denser page is strictly more
       useful. This clause was ADDED after CI proved it was load-bearing, and
       the story is worth keeping: a GitHub runner has no mouse, so Chrome
       answers `pointer: none` — correctly — in BOTH of its headless modes. The
       original condition therefore never matched there, the desk density was
       never rendered in CI, and the harness said so on the first run rather
       than reporting a clean matrix for a page it had never drawn.

   `and (hover: hover)` qualifies the FINE arm on purpose. A stylus reports
   `pointer: fine` and `hover: none`, and a stylus is held in a hand at the
   distance a finger is. Requiring hover keeps the pen out.

   THE LEVEL-4 `or` IS DELIBERATE AND SO IS ITS FALLBACK. `or` inside a media
   condition needs Chrome 88 / Firefox 74 / Safari 16.4. A browser too old to
   PARSE this condition does not match it — the link is fetched and never
   applied — and not applying means the phone view, which is the safe direction
   and the reason it is written this way round rather than as a negation.

   HOW THE SCALE WAS BUILT: the small end does not move.
   `--fs-micro` (11 px) through `--fs-xs` (13 px) are unchanged, and `--sp-1`
   and `--sp-2` are unchanged, because they are already at their floor — 11 px
   is the smallest legal label in this system and 4 px is not a gap that can be
   halved. Everything above them compresses. On a phone the top of the scale is
   large so it can be read while moving; at a desk it is large only to establish
   hierarchy, and hierarchy survives a tighter ratio because a seated eye at a
   fixed distance resolves differences a moving one cannot.

   Everything here is still rem, for the same reason as everything in tokens.css
   §4: a person who turns the OS text size up gets a bigger target, not a
   clipped one.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   1. TOKENS
   ------------------------------------------------------------------------ */
:root {
  /* --- TARGETS -------------------------------------------------------
     32 px is the floor a mouse acquires in one movement, and it is the number
     this project's own brief names. WCAG 2.2 SC 2.5.8 (AA) asks for 24 px, so
     there is a third of the target in hand.
     40 px for a row or an input, because a text field has to look like a text
     field: 32 px minus 2 x 8 px of padding leaves no room for a 15 px label to
     sit in.
     44 px for the one primary action per screen. On a mouse the primary action
     needs to be DISTINGUISHABLE rather than large — and 44 px is still WCAG
     2.5.5 AAA Target Size (Enhanced), so the biggest thing on the desk clears
     the strictest bar in the standard. */
  --tap:      2rem;       /* 48 -> 32 */
  --tap-lg:   2.5rem;     /* 56 -> 40 */
  --tap-xl:   2.75rem;    /* 64 -> 44 */
  --tap-gap:  0.25rem;    /*  8 ->  4 — a mouse does not hit two at once */

  /* --- TYPE ----------------------------------------------------------
     17 px body exists because of reading CONDITIONS — standing, moving, dim,
     arm's length, one hand — and not because of distance. At a desk those
     conditions are gone and 15 px is the desktop body this brand's own
     marketing type sits at. micro / 2xs / xs are deliberately absent from this
     list. */
  --fs-sm:     0.875rem;   /* 15 -> 14 — dense table cells */
  --fs-md:     0.9375rem;  /* 17 -> 15 — BODY DEFAULT */
  --fs-lg:     1.0625rem;  /* 20 -> 17 — card titles, list primary */
  --fs-xl:     1.3125rem;  /* 24 -> 21 — screen titles */
  --fs-2xl:    1.625rem;   /* 30 -> 26 — section headings */
  --fs-3xl:    2rem;       /* 38 -> 32 — page display */

  /* The data sizes come down further than the body does, because on the phone
     they are large enough to read while walking and here they only have to
     out-rank the row they sit in. `--fs-addr` stays the most prominent
     monospaced thing on a search result, which is its whole job. */
  --fs-qty:    1.375rem;   /* 28 -> 22 */
  --fs-qty-lg: 2.125rem;   /* 44 -> 34 */
  --fs-addr:   1.125rem;   /* 22 -> 18 */

  /* Leading. 1.55 is generous for a 17 px line read while moving; at 15 px on a
     desk it is loose, and loose leading is the single biggest reason a list of
     forty rows only shows eleven. */
  --lh-snug:   1.3;
  --lh-body:   1.45;

  /* --- SPACE ---------------------------------------------------------
     sp-1 and sp-2 hold. Everything above them compresses, hardest in the middle
     of the scale, because sp-3 and sp-4 are the row and card padding and that
     is where the rows come from. */
  --sp-3:  0.5rem;     /* 12 ->  8 */
  --sp-4:  0.75rem;    /* 16 -> 12 */
  --sp-5:  0.875rem;   /* 20 -> 14 */
  --sp-6:  1rem;       /* 24 -> 16 */
  --sp-7:  1.375rem;   /* 32 -> 22 */
  --sp-8:  1.75rem;    /* 40 -> 28 */
  --sp-9:  2rem;       /* 48 -> 32 */
  --sp-10: 2.5rem;     /* 64 -> 40 */

  /* --- SHAPE ---------------------------------------------------------
     A 14 px radius on a 32 px control is a quarter of the control. Large radii
     are the most recognisable phone tell there is; the brand's own desktop
     marketing uses tighter corners than its app does. */
  --r-sm: 8px;    /* 10 ->  8 */
  --r-md: 10px;   /* 14 -> 10 */
  --r-lg: 14px;   /* 20 -> 14 */

  /* --- CHROME --------------------------------------------------------
     Every one of these is a band of colour across the whole window. A 56 px app
     bar and an 80 px action bar are 136 px of a 800 px laptop viewport spent on
     furniture. */
  --appbar-h:   3rem;      /* 56 -> 48 */
  --tabbar-h:   3.25rem;   /* 64 -> 52 */
  --actionbar-h:3.75rem;   /* 80 -> 60 */

  /* --- MEASURE ---------------------------------------------------------
     A width that only exists away from a phone, which is why it is here and not
     beside `--w-content`. A task screen carries no sidebar and no content
     wrapper on purpose — a task is a focused screen, and on a phone focused
     means edge to edge. On a 1280 px window it meant a receive form 1240 px
     wide with a 1240 px amber button pinned under it. `--w-content` is the
     wrong answer for it: 1120 px is a dashboard, not a form. */
  --w-task: 44rem;         /* 704 px — one task, one glance */
}

/* Arabic, restated. `:root:lang(ar), [dir="rtl"]` in tokens.css §2 sets
   `--lh-body: var(--lh-arabic)` at one-class specificity and matches the SAME
   element as `:root` above. Source order saves it here — this file is linked
   after tokens.css — but stating it is what keeps it true if the link order
   ever changes, and Cairo needs the room named rather than inherited: 1.7
   rather than 1.85, still well clear of the 1.5 the Brand Manual treats as the
   Latin figure. */
:root:lang(ar), [lang="ar"], [dir="rtl"] {
  --lh-arabic: 1.7;
  --lh-body: var(--lh-arabic);
  --lh-snug: 1.4;
}

/* ---------------------------------------------------------------------------
   2. WHAT THE TOKEN LAYER COULD NOT REACH
   Almost all of the density arrives through the tokens above, because every
   rule in components.css references them. This section is only the residue:
   the places where a number is written in the component because it is a RATIO
   to something rather than a step on a scale — a glyph inside a button, a
   thumbnail beside a name, the width of a rail.

   A glyph is the clearest case. `.iconbtn__glyph` is 1.25rem inside a target
   that was 48 px and is now 32: unchanged, the glyph goes from 42 % of its
   button to 63 % and the button reads as a badge rather than as a control.
   Nothing in the token layer can know that.

   TWO NUMBERS IN components.css ARE NOT ALLOWED TO MOVE, at any density:
   `.logo--wordmark { min-width: 120px }` and `.logo--mark { width: 24px }`.
   Those are the brand's published on-screen minimums, not app sizing, and a
   mouse does not make a wordmark legible at 90 px.
   ------------------------------------------------------------------------ */

/* Glyphs, each sized to the control it sits in rather than to a scale. */
.iconbtn__glyph   { font-size: 1rem; }
.tabbar__glyph    { font-size: 1.1rem; }
.shortcut__glyph  { font-size: 1.15rem; }
.fromto__arrow    { font-size: 1.15rem; }
.notice__glyph    { font-size: 1rem; }
.who__go          { font-size: 1rem; }
.empty__glyph,
.scan__glyph      { font-size: 1.75rem; }
.doccard--add .doccard__thumb { font-size: 1.35rem; }

/* Fixed-size objects: a picture beside a name, a face, a page thumbnail. */
.pid--result .thumb { inline-size: 2rem; block-size: 2rem; }
.pid--header .thumb { inline-size: 3.25rem; block-size: 3.25rem; }
.who__face          { inline-size: 2rem; block-size: 2rem; }
.auth__mark         { inline-size: 3rem; }
.doccard            { inline-size: 5.25rem; }
.viewer__pagethumb  { inline-size: 2rem; }
.sw__chip           { block-size: 2.5rem; }
.colpick__row input { inline-size: 1.1rem; block-size: 1.1rem; }
.dash__addslot      { min-height: 5.5rem; }

/* Auto-fit tracks. The minimum in each of these was chosen against the phone's
   type; against 15 px body they leave a column of white. */
.shortcuts              { grid-template-columns: repeat(auto-fit, minmax(4.5rem, 1fr)); }
.gal__swatches          { grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr)); }
.pid--header .pid__stats{ grid-template-columns: repeat(auto-fit, minmax(5.5rem, 1fr)); }

/* A SEGMENTED CONTROL IS THE ONE PLACE THE FLOOR NEEDED HELP.
   `.seg__btn` is `calc(var(--tap) - 8px)`, written when `--tap` was 48 and the
   answer was 40. Against a 32 px `--tap` the same expression gives 24, which is
   EXACTLY the WCAG 2.2 AA minimum and no more. A floor with no headroom is not
   a floor, so the inset shrinks with the target. */
.seg__btn,
.seg__btn--radio > span { min-height: calc(var(--tap) - 4px); }

/* A DENSE TABLE THAT IS STILL DENSER THAN A NORMAL ONE. `.tbl--dense` was
   `--sp-2 --sp-3` = 8/12 against a normal 12; at this density `--sp-3` is
   itself 8, so the variant and the default would have rendered identically and
   a modifier that stops modifying is a defect nobody sees. */
.tbl--dense th, .tbl--dense td { padding: var(--sp-1) var(--sp-2); }

/* The picker's scroller was 17rem because six 64 px rows is 384 px. Rows are
   44 px here, so the same height would show eleven and push the field under it
   off the screen; 15rem shows eight. */
.picker__list { max-block-size: 15rem; }

/* A CONTROL IS NOT A CONTAINER, and this was found by looking rather than by
   measuring. On the phone every field is the width of the screen, which is
   right and is also why nobody noticed: at 1280 the movements filter drew four
   `<select>` elements 1020 px wide, each showing a single em dash, and the
   filter card took nine tenths of the window while the four rows of ledger it
   filters sat in the last inch. It escaped nothing, so the overflow harness was
   right not to report it, and it was the single worst thing on any desktop
   screen in this application.

   A control is bounded by the longest value it can hold, not by the space
   available. 26rem is not a new number: `.auth__form` has capped itself at
   exactly that since the sign-in screen was built. One form in this application
   already knew this and the rest did not.

   A textarea is the exception, because it holds a paragraph rather than a
   value, and a paragraph has its own measure — the one the token layer already
   states. */
.input, .select { max-inline-size: 26rem; }
.textarea { max-inline-size: var(--w-prose); }
/* A FIELD ROW IS ONE CONTROL, NOT TWO. `.field__row` is `1fr auto` and it means
   "a quantity and the unit it is in". Capping each side separately put 190 px
   of nothing between the number and its unit — measured on the receive screen
   at 1280 — which reads as two unrelated controls and is worse than the stretch
   it was fixing. So the PAIR carries the measure and the two halves fill it. */
.field__row { max-inline-size: 30rem; }
.field__row .input, .field__row .select { max-inline-size: none; }
/* And the same for a two-column block of fields. `.grid2` is a LAYOUT
   everywhere else in this application — it is what puts two cards side by
   side — but inside a form it is a row of fields, and a row of fields belongs
   to the column the rest of the form is in. Without this the From/To pair on
   the movements filter spanned the whole card while every field above it was
   26rem, and one row four hundred pixels wider than its neighbours reads as a
   mistake even when both are deliberate. There is no `<form>` anywhere in the
   gallery, so this selector reaches product screens only. */
form .grid2, form .grid3 { max-inline-size: 30rem; }
/* A BUTTON IN A STACK IS A CONTROL, NOT A ROW — and it was full width by
   ACCIDENT rather than by decision. `.u-stack` is a grid, a grid item
   stretches, and so every plain `.btn` inside one has silently been as wide as
   whatever contained it. On a phone that is invisible and harmless. On the
   settings screen at 1920 it drew a 822 px bar of solid amber under a 416 px
   number box, four times down the page — and amber in this system is the
   IRREVERSIBLE action, so four stacked banners were the loudest thing on the
   screen saying the least.

   `--block` is the EXPLICIT opt-in for a full-width button and it still means
   that; it is only capped inside a card, where the card is a section rather
   than a row. The action bar is not a stack and not a card, so the one primary
   action per screen is untouched. */
.u-stack > .btn { justify-self: start; }
.card .btn--block, .dcard .btn--block { max-inline-size: 26rem; }
/* A picker is a field, and a bare search bar is a screen.
   `.picker` is how a form asks "which shelf, which item" — it is a control in a
   column of controls and it lines up with them, results list and all.
   A `.searchbar` that is NOT inside a picker is the subject of the screen it is
   on, and a search box the width of the results under it is the one place a
   full-width control is the point. That is the whole distinction, and it is the
   reason this rule names `.picker` rather than `.searchbar`. */
.picker { max-inline-size: 30rem; }

/* AND THE SAME ARGUMENT ONE LEVEL UP, FOR THE TASK FLOW.
   `chrome="task"` screens deliberately have no sidebar and no `.sec`, because a
   task is a focused screen — which on a phone means edge to edge and on a
   1280 px window meant a receive form 1240 px wide with a 1240 px amber button
   pinned across the bottom of it. That button is the one irreversible action in
   the application, and at that width it reads as a banner rather than as a
   thing to press.

   `--w-task` is the measure a single task reads at: wide enough for a quantity
   field beside its unit picker, narrow enough that the label, the value and the
   confirmation sentence are one glance rather than three. The trailing `.sec` —
   the "what just happened" list under every task form — comes to the same
   measure, because two different column widths stacked on one screen look like
   a bug whichever of them is right.

   The dark head band and the action bar stay full-bleed; a band that stops
   short of the window edge looks like a rendering fault. Only their CONTENTS
   come back to the column, and they do it with `inline-size` and `justify-self`
   rather than with `margin-inline: auto` — measured, and the reason is worth
   the line: auto inline margins on a GRID ITEM beat `justify-self: stretch`, so
   the item shrinks to fit-content first and is then centred. The action bar's
   one primary action came out an 80 px pill floating in the middle of a 1280 px
   window. */
.task__body,
.main--task .sec { max-inline-size: var(--w-task); margin-inline: auto; }
.task__head > *,
.actionbar > * { inline-size: min(100%, var(--w-task)); justify-self: center; }

/* The gallery's specimen label column, sized to 15 px type. */
@media (min-width: 560px) {
  .gal__typerow { grid-template-columns: 7.5rem 1fr; }
}

/* ---------------------------------------------------------------------------
   3. WHERE THE LAYOUT HAS ALSO CHANGED
   These three sit inside `min-width: 900px` blocks in components.css, so the
   width has to come back into the condition to out-rank them — this is the one
   place the two halves of the rule meet. Everything above here is density
   alone.
   ------------------------------------------------------------------------ */
@media (min-width: 900px) {
  /* A 15rem rail was 240 px of a 1440 px window carrying 15 px labels. */
  .app--desk { grid-template-columns: 13rem 1fr; }

  /* THE POINT OF THE WHOLE EXERCISE, IN ONE NUMBER. 34rem of table at 48 px a
     row is eleven rows; at 37 px it is fourteen, and 44rem of it is nineteen. A
     stock list that shows nineteen rows without a scroll is a different tool
     from one that shows eleven. */
  .dt__table-wrap { max-block-size: 44rem; }

  /* A dialog is sized to its content, and its content just got smaller. */
  .sheet__panel { inline-size: min(30rem, 92vw); }
  .auth__panel  { inline-size: min(28rem, 100%); }
}
