/* ================= USER TRAFFIC — the shell, the range picker and the filter row ==========
   One of two sheets, prefix is the ownership boundary: `ut-` here is the pane chrome (range
   picker, notes, tables, states, the two layer hosts); `utc-` is alt-user-traffic-charts.css
   (the charts/heatmap/bars). Reuses the Admin Console's explorer vocabulary (`.sx`, `.sx-head`,
   etc. from alt-storage.css) by extension only — a second bare rule for the same name is how
   two components once silently merged into one. Declares no geometry for the user drawer —
   `.sx-drawer` (alt-storage-panels.css) already positions it; a rule here would fight it at
   equal specificity. No colour literals (tokens only); container queries on the PANE (`.sx`
   is `sxpane`), never the window; nothing may scroll the page sideways (every grid/flex item
   is `minmax(0,…)`/`min-width:0`). Selection is never colour alone (design-system §20). */

/* ---------- the pane ---------- */

/* Positioning context for the range popover. `.sx` already establishes one via
   `container-type:inline-size`; this states it rather than relying on the side effect. */
.alt-app .sx.ut{ position:relative; }

/* ---------- the date range control ----------
   Two lines in one button: the preset's name, and the dates it resolves to — "Last 30 days"
   alone can't be checked against a figure a week later. Tabular figures stop the second line
   jittering between ranges. */
.alt-app .ut-range-btn{
  display:inline-flex; flex-direction:column; align-items:flex-start; justify-content:center;
  gap:0; height:auto; min-height:var(--a-ctl); padding:4px var(--a-3);
  min-width:0; max-width:100%; text-align:left; line-height:1.25;
}
.alt-app .ut-range-lbl{ font-size:12px; font-weight:600; color:var(--a-text); white-space:nowrap; }
.alt-app .ut-range-dates{
  font-size:10px; color:var(--a-dim); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.alt-app .ut-range-dates:empty{ display:none; }
.alt-app .ut-range-btn[aria-expanded="true"]{
  border-color:var(--a-blue); background:var(--a-blue-soft);
}
.alt-app .ut-range-btn[aria-expanded="true"] .ut-range-lbl{ color:var(--a-blue-text); }

/* ---------- the two-month picker ----------
   A non-modal layer on purpose — it traps nothing, so comparing dates against a figure behind it
   needs no close first; dismisses on Escape and an outside press. Anchored right and clamped,
   full-width below the tablet step: a two-month calendar and a preset column don't fit 320px
   side by side. */
.alt-app .ut-range-pop{
  /* The z-index is a token and never a number (design-system §11b) — `--z-float` is the floor
     for something that floats over the page without owning the screen, the same rung the
     mention picker and the chart tooltip sit on. */
  position:absolute; z-index:var(--z-float); top:calc(var(--a-ctl) + var(--a-5)); right:0;
  width:min(560px, 100%); max-width:100%; min-width:0;
  max-height:min(70vh, 560px); overflow-y:auto; overscroll-behavior:contain;
  padding:var(--a-4);
  border:1px solid var(--a-line-strong); border-radius:var(--a-r-lg);
  background:var(--a-float); box-shadow:var(--a-shadow-lg);
}
.alt-app .ut-range-pop[hidden]{ display:none; }
.alt-app .ut-range-body{
  display:flex; flex-direction:column; gap:var(--a-3); min-width:0; margin-top:var(--a-2);
}

/* The seven presets, as a wrapped group — six offered, since `custom` is the state the calendar
   leaves behind rather than a button (there would be nothing for it to apply). */
.alt-app .ut-presets{
  display:flex; flex-wrap:wrap; gap:var(--a-1) var(--a-2); min-width:0;
}
.alt-app .ut-preset{
  height:var(--a-ctl); padding:0 var(--a-3); min-width:0;
  border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  background:var(--a-panel); color:var(--a-dim);
  font-family:var(--a-body); font-size:12px; font-weight:600;
  cursor:pointer; white-space:nowrap;
  transition:background var(--a-quick) var(--a-ease), color var(--a-quick) var(--a-ease);
}
.alt-app .ut-preset:hover{ background:var(--a-raised); color:var(--a-text); border-color:var(--a-line-strong); }
.alt-app .ut-preset:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }
/* Keyed on the attribute as well as the class, so the appearance and what a screen reader reads
   cannot drift apart. Three signals: a wash, a full border and a heavier weight. */
.alt-app .ut-preset[aria-pressed="true"]{
  background:var(--a-blue-soft); border-color:var(--a-blue); color:var(--a-blue-text);
  font-weight:700;
}

.alt-app .ut-cal{ display:flex; flex-direction:column; gap:var(--a-2); min-width:0; }
.alt-app .ut-cal-nav{
  display:flex; align-items:center; justify-content:space-between; gap:var(--a-2); min-width:0;
}
.alt-app .ut-cal-nav-lbl{
  font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  color:var(--a-faint); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.alt-app .ut-cal-step{
  display:flex; align-items:center; justify-content:center;
  width:26px; height:26px; flex:0 0 26px; padding:0;
  border:1px solid var(--a-line); border-radius:var(--a-r-sm);
  background:var(--a-panel); color:var(--a-dim);
  font-size:14px; line-height:1; cursor:pointer;
}
.alt-app .ut-cal-step:hover{ background:var(--a-raised); color:var(--a-text); }
.alt-app .ut-cal-step:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }

/* Two months side by side where there's room, stacked where there's not. `minmax(0,1fr)`, not
   `1fr` — a seven-column grid inside a bare `1fr` track refuses to go narrower than its widest
   cell. */
.alt-app .ut-cal-months{
  display:grid; gap:var(--a-3); grid-template-columns:minmax(0, 1fr); min-width:0;
}
.alt-app .ut-cal-month{ min-width:0; }
.alt-app .ut-cal-head{
  margin-bottom:4px; font-size:11px; font-weight:700; color:var(--a-text);
}
.alt-app .ut-cal-grid{
  display:grid; grid-template-columns:repeat(7, minmax(0, 1fr)); gap:2px; min-width:0;
}
.alt-app .ut-cal-dow{
  font-size:9px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color:var(--a-faint); text-align:center; padding-bottom:2px;
}
/* A day is a real button — 28px is above the 24px floor a pointer needs at this density, and
   the grid sits inside a layer that can scroll, so the cell is never shrunk to fit a narrow pane. */
.alt-app .ut-day{
  display:flex; align-items:center; justify-content:center;
  min-width:0; min-height:28px; padding:0;
  border:1px solid transparent; border-radius:var(--a-r-sm);
  background:transparent; color:var(--a-text);
  font-family:var(--a-body); font-size:11px; font-variant-numeric:tabular-nums;
  cursor:pointer;
}
.alt-app .ut-day.is-pad{ cursor:default; }
.alt-app .ut-day:hover:not(:disabled){ background:var(--a-raised); border-color:var(--a-line-strong); }
.alt-app .ut-day:focus-visible{ outline:2px solid var(--a-ring); outline-offset:1px; }
/* After today, nothing is recorded — disabled rather than absent, so a calendar missing its
   last third reads as a bounded grid rather than a broken one. */
.alt-app .ut-day:disabled{ color:var(--a-faint); cursor:not-allowed; opacity:.55; }
/* Inside the selection: a wash, and the two ends additionally carry a border and a weight, so
   the range and its endpoints are three states rather than two shades of one. */
.alt-app .ut-day.is-in{ background:var(--a-blue-soft); color:var(--a-blue-text); }
.alt-app .ut-day.is-end{
  background:var(--a-blue-fill); border-color:var(--a-blue); color:var(--a-blue-text);
  font-weight:700;
}
/* Today is marked whether or not it is selected, by an underline rather than a colour, so it
   survives sitting inside the selection wash. */
.alt-app .ut-day.is-today{ text-decoration:underline; text-underline-offset:2px; }

/* The footer — Apply and Cancel exist only for the custom path (a preset applies on its own
   press), and Apply disables while the draft is half finished, with a sentence beside it saying
   which half is missing rather than leaving a dead button to be guessed at. */
.alt-app .ut-range-actions{
  display:flex; align-items:center; gap:var(--a-2); flex-wrap:wrap; min-width:0;
  padding-top:var(--a-2); border-top:1px solid var(--a-line-soft);
}
.alt-app .ut-range-state{
  margin:0; flex:1 1 200px; min-width:0;
  font-size:11px; line-height:1.5; color:var(--a-dim); overflow-wrap:anywhere;
}
.alt-app .ut-range-apply:disabled{ opacity:.55; cursor:not-allowed; }
.alt-app .ut-range-note{ margin-top:0; }

@container sxpane (min-width: 520px){
  .alt-app .ut-cal-months{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
}

/* ---------- the notes under the filter bar ----------
   Two separate facts (what the range reaches, what the record can't say) as two paragraphs; the
   host disappears entirely when there's nothing to say — a permanent paragraph gets skipped. */
.alt-app .ut-notes{
  display:flex; flex-direction:column; gap:4px; min-width:0;
}
.alt-app .ut-notes[hidden]{ display:none; }

/* The read failed and nothing here would be current — above the tablist so it's visible from
   any view. `role="alert"` on the element; border and soft fill are the second and third
   signals, since red alone isn't received by every reader. */
.alt-app .ut-unreadable{
  padding:var(--a-3); min-width:0;
  border:1px solid var(--a-red); border-left-width:3px; border-radius:var(--a-r);
  background:var(--a-red-soft); color:var(--a-text);
  font-size:12px; line-height:1.5; font-weight:600; overflow-wrap:anywhere;
}
.alt-app .ut-unreadable[hidden]{ display:none; }

/* ---------- the four states every surface needs ----------
   Loading/empty/filtered-empty/error are four different answers — a false zero mid-read is the
   one thing none may show. The kind is carried as data so a view can style by meaning; `.is-err`
   is accepted too (one lane specified that form) rather than drifting into two rules. `filtered`
   is the one with an affordance — a Clear-filters button, since "nothing matches" needs a way
   back. */
.alt-app .ut-states{ display:flex; flex-direction:column; gap:var(--a-2); min-width:0; }
.alt-app .ut-state{
  padding:var(--a-4); min-width:0;
  font-size:12px; line-height:1.6; color:var(--a-dim); text-align:center;
  overflow-wrap:anywhere;
}
.alt-app .ut-state[data-state="error"],
.alt-app .ut-state.is-err{ color:var(--a-red); font-weight:600; }
.alt-app .ut-state[data-state="filtered"]{ color:var(--a-text); }
.alt-app .ut-state[data-state="loading"]{ color:var(--a-faint); }

/* ---------- the log and roster tables ----------
   The table itself is `.a-admin-table`/`.a-admin-tscroll` (alt-admin.css) — nothing below
   redeclares either; these are the modifiers the views add on top. */

.alt-app .ut-log-toolbar,
.alt-app .ut-log-pager,
.alt-app .ut-pager{
  display:flex; align-items:center; gap:var(--a-2); flex-wrap:wrap; min-width:0;
}
.alt-app .ut-pager{ margin-top:var(--a-3); }
.alt-app .ut-pagestat,
.alt-app .ut-pager-count{
  font-size:11px; color:var(--a-dim); font-variant-numeric:tabular-nums; min-width:0;
}

/* A sortable header — the button inherits the th's own type so the heading doesn't resize when
   it becomes sortable; sorted state keys off `[aria-sort]` on the th itself, so appearance and
   what a screen reader hears cannot drift apart. */
.alt-app .ut-sortbtn{
  padding:0; border:none; background:transparent; color:inherit;
  font:inherit; letter-spacing:inherit; text-transform:inherit; text-align:inherit;
  cursor:pointer; min-width:0;
}
.alt-app .ut-sortbtn:hover{ color:var(--a-text); text-decoration:underline; }
.alt-app .ut-sortbtn:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }
.alt-app .a-admin-table th[aria-sort="ascending"] .ut-sortbtn,
.alt-app .a-admin-table th[aria-sort="descending"] .ut-sortbtn{
  color:var(--a-text); font-weight:700;
}
.alt-app .a-admin-table th[aria-sort="ascending"],
.alt-app .a-admin-table th[aria-sort="descending"]{
  box-shadow:inset 0 -2px 0 0 var(--a-blue);
}

/* An activatable row — these carry tabindex="0" and role="button" from their view, so the ring
   is inset; an outline on a table row is clipped by the scroller it sits in. */
.alt-app .ut-row{ cursor:pointer; }
.alt-app .ut-row:hover{ background:var(--a-raised); }
.alt-app .ut-row:focus-visible{ outline:none; box-shadow:inset 0 0 0 2px var(--a-ring); }
.alt-app .ut-row.is-open{ background:var(--a-blue-soft); font-weight:600; }

/* The organization header row inside "Teams, compared" is deliberately NOT `.a-admin-disc`
   (alt-admin.css) — that class sets `display:flex`, which would break a <tr>'s column alignment
   with the plain rows around it; a table row needs `display:table-row` to keep its cells lined
   up. Same recipe otherwise (uppercase, dim, a rotating chevron), for a <tr>/<th> pair instead
   of a flex container. Team rows hide individually (`tr.hidden`) since a <tbody> only ever
   holds <tr> children — there's no wrapper to hide instead. */
.alt-app .ut-team-org-head{ cursor:pointer; }
.alt-app .ut-team-org-head th{
  text-align:left; font-family:var(--a-body); font-size:12px; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--a-dim);
  padding:10px 8px 6px;
}
.alt-app .ut-team-org-head:hover th{ color:var(--a-text); }
.alt-app .ut-team-org-head:focus-visible{ outline:2px solid var(--a-ring); outline-offset:-2px; }
.alt-app .ut-team-org-head .chev{
  display:inline-block; margin-right:6px; transition:transform var(--a-quick) var(--a-ease);
}
.alt-app .ut-team-org-head.collapsed .chev{ transform:rotate(-90deg); }
.alt-app .ut-users-tbl tbody tr{ cursor:pointer; }
.alt-app .ut-users-tbl tbody tr:hover{ background:var(--a-raised); }
.alt-app .ut-users-tbl tbody tr.is-open{
  background:var(--a-blue-soft); font-weight:600;
  box-shadow:inset 2px 0 0 0 var(--a-blue);
}

/* No actor, and it's a fact rather than a gap — `tasks.user_id` is the OWNER, not who acted, so
   a reconstructed row deliberately shows nobody (italic/faint, not a name that failed to load). */
.alt-app .ut-noactor{ font-style:italic; color:var(--a-faint); }

/* Where a row came from: recorded, sign-in, account, reconstructed. Four values, each
   distinguishable by edge and fill rather than hue alone. */
.alt-app .ut-src{
  display:inline-block; padding:1px 6px; max-width:100%;
  border:1px solid var(--a-line); border-radius:var(--a-r-pill);
  background:var(--a-raised); color:var(--a-dim);
  font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.alt-app .ut-src[data-src="event"]{ border-color:var(--a-blue); background:var(--a-blue-soft); color:var(--a-blue-text); }
.alt-app .ut-src[data-src="session"]{ border-color:var(--a-purple); background:var(--a-purple-soft); color:var(--a-text); }
.alt-app .ut-src[data-src="account"]{ border-color:var(--a-green); background:var(--a-green-soft); color:var(--a-text); }
/* Reconstructed is the one the reader must not mistake for a measurement, so it's the one with
   a dashed edge — a figure recovered from the data rather than an event that was captured. */
.alt-app .ut-src[data-src="derived"]{ border-style:dashed; border-color:var(--a-line-strong); }

/* A badge whose meaning is never the colour — each modifier changes the border as well, and the
   text inside says what it is. */
.alt-app .ut-pill,
.alt-app .ut-flag{
  display:inline-block; padding:1px 6px; max-width:100%;
  border:1px solid var(--a-line); border-radius:var(--a-r);
  background:var(--a-raised); color:var(--a-dim);
  font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.alt-app .ut-pill.is-active{ border-color:var(--a-green); background:var(--a-green-soft); color:var(--a-text); }
.alt-app .ut-pill.is-idle{ border-color:var(--a-gold); background:var(--a-gold-soft); color:var(--a-text); }
.alt-app .ut-pill.is-inactive{ border-style:dashed; }
.alt-app .ut-pill.is-disabled{ border-color:var(--a-red); background:var(--a-red-soft); color:var(--a-text); }
.alt-app .ut-flag{ border-color:var(--a-amber); background:var(--a-amber-soft); color:var(--a-text); }

/* A name that opens something — a button reset rather than a link, because it navigates nowhere. */
.alt-app .ut-name-btn{
  padding:0; border:none; background:transparent; color:var(--a-text);
  font:inherit; text-align:left; cursor:pointer; min-width:0;
  overflow-wrap:anywhere;
}
.alt-app .ut-name-btn:hover{ text-decoration:underline; font-weight:600; }
.alt-app .ut-name-btn:focus-visible{ outline:2px solid var(--a-ring); outline-offset:2px; }

/* The short-id fallback, when an event names an account that no longer exists — monospace so it
   reads as an identifier rather than as a name this code failed to resolve. */
.alt-app .ut-id{ font-family:var(--a-mono); font-size:10px; color:var(--a-faint); }

/* ---------- the trend strip ----------
   Two forms, one class, separated by a modifier: the default is bars sized from an inline
   `--ut-v` (same technique as storage-charts.js's `--sxc-v`); `.is-line` is inline SVG, whose
   stroke is `currentColor` so it needs no rule here. */
.alt-app .ut-spark{
  display:flex; align-items:flex-end; gap:2px;
  height:44px; max-width:140px; min-width:0;
}
.alt-app .ut-spark-bar{
  flex:1 1 0; min-width:2px; height:var(--ut-v, 0%);
  background:var(--a-blue); border-radius:2px 2px 0 0;
}
.alt-app .ut-spark > svg{ width:100%; height:100%; display:block; }
.alt-app .ut-spark.is-line{ display:block; height:24px; max-width:120px; }
.alt-app .ut-trend-btn{ font-size:11px; }

/* ---------- the drawer's own content ----------
   Geometry is `.sx-drawer`'s (alt-storage-panels.css) — nothing here positions or sizes the
   drawer; these are only the blocks the Users view builds inside it. */
.alt-app .ut-drawer[hidden]{ display:none; }
.alt-app .ut-export[hidden]{ display:none; }
.alt-app .ut-drawer-body,
.alt-app .ut-export-body{
  display:flex; flex-direction:column; gap:var(--a-4); min-width:0;
}

.alt-app .ut-facts{
  display:grid; gap:var(--a-3);
  grid-template-columns:repeat(auto-fit, minmax(min(100%, 150px), 1fr));
  margin:0; min-width:0;
}
.alt-app .ut-fact{ display:flex; flex-direction:column; gap:1px; min-width:0; }

.alt-app .ut-detail{
  display:grid; gap:var(--a-1) var(--a-3);
  grid-template-columns:minmax(0, auto) minmax(0, 1fr);
  margin:0; min-width:0;
}
.alt-app .ut-detail-k,
.alt-app .ut-sess-k{
  font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color:var(--a-faint); min-width:0;
}
/* A full address and a raw user agent both live here, and neither may widen the layer. */
.alt-app .ut-detail-v,
.alt-app .ut-sess-v{
  font-size:12px; color:var(--a-text); min-width:0; overflow-wrap:anywhere;
}
.alt-app .ut-detail-note{
  grid-column:1 / -1; margin:var(--a-2) 0 0;
  font-size:11px; line-height:1.5; color:var(--a-faint); max-width:78ch;
}

.alt-app .ut-sess,
.alt-app .ut-rel{ display:flex; flex-direction:column; gap:var(--a-3); min-width:0; }
.alt-app .ut-sess-row,
.alt-app .ut-rel-row{
  display:grid; gap:2px var(--a-3); grid-template-columns:minmax(0, 1fr); min-width:0;
  padding-bottom:var(--a-2); border-bottom:1px solid var(--a-line-soft);
}
.alt-app .ut-sess-row:last-child,
.alt-app .ut-rel-row:last-child{ border-bottom:none; padding-bottom:0; }

/* Parsed from a user agent, which is a guess and is labelled as one — a reader acting on it
   needs to know it's a client-side interpretation, never a fact the database recorded. */
.alt-app .ut-derived{ font-size:10px; font-style:italic; color:var(--a-faint); }

/* ---------- the journey timeline ----------
   The left rule is what reads as a timeline — a border on the item list, not a pseudo-element,
   so it can't come apart from the items it belongs to. */
.alt-app .ut-tl{ display:flex; flex-direction:column; gap:var(--a-3); min-width:0; }
.alt-app .ut-tl-day{
  position:sticky; top:0; z-index:var(--z-sticky);
  padding:2px 0; background:var(--a-panel);
  font-size:10px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color:var(--a-faint); border-bottom:1px solid var(--a-line-soft);
}
.alt-app .ut-tl-items{
  border-left:1px solid var(--a-line-soft);
  margin-left:8px; padding-left:var(--a-4); min-width:0;
}
/* Every child is placed by name, not DOM order — auto-placement would make this layout depend
   on the order the view happens to append its four parts in, so a later reorder would silently
   move the time under the icon instead. */
.alt-app .ut-tl-item{
  display:grid; gap:2px var(--a-3); min-width:0;
  grid-template-columns:56px 20px minmax(0, 1fr);
  align-items:start; padding:var(--a-2) 0;
}
.alt-app .ut-tl-time{
  grid-column:1; grid-row:1;
  font-size:11px; color:var(--a-dim); font-variant-numeric:tabular-nums; min-width:0;
}
.alt-app .ut-tl-ico{
  grid-column:2; grid-row:1;
  display:flex; align-items:center; justify-content:center;
  width:20px; height:20px; flex:0 0 20px;
  border:1px solid var(--a-line); border-radius:var(--a-r-pill);
  background:var(--a-panel); color:var(--a-dim);
}
.alt-app .ut-tl-ico svg{ width:14px; height:14px; }
.alt-app .ut-tl-act,
.alt-app .ut-tl-meta,
.alt-app .ut-tl-ctx,
.alt-app .ut-tl-session{ grid-column:3; min-width:0; overflow-wrap:anywhere; }
.alt-app .ut-tl-act{ font-size:13px; font-weight:600; color:var(--a-text); }
.alt-app .ut-tl-meta{ font-size:11px; color:var(--a-faint); }
.alt-app .ut-tl-ctx{ font-size:11px; color:var(--a-dim); }
.alt-app .ut-tl-session{ font-size:10px; justify-self:start; margin-top:2px; }

/* A note belonging to the Teams view, kept at the type floor beside the panel it explains. */
.alt-app .ut-teams-note{
  margin:var(--a-2) 0 0; font-size:11px; line-height:1.5; color:var(--a-faint); max-width:78ch;
}

/* ---------- the narrow steps ----------
   The PANE's width, not the window's — at 320px the console has already stacked, so these are
   what the pane itself still needs: the popover fills it, the timeline's time column moves
   above the item instead of squeezing to nothing, and the facts grid collapses to one column. */
@container sxpane (max-width: 559px){
  .alt-app .ut-range-pop{
    position:static; width:auto; max-height:none; box-shadow:var(--a-shadow-sm);
    margin-top:var(--a-2);
  }
  .alt-app .ut-range-btn{ flex:1 1 100%; }
  .alt-app .ut-spark{ max-width:none; }
  /* The time moves above the item rather than squeezing to nothing — a 56px column holding
     "11:47 PM" is the first thing to break at 320px; the icon stays in its own column so the
     item still reads as one entry, not three stacked lines. */
  .alt-app .ut-tl-item{ grid-template-columns:20px minmax(0, 1fr); }
  .alt-app .ut-tl-ico{ grid-column:1; grid-row:1; }
  .alt-app .ut-tl-time{ grid-column:2; grid-row:1; }
  .alt-app .ut-tl-act,
  .alt-app .ut-tl-meta,
  .alt-app .ut-tl-ctx,
  .alt-app .ut-tl-session{ grid-column:2; }
  .alt-app .ut-facts{ grid-template-columns:minmax(0, 1fr); }
  .alt-app .ut-detail{ grid-template-columns:minmax(0, 1fr); }
  .alt-app .ut-detail-k{ margin-top:var(--a-2); }
}
