/* ============================================================================
   mobile.css — one sheet, three products: ViryaCORE, ANSR CORE, EMCORE.

   Asa, 18 Oct 2026: "major issues with mobile responsiveness — the swipeable
   tabs, 1 line, the rounded boxes look bad, the drop downs are not mobile
   friendly. Do a full estate scan and fix all 3 in one sweep."

   THE ONE RULE: a horizontal group of controls keeps its line and scrolls
   INSIDE ITS OWN BOX. Nothing wraps into three stacked rows, and the page never
   scrolls sideways. Those are the two ways a desktop screen fails on a phone and
   they have the same fix.

   THE TEST THAT COUNTS is not a screenshot — a screenshot cannot show that the
   page scrolls sideways. It is:
     document.documentElement.scrollWidth === document.documentElement.clientWidth

   ---------------------------------------------------------------------------
   HOW THE CLASS LIST WAS BUILT, and what was deliberately LEFT OUT.

   Every stylesheet in all three products was parsed for rules declaring
   flex-wrap:wrap whose last class names a horizontal group. That yielded 100
   candidates. 64 are listed below. The rest are excluded ON PURPOSE, because
   "it wraps on a phone" is not the same as "it should slide":

     .row       modal footers (.modal .row — justify-content:flex-end) and form
                field rows (.rd-page .row — align-items:flex-end). As a rail the
                Save button scrolls out of reach and fields stop stacking. Both
                are regressions; wrapping is the CORRECT behaviour here.
     .bar       the shell header. core.css already sets .bar{flex-wrap:wrap}
                under max-width:900px — a deliberate decision, not an oversight.
     .bar__nav  the burger menu's list. It is display:none on mobile and shown
                only inside .bar.is-open. Forcing display onto it puts the whole
                nav permanently on screen and breaks the burger.
     *-head, *__head, *-meta, *__meta, .chead-titlerow, .cbl-hrow, .b-hrow
                title and metadata rows. A heading that wraps above its actions
                reads better on a phone than one that hides them off-edge.
     *-row with card chrome (.arch-row, .batch-row, .rd-row, .r2-chrow,
     .cbl-vrow, .sa-row, .rcrow, .cb-sr-clsrow, .gw-row)
                these are LIST ITEMS — a record drawn as a row. Sliding one
                sideways hides the record's own content.
     form rows (.cb-row, .pm-row, .pm-pickrow, .cb-al3-fnrow)
                align-items:flex-end gives them away: they are fields, and a
                field belongs full width on a phone.

   NOTHING here sets `display`. Every class below already declares display:flex
   in its own stylesheet — that is how it was found. Declaring it again is what
   un-hid .bar__nav. !important appears on exactly four properties — flex-wrap, overflow-x,
   and a field's font-size and min-height — each of which must beat a more
   specific selector already in core.css or an app sheet. Every other
   declaration here wins on source order alone, because this sheet loads last.
   ========================================================================== */

/* ---- always on, every width ---------------------------------------------- */
/* Scrollbars are hidden EVERYWHERE, which is only honest because every rail
   below bleeds to the screen edge — the cut-off edge is the affordance that
   says "this scrolls". A rail that ended flush with a hidden scrollbar would
   have no clue at all. */
*{scrollbar-width:none;-ms-overflow-style:none}
*::-webkit-scrollbar{width:0;height:0;display:none}
*{-webkit-tap-highlight-color:transparent}

/* THE most common cause of a real sideways dropoff: a grid or flex child
   defaults to min-width:auto, so one wide table or one long unbroken string
   pushes its column — and the whole page — wider than the screen. */
.wrap>*,.shell>*,.split>*,.grid2>*,.cards>*,.figures>*,.stats>*,.two>*{min-width:0}

/* A shell must CLIP, never hide. overflow:hidden creates a scroll container,
   and every position:fixed child inside it — a sheet, the aura — silently
   starts scrolling with the page instead of staying put. */
.shell{overflow-x:clip}

/* ---- the phone ----------------------------------------------------------- */
@media (max-width:760px){

  /* TIER ONE — naked control groups. No chrome of their own, so they may bleed
     to the screen edge and pad inside. A rail with a right margin looks
     finished, so nobody swipes it; one that runs off the edge is visibly cut
     off, and that is the whole affordance. */
  .actbar, .appfilter, .au-chips, .au-row, .au-seg, .b-tbar, .cb-al3-chips, .cb-al3-lvbar,
  .cb-bm-filters, .cb-facet, .cb-facet__pills, .cb-maprow, .cb-sk-chips, .cb-tabs, .cbkg-bar,
  .cbl-an-pills, .cbl-crumb, .cbl-rchips, .cbl-row, .cbx-sub2row, .cfilter, .chips,
  .colf-bar, .filters, .fsig-tabs, .grp-actions, .gw-bar, .hlrow, .lib-filters, .mchips,
  .n-frow, .od-actions, .pick__row, .pl-chips, .r1-chips, .r1-runrow, .r1-tools, .r2-urlrow,
  .rchips, .rp-actions, .rp-bar, .skill-filter, .tablebar, .tabs, .third, .topicfilter,
  .tsr-chips, .typerow
  {
    flex-wrap:nowrap !important;
    overflow-x:auto !important;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior-x:contain;   /* a swipe past the end must not go Back */
    scroll-snap-type:x proximity;
    margin-left:0;
    margin-right:0;
    padding-left:14px;
    padding-right:14px;
    border-radius:0;
  }

  /* TIER TWO — groups that carry their own card chrome: a background, a border,
     a pill. A segmented control keeps its pill and a save bar keeps its panel;
     they scroll INSIDE that shape rather than being flattened to the edge. */
  .au-bar, .bulkbar, .cb-al3-seg, .cb-tabbar, .cbkg-seg, .cbl-chips, .cbl-g-bar,
  .cbl-rp-filters, .cbl-verbar, .ex-tabs, .fl-bar, .fld-bar, .genbar, .gw-tabs, .savebar,
  .usr-tabs
  {
    flex-wrap:nowrap !important;
    overflow-x:auto !important;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;
  }

  /* Both tiers: an item must hold its width instead of squashing to fit. The
     shell's own .tabs already scrolls but never pinned its children, so five
     tabs quietly compressed into illegible slivers rather than sliding. */
  .actbar>*, .appfilter>*, .au-bar>*, .au-chips>*, .au-row>*, .au-seg>*, .b-tbar>*,
  .bulkbar>*, .cb-al3-chips>*, .cb-al3-lvbar>*, .cb-al3-seg>*, .cb-bm-filters>*, .cb-facet>*,
  .cb-facet__pills>*, .cb-maprow>*, .cb-sk-chips>*, .cb-tabbar>*, .cb-tabs>*, .cbkg-bar>*,
  .cbkg-seg>*, .cbl-an-pills>*, .cbl-chips>*, .cbl-crumb>*, .cbl-g-bar>*, .cbl-rchips>*,
  .cbl-row>*, .cbl-rp-filters>*, .cbl-verbar>*, .cbx-sub2row>*, .cfilter>*, .chips>*,
  .colf-bar>*, .ex-tabs>*, .filters>*, .fl-bar>*, .fld-bar>*, .fsig-tabs>*, .genbar>*,
  .grp-actions>*, .gw-bar>*, .gw-tabs>*, .hlrow>*, .lib-filters>*, .mchips>*, .n-frow>*,
  .od-actions>*, .pick__row>*, .pl-chips>*, .r1-chips>*, .r1-runrow>*, .r1-tools>*,
  .r2-urlrow>*, .rchips>*, .rp-actions>*, .rp-bar>*, .savebar>*, .skill-filter>*,
  .tablebar>*, .tabs>*, .third>*, .topicfilter>*, .tsr-chips>*, .typerow>*, .usr-tabs>*
  {flex:0 0 auto;scroll-snap-align:start;white-space:nowrap}

  /* THE APP MENU. Asa's phone showed it wrapped onto FOUR stacked rows, and the
     sub-nav cut mid-word at the right edge ("Anomaly Re...").

     .bar__nav is display:none on mobile and shown only inside .bar.is-open, so
     it is reached THROUGH that state. Styling .bar__nav bare — which is what
     the first version of this sheet did, with display:flex !important — forces
     the closed burger menu permanently on screen. Hence the .bar.is-open
     prefix: specificity 0,3,0, which beats the 0,1,0 that sets wrap, so this
     needs no !important either. */
  .bar.is-open .bar__nav{
    flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch;
    overscroll-behavior-x:contain; scroll-snap-type:x proximity}
  .bar.is-open .bar__nav>*{flex:0 0 auto; scroll-snap-align:start; white-space:nowrap}

  /* THE HEADER IS THE TOP EDGE.
     Asa, 20 Oct: "get rid of the curved menus — in mobile main nav be fixed to
     the top with glass background header ... the curves look real bad in
     mobile."

     On a desktop .bar is a floating capsule: top:14px for air, a gutter either
     side, a pill radius. Those three are what make it an OBJECT, and a phone has
     no room for an object floating in front of the content — it becomes the
     screen's top edge instead. The glass is already in core.css, so this is a
     geometry fix, not a repaint. Only the bottom hairline survives: a border
     down the sides of a full-bleed header draws two lines nothing needs. */
  .bar{
    top:0; left:0; right:0;
    transform:none;                 /* kill the desktop centring translate */
    width:100%; max-width:none;
    border-radius:0;
    border-left:0; border-right:0;
    padding-left:max(14px,env(safe-area-inset-left));
    padding-right:max(10px,env(safe-area-inset-right));
    padding-top:max(9px,env(safe-area-inset-top));
  }
  /* Every layout clears the bar through ONE variable, and moving the bar to
     top:0 changed its height. Measured at 390px against the real bar markup:
     the bar is 64px, while --bar-clear was still 92px (core.css sets 84, this
     product's brand sheet raises it) — a 28px dead band above the first line.
     64 + a 14px breathing gap. The safe-area term is added rather than folded
     in, so on a notched phone this over-reserves by a few px instead of ever
     sliding content under the glass. */
  :root{--bar-clear:calc(78px + env(safe-area-inset-top,0px))}

  /* And "no doubel lines": .third draws a border-bottom across the whole strip
     while .third a.on::after draws the active underline at bottom:-1px, sitting
     ON that border. One line, by design. They only separate into two visible
     lines when .third WRAPS and the active item ends up on a different row from
     the strip's bottom edge. The rail above is what fixes it — once the strip
     is one line again, the underline is back on the border. */

  /* tables scroll in their own box, never widening the page */
  .table-wrap,.tablewrap,.scroll-x,.tscroll,.tbl-wrap{
    overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}

  /* iOS zooms the page when a field is under 16px and will not zoom back out,
     and a 36px control is under the touch floor. Both are functional defects,
     not style preferences, which is why they carry the sheet's only !important
     outside the rails: core.css sets font-size:14px and min-height:36px through
     a selector carrying NINE :not() clauses (specificity 0,9,1), and nothing
     sane outruns that. Measured on the sign-in field, before -> after:
     font-size 14px -> 16px, height 39px -> 44px. */
  input:not([type=checkbox]):not([type=radio]):not([type=hidden]),
  select,textarea{font-size:16px !important; min-height:44px !important}
  .btn,button,[role=button]{min-height:44px}

  /* Touch targets. 44px is the floor. The drop-downs Asa called out keep their
     NATIVE appearance on purpose: there is no custom arrow image anywhere in
     the estate, so appearance:none would strip the only affordance a select
     has and leave it looking like a text box. A native select on a phone opens
     the OS picker, which is the most mobile-friendly control available — it
     needed room to be tappable, not restyling. */
  select{padding:10px 12px}
  .btn,.chip,.pill,button{user-select:none;-webkit-user-select:none}

  /* The rounded boxes Asa said "look bad": at 390px a 14px radius with side
     margins leaves two slivers of ground either side of every card, and the
     corners eat the text's own margin. Tighter radius, not full bleed —
     negative margins are themselves a leading cause of sideways scroll. */
  .card,.co,.grp-co,.co-app,.panel,.well{border-radius:10px}

  /* ---- actions are not tokens -------------------------------------------
     --r-pill is 100px and the whole control system wears it. On a pill the
     radius is the POINT when the thing is a token — a chip, a status tag, a
     segmented tab — because a token is a small self-contained object. An action
     button is not an object, it is a control, and at phone width it goes full
     width: 100px then turns each end into a ~22px semicircle, the corners go
     dead, and a column of them reads as a pile of lozenges. Actions take the
     radius of what surrounds them, which here is 9-10px (cards, fields).
     .chip, .pill, .nav and the status tags keep the pill, on purpose. */
  .btn,.v-btn,.bar__burger,.who__out,
  .btn--ghost,.btn-ai,.btn-recal,.railbtn,.send-btn{border-radius:10px}

  /* ---- every dialog is a bottom sheet -----------------------------------
     All three overlay families are the same shape: a fixed veil that centres a
     box (.veil>.sheet, .v-veil>.v-sheet, .modal-bg>.modal). Centred is right on
     a desktop and wrong on a phone — it floats mid-screen, out of thumb reach,
     with dead gutters either side. A sheet is anchored to the edge the thumb
     is already near, and keeps its own rounded top so it still reads as a
     layer above the page rather than a new screen. */
  .veil,.v-veil,.modal-bg{place-items:end stretch; padding:0}
  .sheet,.v-sheet,.modal{
    width:100%; max-width:none;
    max-height:85dvh;              /* dvh, not vh: vh counts the address bar */
    border-radius:22px 22px 0 0;
    border-left:0; border-right:0; border-bottom:0;
    animation:phone-sheet-up .26s var(--ease);
  }
  /* the home indicator must not sit on top of the last control */
  .sheet,.v-sheet{padding:20px 18px calc(20px + env(safe-area-inset-bottom,0px))}
  .modal{padding:24px 18px calc(24px + env(safe-area-inset-bottom,0px))}
  /* a sheet's own actions are reachable: side by side, splitting the width */
  .v-sheet__acts > *,.modal .row > *{flex:1 1 0; min-width:0}

  /* The page already reserves 60px (core.css). All that was missing was the
     home indicator on a notched phone. There is no fixed bottom nav in any of
     the three products, so nothing more is reserved here. */
  .page{padding-bottom:calc(60px + env(safe-area-inset-bottom,0px))}
}

/* ============================================================================
   THE PHONE AUDIT FIXES (Asa, 21 Oct 2026: "go"). Measured with the phone-audit
   skill at 390px across ANSR CORE, ViryaCORE and EMCORE — every rule below names
   the finding it answers. Phone only; the desktop is untouched.
   ========================================================================== */
@media (max-width:760px){

  /* 1 · THE HAMBURGER IS A MENU, NOT A RAIL. Opened, it was the glass header
     grown taller: the apps a sideways row of pills, "Change password" and
     "Sign out" floating as pills on the right, the page reading through the
     glass behind them. A phone menu is a solid panel under the header: one app
     per full-width row, the account below as rows, the page dimmed behind it.
     phone-shell.js closes it on a tap outside, Escape and a route change, and
     stops the page scrolling underneath. */
  .bar.is-open{
    background:var(--w,#fff); -webkit-backdrop-filter:none; backdrop-filter:none;
    box-shadow:0 0 0 100vmax rgba(17,38,46,.34);
    max-height:100dvh; overflow-y:auto; overscroll-behavior:contain;
    padding-bottom:max(8px,env(safe-area-inset-bottom));
  }
  .bar.is-open .bar__nav{
    flex-direction:column; align-items:stretch; flex-wrap:nowrap;
    overflow:visible; scroll-snap-type:none; gap:0; padding:6px 0 0;
  }
  .bar.is-open .bar__nav>.nav{
    position:relative; display:flex; align-items:center; gap:10px;
    min-height:50px; padding:0 4px; border-radius:0;
    border-bottom:1px solid var(--line); font-size:16px; white-space:nowrap;
  }
  .bar.is-open .bar__nav>.nav[hidden]{display:none}
  .bar.is-open .bar__nav>.nav:last-child{border-bottom:0}
  /* the current app: a dot beside its name — the travelling underline belongs
     to a horizontal bar, and a stripe down one edge is never used */
  .bar.is-open .bar__nav>.nav.on::after{
    position:static; order:3; margin-left:auto; width:8px; height:8px;
    border-radius:50%; view-transition-name:none;
  }
  /* CompBench's PRO switch: a small tag after the name, on the name's line.
     It is a [role=button], so the 44px touch floor above stretched it into a
     tall orange block (Asa: "the PRO on mobile looks out of sync"). The tag stays
     small; its tap area is widened invisibly instead. */
  .bar.is-open .nav-pro{position:relative; top:auto; left:auto; transform:none; order:2;
    display:inline-flex; align-items:center; min-height:0 !important; height:22px;
    margin-left:2px; padding:0 8px; border-radius:6px; font-size:10px; line-height:1}
  .bar.is-open .nav-pro::before{content:""; position:absolute; inset:-11px -8px}
  .bar.is-open .bar__who{
    flex-wrap:wrap; align-items:center; gap:10px;
    margin:6px 0 0; padding:12px 4px 0; border-top:1px solid var(--line);
  }
  .bar.is-open .who__menu{
    flex-basis:100%; width:100%; margin:6px 0 0; padding:0; min-width:0;
  }
  .bar.is-open .who__out{
    min-height:50px; padding:0 4px; font-size:16px; background:none;
    border:0; border-top:1px solid var(--line); border-radius:0; box-shadow:none;
  }
  .bar__burger[aria-expanded="true"]{background:var(--mist,#F1F4F5)}

  /* 2 · A DROP-DOWN IS A SHEET. The column filter opened as a 248px box pinned
     under its header, half off a finger's reach. On a phone it rises from the
     bottom edge, full width, like every other dialog. colf.js writes top/left
     inline, hence the !important on those two and on position. */
  html body .cfp{   /* colf.js injects its own <style> after this sheet: outrank it */
    position:fixed !important; top:auto !important; left:0 !important; right:0; bottom:0;
    width:100%; min-width:0; max-width:none; max-height:75dvh; overflow-y:auto;
    padding:18px 18px calc(18px + env(safe-area-inset-bottom,0px));
    border-radius:22px 22px 0 0; border-left:0; border-right:0; border-bottom:0;
    box-shadow:0 0 0 100vmax rgba(17,38,46,.34); z-index:120;
    animation:phone-sheet-up .26s var(--ease);
  }
  html body .cfp .srt,html body .cfp .acts button{min-height:44px; font-size:15px}
  html body .cfp input.cfq{font-size:16px; min-height:44px}

  /* 3 · PHONE CORNERS. A desktop 14–18px radius on a block that spans the
     phone reads as a blob — every block below was measured at 14–18px and at
     least 60% of the screen wide. Cards take 12px, wells and wraps 10px. */
  .gw-card,.gw-head,.rd-tile,.r2-empty,.r2-lst,.r2-tcard,.kcol,.rd-rail,.fl-bar,
  .cbl-head,.cbl-card,.cbp-card,.board,.chat,.band,.sk-group,.od-panel,.pipe,.prov,
  .au-head,.au-card,.au-wrap,.au-bar,.bulkbar,.figures,.grp-co,.mod,.ex-side,.ex-grid,
  .pl-head,.pl-card,.dz-way,.drop,.empty{border-radius:12px !important}
  .table-wrap,.tablewrap,.cb-tablewrap{border-radius:10px !important}
  /* !important because each app's stylesheet is injected AFTER this one and
     scopes its radius under the pane class (.rd-page .rd-tile, 0,2,0) */

  /* 4 · TAP TARGETS. Admin's Save / Test / pager buttons measured 26–30px,
     the column-filter header 33px, small buttons 33–34px: a size rule more
     specific than the shell's 44px floor won. The floor is a floor. */
  .btn,.btn.small,.btn-sm,.sk .btn,.colf,.ex-pager button,.gateslink,.ceditlink{min-height:44px !important}
  .sec__x,.cb-swipe__arw,.cb-ob-v{min-width:44px}

  /* 4b · ONE-COLUMN GRIDS THAT KEPT A DESKTOP WIDTH. A grid collapsed to one
     column still sized that column to its widest child (min-width:auto), so the
     column ran past the screen and the shell's clip cut it: PowerProposal's
     template list (382px in a 358px pane), CompBench's skill tiers (884px),
     Signals' Finance boards (558px), RayDar R1's routes (3,020px, ViryaCORE). */
  .tpl,.cb-sk-grid,.split2,.routes{grid-template-columns:minmax(0,1fr) !important}
  .tpl>*,.cb-sk-grid>*,.split2>*,.routes>*{min-width:0 !important}
  /* a text box never wider than its screen: RayDar R1's rule editors were 523px
     (ViryaCORE); and an action button inside an app pane is a box, not a capsule —
     !important because the app sheets set their own radius after this one */
  .v-pane textarea,.page textarea{max-width:100%; box-sizing:border-box}
  /* …and a fold-out holding one (RayDar R1's rule cards) drops below its row,
     full width, instead of opening past the screen edge */
  .brcard div:has(> details){flex-wrap:wrap}
  .brcard details[open]{flex:1 1 100%; min-width:0}
  .brcard details textarea{width:100% !important; max-width:100%}
  .v-pane .btn{border-radius:10px !important}
  /* a long role chip on the group page ran 9px past the edge (ViryaCORE) */
  .sa-chip{white-space:normal; max-width:100%}

  /* 4c · RADII THAT WERE HARDCODED as a full capsule (999px) on wide buttons:
     CompBench's anomaly filters. On a phone they are boxes like every action. */
  .cbl-an-pill,.sweep-btn{border-radius:10px !important}
  .cb-hero,.cmd,.chead,.kcard,.cb-tree,.cb-main{border-radius:12px !important}

  /* 4d · ROWS THAT WRAPPED onto 3–10 lines become one-line rails (mobile.css's
     own rule for rows of controls): Signals' suggested questions, Admin's
     per-user actions, the Explorer's table boxes; ViryaCORE's pipeline headers
     and RayDar R1's idea-card tag and action rows. */
  .seed,.au-rowacts,.cb-boxes,.pipe-head,.board-top,.idea-topline,.idea .acts,.board .acts
  {flex-wrap:nowrap !important; overflow-x:auto !important;
    -webkit-overflow-scrolling:touch; overscroll-behavior-x:contain; scroll-snap-type:x proximity}
  .seed>*,.au-rowacts>*,.cb-boxes>*,.pipe-head>*,.board-top>*,.idea-topline>*,.idea .acts>*,.board .acts>*
  {flex:0 0 auto; white-space:nowrap; scroll-snap-align:start}

  /* 5 · TABLES (marked by phone-shell.js — see the note there).
     A table nobody put in a scroll box scrolls inside ITSELF instead of losing
     its right-hand columns to the shell's clip. */
  table.ph-xscroll{display:block; width:auto !important; min-width:0 !important; max-width:100%;
    overflow-x:auto; -webkit-overflow-scrolling:touch; overscroll-behavior-x:contain}

  /* A LIST becomes cards. The header row stays, as a one-line strip of the sort
     and filter buttons it carries; plain header labels (nothing to press) are
     dropped because each card already prints them beside its values. Widths an
     app set for the desktop grid are released — !important because app sheets
     set them per column through their pane scope. */
  table.ph-cards,table.ph-cards tbody{display:block; width:100% !important; min-width:0 !important;
    max-width:100%; border:0 !important; border-radius:0 !important; background:none !important;
    box-shadow:none !important; overflow:visible !important}
  table.ph-cards thead{display:block; margin:0 0 10px; background:none !important}
  table.ph-cards thead tr{display:flex; gap:6px; overflow-x:auto; overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch; scroll-snap-type:x proximity; background:none !important}
  table.ph-cards thead th{display:block; flex:0 0 auto; width:auto !important; min-width:0 !important;
    padding:0 !important; border:0 !important; background:none !important; box-shadow:none !important;
    white-space:nowrap; position:static !important}
  table.ph-cards thead th:not(:has(button,a,input,select,[role=button])){display:none}
  table.ph-cards tbody tr{display:block; margin:0 0 10px; padding:12px 14px;
    border:1px solid var(--line,#E3E7E9) !important; border-radius:12px !important;
    background:var(--w,#fff) !important; box-shadow:none !important}
  table.ph-cards tbody td{display:flex; align-items:baseline; justify-content:space-between; gap:12px;
    width:auto !important; min-width:0 !important; max-width:none !important; height:auto !important;
    padding:5px 0 !important; border:0 !important; background:none !important; box-shadow:none !important;
    text-align:right; white-space:normal; overflow-wrap:anywhere; position:static !important}
  table.ph-cards tbody td::before{content:attr(data-l); flex:0 0 auto; max-width:46%; text-align:left;
    font-size:11px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--ink-3,#6B7C83)}
  /* the first column is the card's title */
  table.ph-cards tbody td:first-child{display:block; text-align:left; font-size:15px; font-weight:600;
    padding:0 0 8px !important; margin:0 0 4px; border-bottom:1px solid var(--line,#E3E7E9) !important}
  table.ph-cards tbody td:first-child::before,
  table.ph-cards tbody td[data-l=""]::before,
  table.ph-cards tbody td:not([data-l])::before{content:none}
  /* an unlabelled cell (row actions) or a message row spanning every column */
  table.ph-cards tbody td[data-l=""],table.ph-cards tbody td:not([data-l]){justify-content:flex-start; text-align:left; flex-wrap:wrap}
  table.ph-cards tbody td:empty{display:none}
  table.ph-cards tbody tr:hover,table.ph-cards tbody tr:hover td{background:none !important}
  table.ph-cards tbody tr:hover{background:var(--w,#fff) !important}
}

/* ---- safe areas — only where content meets an edge ------------------------ */
@supports (padding:env(safe-area-inset-left)){
  @media (max-width:760px){
    .wrap{padding-left:max(16px,env(safe-area-inset-left));
          padding-right:max(16px,env(safe-area-inset-right))}
  }
}
/* a sheet arrives from the edge it is anchored to */
@keyframes phone-sheet-up{from{transform:translateY(100%)}to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){*{scroll-behavior:auto}}
