/* apliteni-ui — the tap zone. Below the phone step, to a coarse pointer, a
 * control that draws smaller than --tap-min carries a transparent layer that
 * reaches the floor, and no control is drawn any bigger. Zones alone do not
 * finish it: a layer takes HALF the clear space its container declares, so
 * where the kit packs small controls closer than that, the GAP opens to
 * --tap-gap. The controls keep their size; the space between them grows.
 *
 * Read LAST, after every component sheet — see src/index.css — because each
 * opening overrides a gap one of them already set.
 *
 * why: docs/foundations.md#a-tap-reaches-the-floor-below-the-phone-step
 * Held by stories/tap-zone.test.js, measured in a browser at 390.
 */

:root {
  /* WCAG 2.5.5, and where iOS and Android land. Not on the spacing scale,
     which runs 40 then 48, because a fingertip is not spacing. Declared here
     rather than in tokens.css for the reason field-zoom.css carries its own 16:
     react/src/index.ts imports this sheet without the token file, and a var()
     resolving to nothing there would size the layer to `auto` in silence. */
  --tap-min: 44px;

  /* WCAG 2.5.8 (AA), the target the kit holds at every width: the floor this
     sheet raises FROM and may never drop below. */
  --tap-aa: 24px;

  /* 44 − 24: two zones fit between two of the smallest marks the kit draws. */
  --tap-gap: var(--space-5, 20px);

  /* For a container of BORDERED controls at the smallest mark: `100%` on the
     layer is the padding box, so one of those measures two less there and
     --tap-gap stops its layer short. The floor, less that box. */
  --tap-gap-bordered: calc(var(--tap-min) - var(--tap-aa) + 2px);

  /* Clear space to the nearest neighbour, declared by the container that knows
     its own gap; a zone takes half on each side.

     ZERO by default, so a zone grows nowhere until a container has opened the
     room — assuming --tap-gap everywhere was measured handing `Keep the
     workspace` a pixel of its own box that answered for `Delete it
     permanently`. */
  --tap-clear-x: 0px;
  --tap-clear-y: 0px;
}

@media (max-width: 560px) and (pointer: coarse) {
  /* The containing block for every layer below. `.ui-btn` already has it; the
     rest take it only inside this query, because `position: relative` lifts a
     control over the in-flow one beside it and that changes who wins a shared
     pixel. */
  :where(
    .ui-seg button,
    .ui-tabs__tab,
    .ui-dropdown__trigger,
    .ui-toast__action,
    .ui-drawer__close,
    .ui-snippet__copy,
    .ui-footer__social,
    .ui-app__search,
    .toggle,
    /* Already relative in react/src/DatePicker.css — restated because this
       gate reads the kit's own sheets and cannot see that one, and a carrier
       whose containing block it cannot find is a layer that measures against
       whatever ancestor happens to be positioned. */
    .ui-datepicker__opt
  ) { position: relative; }

  /* The layer: centred, transparent, sized to the floor, clamped to half the
     clearance. */
  :where(
    .ui-btn,
    .ui-seg button,
    .ui-tabs__tab,
    .ui-dropdown__trigger,
    .ui-toast__action,
    .ui-drawer__close,
    .ui-snippet__copy,
    .ui-footer__social,
    .ui-switch,
    .ui-datepicker__opt,
    .ui-app__search,
    .toggle
  )::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-x)));
    height: min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-y)));
  }

  /* ::after on these is spoken for — the tick and the dot, the toast close's
     glyph plate — so the existing ::before grows, floored at --tap-aa. The
     floor is load-bearing: `100%` is the PADDING box, 16 on a 19px checkbox
     with a 1.5px border, so without it the clamp takes this layer DOWN to 22
     and under the kit's own minimum. */
  .ui-check input::before,
  .ui-table__selection input[type="checkbox"]::before,
  .ui-toast__close::before {
    width: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-x))));
    height: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-y))));
  }

  /* -- Where the kit opens a gap, and where it cannot --------------------
   * `!important` for the reason field-zoom.css takes it: each opening
   * overrides a `gap` shorthand a component sheet set, and the React bundle
   * ships this sheet without those sheets, where order is the consumer's.   */

  /* A strip keeps its pills packed across — that tight track IS the control —
     and opens down, where the room is free until it wraps. */
  .ui-seg {
    row-gap: var(--tap-gap) !important;
    --tap-clear-x: var(--space-1, 4px);
    --tap-clear-y: var(--tap-gap);
  }

  /* The underline appearance keeps the gap it draws, at every width and under
     both pointers, so a wrapped strip reads as one block. It can because the tab
     draws the floor itself — segmented.css gives it `min-height: var(--tap-min)`
     — leaving its layer inside the drawn box. The clearance is still declared,
     and declared SMALL on purpose: the pill rule above hands every strip
     --tap-gap, and this one has 4px of row to give, not 20. So a layer here can
     never reach past the gap it was promised, whatever a tab draws. A pill draws
     31 tall and does want the full 20. #527, measured in
     stories/segmented-wrap.test.js. */
  .ui-seg--underline { row-gap: var(--space-1, 4px) !important; --tap-clear-y: var(--space-1, 4px); }

  /* Tabs are wide enough across; down, the panel under them has the room. */
  .ui-tabs__list { --tap-clear-x: 2px; --tap-clear-y: var(--tap-gap); }

  /* Equal cells read as one strip, so they stay packed across and open down,
     which is where this strip wraps at this width. */
  .ui-pager__steps {
    row-gap: var(--tap-gap) !important;
    --tap-clear-x: var(--space-1, 4px);
    --tap-clear-y: var(--tap-gap);
  }
  .ui-pager { row-gap: var(--tap-gap) !important; --tap-clear-y: var(--tap-gap); }

  /* Chips open both ways: the row wraps, and the button at the end of it is a
     target like the chips are. */
  .ui-filter-bar { gap: var(--tap-gap) !important; --tap-clear-x: var(--tap-gap); --tap-clear-y: var(--tap-gap); }
  /* In a split toolbar the rail row beside the report sits on the same line as
     Clear all. One step plus 1px keeps the button's layer off that row. */
  .ui-toolbar--split .ui-filter-bar { column-gap: calc(var(--tap-gap) + var(--space-1) + 1px) !important; }

  /* Inside a chip there is nothing to open: parting the value from its remove
     mark would draw two controls where the reader sees one. Named on the
     Accessibility minimums page. */
  .ui-filter-bar__chip { --tap-clear-x: 0px; --tap-clear-y: 0px; }

  /* Row actions open across — the pair #488 names — and cannot open down:
     a dense table's rows share an edge, and parting them is the row height the
     guideline protects. Down, they get the row's own padding, twice. */
  /* Row actions — the pair #488 names — part ACROSS with a margin: the cell is
     a `table-cell`, where `gap` does nothing, and declaring it anyway left the
     mark's zone 9px inside `Revoke`. Nothing down, because a dense table's
     rows share an edge and its padding is not clearance to spend. */
  .ui-table__act .ui-btn + .ui-btn { margin-inline-start: var(--tap-gap) !important; }

  /* A file drop's pair opens both ways: the row's own floor leaves clearance
     under a button shorter than the target, and the panel's padding is below. */
  .ui-drop__row { --tap-clear-y: var(--tap-gap); }
  .ui-drop__actions {
    gap: var(--tap-gap) !important;
    --tap-clear-x: var(--tap-gap);
    --tap-clear-y: var(--tap-gap);
  }
  .ui-table__act { --tap-clear-x: var(--tap-gap); --tap-clear-y: 0px; }

  /* The selection box is 19px in a 58px row and a 34px header: the layer has room to reach the floor both ways. */
  .ui-table__selection { --tap-clear-x: var(--tap-min); --tap-clear-y: var(--tap-min); }
  /* A dense or compact table's rows are 33px to 40px apart and share an edge, so a layer that grows down takes the pixels nearest the next row's box. Those rows keep the 24px floor. */
  .ui-table--dense .ui-table__selection,
  .ui-table--compact .ui-table__selection { --tap-clear-y: 0px; }

  /* Down only, like the nine rows below: a toast is a full row at this width,
     and opening it across took 24px out of the message for no reach at all —
     its action already clears the floor on the vertical half. The box does not
     open either: a toast clips to its own rounded corners for the timer bar,
     and widening its padding grows the surface rather than the space between
     controls, measured at four marks for 8px on every toast. */
  .ui-toast { row-gap: var(--tap-gap) !important; --tap-clear-y: var(--tap-gap); }

  /* The kit's remaining control rows open DOWN only. A row of labelled buttons
     at 390 is often already full, so widening its column gap does not move the
     buttons apart — it makes them narrower, and that is the half #488 rules
     out. Measured on a toolbar of three buttons and a dropdown. These rows
     wrap, which is also where the review measured them colliding. */
  .ui-confirm__acts,
  .ui-toolbar,
  .ui-empty__actions,
  .ui-sx__actions,
  .ui-fbc__foot,
  .ui-drawer__footer,
  .ui-snippet__bar,
  .ui-app__main .ui-card__row {
    row-gap: var(--tap-gap) !important;
    --tap-clear-y: var(--tap-gap);
  }

  /* `.ui-seg`'s shape at seven columns: cells packed across — that tight track
     IS the control — opening down, where the sheet has the room. The rows
     inherit both clearances. React-only, so the browser half below reports no
     subject and react/src/DatePicker.test.tsx holds these declarations. */
  .ui-datepicker__grid {
    row-gap: var(--tap-gap) !important;
    --tap-clear-x: var(--space-1, 4px);
    --tap-clear-y: var(--tap-gap);
  }
  /* The opened rows outgrow the menu's 300px cap, whose scroll edge cut the last
     week's tap layers in a phone popover. The panel keeps the viewport and edge limits. */
  .ui-datepicker__panel { --ui-dropdown-max: 100dvh; }

  /* Neither axis is opened: the room is already there, a hundred pixels to the
     caption and twelve to the grid, which is how `.ui-tabs__list` declares its
     own. The bordered step, because both controls are bordered at --tap-aa. */
  .ui-datepicker__head { --tap-clear-x: var(--tap-gap-bordered); --tap-clear-y: var(--tap-gap-bordered); }

  /* In the sheet the row scrolls, so its own block padding is the clearance —
     anything past the chip is clipped rather than hit. The chips are already
     wider than the floor, so the gap across stays the kit's. The phone popover
     scrolls its row the same way. */
  .ui-datepicker__presets {
    row-gap: var(--tap-gap-bordered) !important;
    --tap-clear-x: var(--space-1, 4px);
    --tap-clear-y: var(--tap-gap-bordered);
  }

  /* Both ways: fixed squares cannot overflow the way labels can, and a drawer
     header spends its column gap on the title. Not the accent picker — its
     swatches are on no carrier list, so opening it bought no reach. */
  .ui-footer__socials,
  .ui-drawer__header {
    gap: var(--tap-gap) !important;
    --tap-clear-x: var(--tap-gap);
    --tap-clear-y: var(--tap-gap);
  }

  /* Two 52px rows, each holding a control the kit draws under the floor: the
     shell band's palette trigger, 37.05 tall once the phone band swaps its
     sentence for the short word, and the theme switch at 34 square on both.
     Neither row opens anything — the room is already in it, which is why these
     two declare a clearance and no gap. Across, 6px a side against the band's
     own 12px gap and the topbar's 8 below 560px, where this layer exists — not
     the topbar's 14 above that step, where it does not. 6px a side crosses the
     topbar's 4px midline by 1px, which does not mis-tap: neither neighbour on
     that row carries a layer of its own. Down, the row's leftover height is 7.4px
     above and below the trigger and 9 around the switch, where a 44px layer
     needs 3.5 and 5. The rows keep their height, their gaps and their paint.
     #486

     --space-3 rather than --tap-gap, which is what every row above declares:
     20 claims 10px a side and the trigger has 7.4. The clamp would still stop
     at 44 today and be a number that is not true, which is what the browser
     half fails a container for. */
  .ui-app__bar,
  .topbar__in { --tap-clear-x: var(--space-3, 12px); --tap-clear-y: var(--space-3, 12px); }
}
