/* ui.css: the pieces both first-ship apps are made of (RN441, 2 Oct 2026).
   One drawer, one foot, one value pill, one section, one picker, one calendar, one signing pad, one symbol set,
   one motion. A screen is composed from these; it does not bring its own.
   The record of each piece (what backs it, Ryan's state) is in prototype/design-system/PATTERNS.md.
   Written against role values (--ui-*). Each app sets them once (operator.css, client.css). */

.ui-root {
  /* The one motion (RN612). What arrives settles like something with a little weight, and nothing is sudden.
     A surface (a drawer, a view, a row that makes room) glides to rest. A small thing (a card, a pill, a lens) rises
     and lands on a soft spring: the same lift the items that need her show, a few parts in a hundred past its place
     and back, never a wobble. What leaves goes quietly and quicker. Blur clears as a thing arrives and returns as
     it goes. */
  --ui-ease: cubic-bezier(0.32, 0.72, 0, 1);
  --ui-spring: cubic-bezier(0.3, 1.3, 0.4, 1);
  --ui-t-spring: 720ms;
  --ui-exit: cubic-bezier(0.4, 0, 1, 1);
  --ui-t: 420ms;        /* blur in; blur out is quicker */
  --ui-t-drawer: 460ms; /* the drawer's edge keeps its settled glide while its height stays out of layout */
  --ui-t-wait: 900ms;   /* one breath shared by waiting controls and the drawer */
  --ui-ease-wait: ease-in-out;
  --ui-wait-strength: 0.54; /* peak strength of the button's wait veil; the drawer uses one third */
  --ui-blur: 14px;
  --ui-edge-cut: 24px;  /* the distance over which a list thins at a fixed edge */
  --ui-tap: 44px;       /* the floor for anything touched */
  /* The bodies a control can have, one recipe each, so no two pieces differ by accident (RN553). All of them are
     flat: an even fill and, where there is an edge, an even hairline. No lip of light, no dome, no inner shadow.
     Glass: something you touch. Well: something that holds what you type, pick or draw. */
  --ui-glass: rgba(255, 255, 255, 0.07);
  /* the search bar's own ground, and the ink on it: one bar wherever she searches (RN673) */
  --ui-frost: rgba(255, 255, 255, 0.82); --ui-frost-edge: rgba(255, 255, 255, 0.5); --ui-frost-ink: #0b111e; --ui-frost-ink-2: rgba(11, 17, 30, 0.66);
  --ui-edge: rgba(255, 255, 255, 0.15);
  --ui-well: rgba(0, 0, 0, 0.24);
  --ui-well-edge: rgba(255, 255, 255, 0.1);
  --ui-on-a: var(--tune-acton, 0.34);      /* how strongly the chosen one is filled with the class colour; his hand control may set it (RN999) */
  --ui-lens: var(--ui-t-spring) var(--ui-spring);   /* how a lens travels to the next choice, in a track, a toggle or a dock */
}
@supports (animation-timing-function: linear(0, 1)) { .ui-root { --ui-spring: linear(0, 0.043, 0.146, 0.28, 0.423, 0.561, 0.685, 0.79, 0.874, 0.938, 0.984, 1.015, 1.034, 1.043, 1.046, 1.044, 1.039, 1.033, 1.027, 1.02, 1.014, 1.01, 1.006, 1.003, 1.001, 1); } }

/* ── the one motion ───────────────────────────────────────────────────── */
@property --ui-fl { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --ui-fl0 { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --ui-fr { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --ui-cut { syntax: "<length>"; inherits: false; initial-value: 0px; }
/* the top fade belongs to the one scroller it was measured on: a list inside a scrolled drawer starts clear */
@property --ui-ft { syntax: "<length>"; inherits: false; initial-value: 0px; }
/* how far up the foot of a scroller dissolves; it grows while something stands over that foot */
@property --ui-fb { syntax: "<length>"; inherits: true; initial-value: 22px; }
/* how far up the foot of a scrolled list dissolves: the more there is below, up to its full reach; none at the list's end (ui.js listFoot) */
/* its own name (28 Oct): it once shared --ui-fl, a sideways row's left fade, and its 26px start put that fade over the first pill of
   every row not scrolled from its start (RN1392: a row shows a left fade only once it is scrolled away from its start) */
@property --ui-lf { syntax: "<length>"; inherits: false; initial-value: 26px; }
/* what changes in place (a drawer's swap) sets --ui-out-to and --ui-in-from: the old leaves to a soft blurred floor and the new
   comes from that same floor, so no frame is ever an empty drawer while the new is being built; everywhere else both are 0 */
@keyframes ui-in { from { opacity: var(--ui-in-from, 0); filter: var(--ui-point-in-filter, blur(var(--ui-blur))); transform: translateY(6px) scale(0.985); } to { opacity: 1; filter: blur(0); transform: none; } }
@keyframes ui-out { from { opacity: 1; filter: blur(0); transform: none; } to { opacity: var(--ui-out-to, 0); filter: blur(var(--ui-blur)); transform: scale(0.985); } }
.ui-in { animation: ui-in var(--ui-t) var(--ui-ease) both; }
.ui-out { animation: ui-out 200ms var(--ui-exit) both; pointer-events: none; }
/* the thing under the lens owns its entry blur; its siblings arrive already soft with it */
.ui-point-in { --ui-point-in-filter: none; }

/* ── scrim and drawer ─────────────────────────────────────────────────── */
.ui-scrim { position: absolute; inset: 0; z-index: 40; background: var(--ui-scrim, rgba(2, 5, 12, 0.42)); -webkit-backdrop-filter: blur(10px) saturate(0.9); backdrop-filter: blur(10px) saturate(0.9); opacity: 0; pointer-events: none; transition: opacity 300ms ease; }
/* the dimming behind a drawer runs on the drawer's own clock, so the two arrive as one (RN645) */
.ui-scrim.on { opacity: 1; pointer-events: auto; transition: opacity 560ms var(--ui-ease); }
/* The veil and the drawer stay their own layers for good (RN1254, 18 Oct, his recording): on his Pixel, the frame where their
   560 ms slide and fade ended was drawn with both missing (the list behind shone full bright, the drawer's words
   ghosted), with a dropped frame either side, because the phone took them back into the page the moment the motion
   stopped. Kept as their own layers, nothing is taken back. The drawer's layer is no lens for what is inside it. */
.ui-scrim { will-change: opacity; }
.ui-drawer { will-change: transform; }
/* a touch flashes nothing of the browser's own, in either app: what was touched answers in the kit's way (15a, RN960) */
html { -webkit-tap-highlight-color: transparent; }

/* Glass only where it shows (RN1246, 17 Oct 2026). The blur lives in the dimming above a drawer and in the band behind
   a message at the top, where what is behind it moves and the softening is seen; the dock and the studio's picture keep
   theirs. The drawer itself stands solid in its own colour, and so does everything in it, every small pill that floats
   over a moving list, and every card on the plain ground: there a blur showed nothing and cost every frame. */
.ui-drawer {
  --c-rgb: var(--ui-accent-rgb);
  --ui-size-y: 0px;
  position: absolute; z-index: 41; left: 0; right: 0; bottom: 0; max-height: calc(100% - var(--safe-top, 12px) - 28px);
  display: flex; flex-direction: column; border-radius: 28px 28px 0 0; isolation: isolate; overflow: hidden;
  border: 1px solid var(--ui-sheet-edge); border-bottom: 0;
  background: var(--ui-sheet);
  /* the rim (RN1401): one hairline all round, and the class's light along the top edge that follows the corners down
     and fades as the edge turns, never a line drawn straight across the glass ("a kid took a white marker") */
  box-shadow: inset 0 1px 0 rgba(var(--ui-rim-rgb, var(--c-rgb)), var(--ui-rim-a, 0.55)), 0 -36px 100px -30px rgba(0, 0, 0, 0.9);
  color: var(--ui-ink); transform: translateY(calc(100% + 80px + var(--ui-size-y))); visibility: hidden;
  transition: transform 300ms var(--ui-exit), translate 300ms var(--ui-exit), visibility 0s linear 300ms, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease;
}
/* held at its start for the two frames it takes to be drawn, so the slide is seen whole (ui.js UI.open) */
.ui-drawer.open.ui-hold { transform: translateY(calc(100% + 80px + var(--ui-size-y))); translate: none; transition: visibility 0s; }
.ui-drawer.open { transform: translateY(var(--ui-size-y)); visibility: visible; transition: transform 560ms var(--ui-ease), translate 560ms var(--ui-ease), visibility 0s, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease; }
/* The box stays at its tallest while its edge moves (RN1257), so the layers that paint the glass (the glow at its top,
   the lit wash, a colour or frost settling at its foot) are drawn for the box and drawn down to the part in sight: they
   stand exactly where they stood when the box itself was that tall, and a scale costs no frame a layout or a repaint.
   A one-pixel rim keeps its pixel by the same factor. */
.ui-drawer::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: radial-gradient(70% 30% at 50% -6%, rgba(255, 255, 255, 0.09), transparent 70%); }
.ui-drawer::before, .ui-drawer > .ui-lit, .ui-drawer::after { transform-origin: 50% 0; transform: scaleY(var(--ui-size-s, 1)); }
.ui-drawer.ui-size-glide::before { transition: transform var(--ui-t-drawer) var(--ui-ease); }
.ui-drawer.ui-size-glide > .ui-lit { transition: transform var(--ui-t-drawer) var(--ui-ease), filter 200ms var(--ui-exit); }
.ui-drawer.ui-size-glide::after { transition: transform var(--ui-t-drawer) var(--ui-ease), opacity 900ms cubic-bezier(0.3, 0, 0.2, 1); }
/* The tallest sheet box stays in place while its edge moves down, the body clips to it and the foot meets it, so the glass keeps its old glide without laying out a frame. */
.ui-drawer.ui-size-glide { transition: transform var(--ui-t-drawer) var(--ui-ease), translate 560ms var(--ui-ease), visibility 0s, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease; }
.ui-drawer.ui-size-glide > .ui-body { transition: clip-path var(--ui-t-drawer) var(--ui-ease); }
.ui-drawer.ui-size-glide > .ui-foot { transition: transform var(--ui-t-drawer) var(--ui-ease); }
/* room for a phone's keyboard (RN943): while she types in a field that answers beneath itself, the drawer stands over
   where the keys are, and its glass runs on down behind them, rising with it */
.ui-drawer.keys { translate: 0 calc(-1 * var(--ui-keys, 0px)); max-height: calc(100% - var(--ui-keys, 0px) - var(--safe-top, 12px) - 28px); }
/* its own subject, never :has() over the whole device: an anchor that holds the page restyled every element in it at each
   small change inside a drawer (37-46 ms a change at 4x) */
.ui-has-drawer > .ui-scrim:has(~ .ui-drawer.keys)::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--ui-keys, 0px); background: var(--ui-sheet); animation: ui-keys-up 560ms var(--ui-ease) both; }
@keyframes ui-keys-up { from { height: 0; } }
.ui-drawer[data-kind="private"] { --c-rgb: var(--ui-private-rgb); }
.ui-drawer[data-kind="duet"] { --c-rgb: var(--ui-duet-rgb); }
.ui-drawer[data-kind="group"] { --c-rgb: var(--ui-group-rgb); }
/* a frozen package's drawer is its card opened (RN986): the glass turns to ice, with the crisp white edge and the cold
   frost settling at the foot that the card has. What is the class's own (its pill, the lens, the main act) keeps its
   colour, as the writing, the dot and the dashes do on the card. */
.ui-drawer[data-ice="1"] { --ui-ice-rgb: 186, 222, 250; --ui-rim-rgb: 228, 242, 253; --ui-rim-a: 0.8; }
.ui-drawer[data-ice="1"] .ui-lit { background:
    radial-gradient(120% 46% at 6% -8%, rgba(var(--ui-ice-rgb), 0.3), transparent 66%),
    radial-gradient(70% 30% at 100% 0%, rgba(var(--ui-ice-rgb), 0.16), transparent 72%),
    radial-gradient(150% 40% at 50% 112%, rgba(var(--ui-ice-rgb), 0.46), transparent 72%),
    linear-gradient(rgba(var(--ui-ice-rgb), 0.07), rgba(var(--ui-ice-rgb), 0.07)); }
.ui-drawer[data-ice="1"]::after { background: linear-gradient(rgba(var(--ui-ice-rgb), 0.1), rgba(var(--ui-ice-rgb), 0.04) 46%, rgba(var(--ui-ice-rgb), 0.08)); }
.ui-drawer[data-ice="1"].is-lit { border-color: rgba(var(--ui-ice-rgb), 0.7); }
/* A finished package's drawer keeps the empty glass and pale ink of its card, including views opened from it. */
.ui-drawer[data-finished="1"] { --ui-finish-rgb: 240, 244, 250; --ui-ink: rgba(var(--ui-finish-rgb), 0.84); --ui-ink-2: rgba(var(--ui-finish-rgb), 0.56); --ui-ink-3: rgba(var(--ui-finish-rgb), 0.44);
  --ui-rim-rgb: 255, 255, 255; --ui-rim-a: 0.17; }
.ui-drawer[data-finished="1"]::before { background: linear-gradient(158deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0) 40%), linear-gradient(172deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.045)); }
.ui-drawer[data-finished="1"] .ui-lit { background: linear-gradient(rgba(var(--ui-finish-rgb), 0.035), rgba(var(--ui-finish-rgb), 0.035)); }
.ui-drawer[data-finished="1"]::after { background: linear-gradient(rgba(var(--ui-finish-rgb), 0.08), rgba(var(--ui-finish-rgb), 0.03) 46%, rgba(var(--ui-finish-rgb), 0.06)); }
.ui-drawer[data-finished="1"].is-lit { border-color: rgba(var(--ui-finish-rgb), 0.34); }
.ui-lit { position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(120% 50% at 6% -8%, rgba(var(--c-rgb), 0.5), transparent 66%),
    radial-gradient(70% 34% at 100% 0%, rgba(var(--c-rgb), 0.24), transparent 72%),
    radial-gradient(140% 42% at 72% 112%, rgba(var(--c-rgb), 0.3), transparent 72%),
    linear-gradient(rgba(var(--c-rgb), 0.07), rgba(var(--c-rgb), 0.07)); filter: brightness(1); transition: filter 200ms var(--ui-exit); }
/* Lit glass (RN645): a pad with ink on it lights the glass it stands in, the way a pane lit from its edge looks. The rim
   takes the class colour and the glass a faint, even wash of it. Nothing is brightened, nothing glows outside the
   drawer, and nothing switches on: the lit layer is always drawn and only fades in, slowly ("too much like a light
   bulb", "a bit jerky"). An empty pad is never lit. */
.ui-drawer::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 900ms cubic-bezier(0.3, 0, 0.2, 1);
  background: linear-gradient(rgba(var(--c-rgb), 0.1), rgba(var(--c-rgb), 0.04) 46%, rgba(var(--c-rgb), 0.08)); }
.ui-drawer.is-lit::after { opacity: 1; }
.ui-drawer.is-lit { border-color: rgba(var(--c-rgb), 0.7); }

.ui-grip { flex: none; width: 38px; height: 5px; margin: 8px auto 2px; border-radius: 3px; background: rgba(204, 217, 215, 0.24); }
.ui-body { position: relative; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 18px 20px; display: flex; flex-direction: column; gap: 14px; clip-path: inset(0 0 var(--ui-size-y, 0px));
  -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-fb, 22px)), rgba(0, 0, 0, 0.14) calc(100% - var(--ui-fb, 22px) * 0.5), transparent calc(100% - var(--ui-fb, 22px) * 0.1)); mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-fb, 22px)), rgba(0, 0, 0, 0.14) calc(100% - var(--ui-fb, 22px) * 0.5), transparent calc(100% - var(--ui-fb, 22px) * 0.1)); }
/* --ui-ft grows with the first pixels scrolled: what passes under the top edge dissolves into it, never a hard cut (RN172) */
.ui-body::-webkit-scrollbar { display: none; }
.ui-body { scrollbar-width: none; }
/* the drawer box is held at its tallest while its edge moves (--ui-size-y), so the body has room it does not show: nothing in it grows into that room
   (a wide track grew into a half circle in Open your studio, 18 Oct) */
.ui-drawer.ui-drawer .ui-body > * { flex-grow: 0; }   /* doubled so it outweighs a wide track's own grow (.ui-seg.wide) */
/* the body scrolls; its blocks keep their full height (a clipped list hid its later rows) */
.ui-body > * { flex-shrink: 0; }

/* The foot: where the thumb is. Back on the left, the one main action on the right. Never an X at the top. */
.ui-foot { flex: none; display: flex; align-items: center; gap: 10px; padding: 6px 18px calc(var(--safe-bottom, 0px) + 16px); transform: translateY(calc(-1 * var(--ui-size-y, 0px))); }
.ui-foot { transition: opacity 0.28s ease; }
.ui-foot.is-spent { opacity: 0; pointer-events: none; }
/* removing acts in the foot, across from back, when the drawer has no main act (RN1379) */
.ui-foot-ends { margin-left: auto; display: flex; align-items: center; gap: 20px; min-width: 0; }
.ui-foot-ends[hidden], .ui-ends.in-foot { display: none !important; }
.ui-foot-ends .ui-text-act { min-height: var(--ui-tap); white-space: nowrap; }
.ui-foot-ends.beside { margin-left: 0; flex: none; }
.ui-back { flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; color: var(--ui-ink); background: var(--ui-glass); box-shadow: inset 0 0 0 1px var(--ui-edge); transition: transform 160ms var(--ui-ease), background-color 160ms; }
.ui-back:active { transform: scale(0.94); background: rgba(255, 255, 255, 0.12); }
.ui-back svg { width: 22px; height: 22px; }
.ui-go { flex: 1; min-width: 0; height: 56px; padding: 0 20px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; font: 700 16px var(--ui-font); letter-spacing: -0.01em; color: var(--ui-on-accent);
  background: var(--ui-go); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: opacity 260ms ease, filter 260ms ease, transform 160ms var(--ui-ease), background-color 260ms ease; }
.ui-go:active { transform: scale(0.98); filter: brightness(0.92); }
.ui-go[disabled] { opacity: 0.32; filter: saturate(0.2); pointer-events: none; }
.ui-go.ui-guides { opacity: 0.32; filter: saturate(0.2); }
:root[data-mode="day"] .ui-drawer[data-kind]:not([data-kind=""]) .ui-go.ui-guides:not([disabled]) { opacity: 1; filter: none; color: var(--ui-ink-3); background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-edge); }
.ui-go.danger { color: #fff; background: #c93a50; }
.ui-go[hidden] { display: none; }
.ui-go svg { width: 20px; height: 20px; }

/* ── type inside a drawer ─────────────────────────────────────────────── */
.ui-title { font: 650 21px/1.15 var(--ui-font); letter-spacing: -0.03em; }
.ui-title .amp { font-weight: 300; color: var(--ui-ink-3); margin: 0 0.24em; }
.ui-eyebrow { font: 650 10.5px var(--ui-font); letter-spacing: 0.13em; text-transform: uppercase; color: var(--ui-ink-3); }
.ui-kind { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; min-height: 28px; padding: 0 10px; border-radius: 12px; background: rgba(var(--c-rgb), 0.32); font: 700 12px var(--ui-font); }
.ui-kind i { font: 600 11px var(--ui-font-num); font-style: normal; flex: none; white-space: nowrap; padding: 3px 7px; border-radius: 8px; background: rgba(0, 0, 0, 0.28); color: var(--ui-ink-2); }
/* a studio names its own class types: a long name gives way, the count beside it never does */
.ui-kind { min-width: 0; max-width: 100%; white-space: nowrap; }
.ui-kind .nm { min-width: 0; overflow: clip visible; text-overflow: ellipsis; }
/* the count's plate keeps its own height (one line and its 3px above and below); its figures are trimmed to their capitals and stand at its middle */
.ui-kind i { padding-block: calc(3px + (1lh - 1cap) / 2); }
.ui-head { display: flex; flex-direction: column; gap: 6px; }
.ui-name { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; min-height: var(--ui-tap); text-align: left; font: 650 23px/1.15 var(--ui-font); letter-spacing: -0.03em; color: var(--ui-ink); }
.ui-name svg { width: 18px; height: 18px; color: var(--ui-ink-3); }
/* two names and their ampersand sit on one baseline, and wrap as whole names */
.ui-names { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.28em; font: 650 23px/1.15 var(--ui-font); letter-spacing: -0.03em; }
.ui-names .amp { font-weight: 300; color: var(--ui-ink-3); }
.ui-names .ui-name { align-self: baseline; }
/* the top line of a head: what it is on the left, where it stands on the right */
.ui-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.ui-state { flex: none; font: 600 13px var(--ui-font); color: var(--ui-ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* an end that is close: the package's own colour, and it hops by how close it is (UI.hop; RN1373) */
.ui-state .soon { display: inline-block; font-weight: 650; color: rgb(var(--c-rgb, 200, 208, 220)); }
/* where it stands has no room beside what it is: it takes the row under it, whole (RN642) */
.ui-top.long { display: grid; grid-template-columns: minmax(0, auto) auto minmax(0, 1fr); row-gap: 7px; }
.ui-top.long > .ui-state { grid-column: 1 / -1; justify-self: start; white-space: normal; overflow-wrap: anywhere; line-height: 1.3; }
/* one line of symbol, value, symbol, choices */
.ui-inline { display: flex; align-items: center; gap: 7px; min-width: 0; }
.ui-inline > .ui-lab:not(:first-child) { margin-left: 7px; }
/* two rows of pills stacked one under the other keep the kit's 8px between them, so no pill rests on the row above (RN1368 scan) */
.ui-inline:has(.ui-chip, .ui-vpill) + .ui-inline:has(.ui-chip, .ui-vpill) { margin-top: 8px; }

/* ── rows: a row is expensive, so several things share one ────────────── */
.ui-rows { display: flex; flex-direction: column; border-top: 1px solid var(--ui-line); }
.ui-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 52px; padding: 4px 2px; border-bottom: 1px solid var(--ui-line); font: 500 14px var(--ui-font); color: var(--ui-ink-2); }
.ui-row > b, .ui-row .v { font-weight: 650; color: var(--ui-ink); font-variant-numeric: tabular-nums; }
.ui-row .side { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; text-align: right; }
/* A hidden row leaves the list's count and layout with it. */
.ui-list > [hidden], .ui-rows > [hidden] { display: none; }
/* A session's date and time are one fact. Its metadata shares the row only when both fit. */
.ui-session-row { flex-wrap: wrap; }
.ui-session-row > b { flex: none; white-space: nowrap; }
.ui-session-row .side { margin-left: 0; text-align: left; }
.ui-row .gold { color: var(--ui-gold); font-weight: 600; }
.ui-lab { display: inline-flex; align-items: center; gap: 7px; color: var(--ui-ink-3); font: 600 13px var(--ui-font); white-space: nowrap; }
.ui-lab svg { width: 19px; height: 19px; color: var(--ui-ink-2); }
/* a label that may run to a second line (an address) */
.ui-lab.long { white-space: normal; align-items: flex-start; line-height: 1.35; padding: 6px 0; }
.ui-lab.long svg { flex: none; }
.ui-pair { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; }
.ui-pair > span { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.ui-pair.tight { flex-wrap: nowrap; justify-content: space-between; gap: 8px; }
.ui-pair.tight > span { gap: 6px; }
.ui-pair.tight .ui-lab { font-size: 12.5px; gap: 5px; }
.ui-pair.tight .ui-vpill { padding: 0 8px 0 12px; min-width: 0; }
/* A trimmed word's box is only as tall as its capitals (RN1390), so whatever cuts a long word short cuts it sideways
   only (overflow: clip visible): accents above (Ứng, Võ) and the letters that hang below (Ngọc, giày) stand whole */
.ui-vpill > span { overflow: clip visible; text-overflow: ellipsis; }
/* the words give way inside the pill, never past its side room; a name there carries the name she goes by and takes it
   instead of being cut (UI.fitNames, RN652) (walkfix45, walkfix47) */
.ui-vpill > span { min-width: 0; }
/* a value pill never runs past the surface it stands on: a long value gives way inside it */
.ui-vpill { max-width: 100%; }
/* on the narrowest phones a pair takes the tight measures, so two values still share their row */
@media (max-width: 374px) { .ui-pair { column-gap: 8px; } .ui-pair .ui-vpill { gap: 4px; padding: 0 8px 0 12px; font-size: 13.5px; } }

/* ── value pill: anything you can change is a pill with a chevron ───────
   Three kinds of thing can stand in a row, and each has one look, so a pill and what it opens never look alike (RN553):
   a value pill opens something: glass with a hairline edge, its symbol and a chevron. Open, its edge takes the class colour.
   a chip is one of the studio's own things to choose (a class type, a package, a person, a reason): glass with no edge.
   a track holds the fixed options of a setting (night or day, days weeks months): one well, bare words, a lens.
   Only the chosen one is ever filled with the class colour. ── */
.ui-vpill { display: inline-flex; align-items: center; gap: 5px; min-height: var(--ui-tap); padding: 0 10px 0 14px; border-radius: 999px; font: 650 14px var(--ui-font); color: var(--ui-ink); white-space: nowrap;
  background: var(--ui-glass); box-shadow: inset 0 0 0 1px var(--ui-edge); transition: background-color 180ms, box-shadow 180ms, transform 160ms var(--ui-ease); font-variant-numeric: tabular-nums; }
.ui-vpill:active { transform: scale(0.96); }
.ui-vpill .chev { width: 16px; height: 16px; color: var(--ui-ink-3); transition: transform 260ms var(--ui-ease); }
.ui-vpill[aria-expanded="true"] { background: rgba(var(--c-rgb), 0.1); box-shadow: inset 0 0 0 1.5px rgba(var(--c-rgb), 0.9); }
.ui-vpill[aria-expanded="true"] .chev { transform: rotate(180deg); color: var(--ui-ink); }
.ui-vpill.empty { color: var(--ui-ink-3); font-weight: 600; }
.ui-vpill.warn { color: var(--ui-warn); }
/* What needs her (RN1383): a badge saying something needs her, and the very thing it means, share the one colour the
   app calls her with, so her eye goes straight from one to the other. The badge is that colour's glass; the thing
   it means is written in it, its sign too. */
/* the package card's paint on every class-coloured fill (RN1383): the card's fall of light, a lit top and a deeper
   foot, laid over the fill the piece already has, so a bar, a chart, a chosen pill and a lens read as the card's
   own colour, never a flat fill. Blueberry, the system's own colour, keeps its plain levels */
/* (RN1399) the lit top is a touch of light, never a white haze over the colour: the fall runs top to foot as on CARE's indicator */
:root { --ui-gloss: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 48%), linear-gradient(180deg, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.16)); }
.ui-root :is(.ui-share-fill, .an-team-kind, .an-wk .stack > i, .c-bars i:not(.l), .ui-drawer[data-kind]:not([data-kind=""]) :is(.ui-chip, .ui-who, .lens)[aria-pressed="true"], .ui-drawer[data-kind]:not([data-kind=""]) .ui-seg .lens) { background-image: var(--ui-gloss); }
.ui-root .ui-attn { color: var(--ui-warn, #e8c27a); background-color: color-mix(in srgb, var(--ui-warn, #e8c27a) 15%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-warn, #e8c27a) 46%, transparent); }
.ui-root :is(.ui-attn-to, .ui-attn-to :is(svg, b, span, small)) { color: var(--ui-warn, #e8c27a); }
.ui-vpill > svg:not(.chev) { flex: none; width: 18px; height: 18px; margin: 0 2px 0 -2px; color: var(--ui-ink-2); }
.ui-vpill.icon-only { padding: 0; width: var(--ui-tap); justify-content: center; }
.ui-vpill.icon-only svg { width: 20px; height: 20px; }
/* A lone symbol has no label-side spacing, including app-level pill rules. */
.ui-vpill.icon-only > svg.ui-i:not(.chev) { margin: 0; }

/* ── chips: one of the studio's own things to choose ──────────────────── */
.ui-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* A row that scrolls sideways. It runs to the drawer's own edge, so a pill slides off the glass and never into a
   wall. A side fades only while more waits there. A flick settles on a pill's edge (RN448). */
.ui-chips.scroll { flex-wrap: nowrap; overflow-x: auto; margin: 0 -18px; padding: 0 18px; scrollbar-width: none; scroll-snap-type: x proximity; scroll-padding: 0 40px 0 18px; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
  /* the fade stands at the row's own edge and never moves while what is in the row grows or slides; when the row
     reaches its end it dissolves where it stands, and the last pill rests at the edge with no room left over (RN1392) */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr) - var(--ui-cut)), transparent calc(100% - var(--ui-cut))); mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr) - var(--ui-cut)), transparent calc(100% - var(--ui-cut)));
  transition: --ui-fl 280ms ease, --ui-fl0 280ms ease, --ui-fr 280ms ease; }
.ui-chips.scroll::-webkit-scrollbar { display: none; }
.ui-chips.scroll > * { scroll-snap-align: start; }
.ui-chips.scroll.more-l { --ui-fl: 36px; }
.ui-chips.scroll.more-r { --ui-fr: 36px; }
/* A body under a fixed head or foot fades on the body itself, and stays whole at rest. */
.ui-edge-y { --ui-cut: var(--ui-edge-cut); }
/* the edge fade masks only the top and foot: a sideways row's bleed past the sides still shows and fades by its own mask (RN1368 scan: rows cut hard at the page's side) */
.ui-edge-y.more-t, .ui-edge-y.more-b { -webkit-mask-clip: no-clip; mask-clip: no-clip; -webkit-mask-repeat: repeat-x; mask-repeat: repeat-x; }
.ui-edge-y.more-t { -webkit-mask-image: linear-gradient(to bottom, transparent var(--ui-edge-top, 0px), #000 calc(var(--ui-edge-top, 0px) + var(--ui-cut)), #000 100%); mask-image: linear-gradient(to bottom, transparent var(--ui-edge-top, 0px), #000 calc(var(--ui-edge-top, 0px) + var(--ui-cut)), #000 100%); }
.ui-edge-y.more-b { -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 calc(var(--ui-edge-bottom, 100%) - var(--ui-cut)), transparent var(--ui-edge-bottom, 100%), transparent 100%); mask-image: linear-gradient(to bottom, #000 0, #000 calc(var(--ui-edge-bottom, 100%) - var(--ui-cut)), transparent var(--ui-edge-bottom, 100%), transparent 100%); }
.ui-edge-y.more-t.more-b { -webkit-mask-image: linear-gradient(to bottom, transparent var(--ui-edge-top, 0px), #000 calc(var(--ui-edge-top, 0px) + var(--ui-cut)), #000 100%), linear-gradient(to bottom, #000 0, #000 calc(var(--ui-edge-bottom, 100%) - var(--ui-cut)), transparent var(--ui-edge-bottom, 100%), transparent 100%); -webkit-mask-composite: source-in; mask-image: linear-gradient(to bottom, transparent var(--ui-edge-top, 0px), #000 calc(var(--ui-edge-top, 0px) + var(--ui-cut)), #000 100%), linear-gradient(to bottom, #000 0, #000 calc(var(--ui-edge-bottom, 100%) - var(--ui-cut)), transparent var(--ui-edge-bottom, 100%), transparent 100%); mask-composite: intersect; }
/* the same row when it starts part-way along a line, after a symbol or a pill */
.ui-chips.scroll.inrow { flex: 1; min-width: 0; margin: 0 -18px 0 0; padding: 0 18px 0 0; scroll-padding: 0 40px 0 0; }
/* a row beside its label has no gutter to fade into: a pill scrolled left clears a band by the label first, so its words never run into the label's (RN1368 scan: "What's right" + "lse") */
.ui-chips.scroll.inrow.more-l { --ui-fl0: 10px; --ui-fl: 44px; }
/* and when it opens a line and stops before what stands at the right (RN493) */
.ui-chips.scroll.lead { flex: 1; min-width: 0; margin: -8px 0 -8px -18px; padding: 8px 2px 8px 18px; scroll-padding: 0 40px 0 18px; }
/* with nothing standing at its right, it runs to the drawer's edge like any other row, and its fade is that edge */
.ui-chips.scroll.lead:last-child { margin-right: -18px; padding-right: 18px; }
/* a person as a pill: the one in hand is lit; done widens to the right and a check is drawn in; off is absent */
.ui-who { flex: none; display: inline-flex; align-items: center; min-height: var(--ui-tap); padding: 0 16px; border-radius: 999px; font: 650 16px var(--ui-font); letter-spacing: -0.015em; color: var(--ui-ink-2); white-space: nowrap; background: var(--ui-glass);
  transition: background-color 280ms ease, color 280ms ease, transform 160ms var(--ui-ease); }
.ui-who:active { transform: scale(0.96); }
.ui-who[disabled] { pointer-events: none; }
.ui-who[aria-pressed="true"] { color: var(--ui-ink); background: rgba(var(--c-rgb), var(--ui-on-a)); }
.ui-who .ui-who-tick { flex: none; display: inline-grid; place-items: center; width: 0; margin-left: 0; overflow: hidden; color: var(--ui-ink); transition: width 460ms var(--ui-ease), margin-left 460ms var(--ui-ease); }
.ui-who .ui-who-tick svg { flex: none; width: 18px; height: 18px; stroke-width: 2.3; }
.ui-who .ui-who-tick path { stroke-dasharray: 21; stroke-dashoffset: 21; }
.ui-who.done .ui-who-tick { width: 18px; margin-left: 8px; }
.ui-who.done .ui-who-tick path { stroke-dashoffset: 0; transition: stroke-dashoffset 440ms cubic-bezier(0.6, 0, 0.2, 1) 280ms; }
/* signed: as the pill widens and its check is drawn it lights from inside in the class colour, then keeps a little
   of that light. The light stays inside the pill, so the row it scrolls in never cuts it (RN514). */
.ui-who { position: relative; isolation: isolate; }
.ui-who::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 400ms ease;
  background: radial-gradient(120% 150% at 50% 50%, rgba(var(--c-rgb), 0.52), rgba(var(--c-rgb), 0.2) 72%);
  box-shadow: inset 0 0 0 1px rgba(var(--c-rgb), 0.95), inset 0 0 14px rgba(var(--c-rgb), 0.35); }
.ui-who.done { color: var(--ui-ink); }
.ui-who.done::before { opacity: 0.34; }
.ui-who.done.just::before { animation: ui-who-lit 1300ms ease-out 120ms both; }
@keyframes ui-who-lit { 0% { opacity: 0; } 34% { opacity: 1; } 100% { opacity: 0.34; } }
.ui-who .ui-who-off { flex: none; max-width: 0; margin-left: 0; overflow: hidden; opacity: 0; font: 650 10px var(--ui-font); font-style: normal; letter-spacing: 0.11em; text-transform: uppercase; color: var(--ui-ink-3); transition: max-width var(--ui-t) var(--ui-ease), margin-left var(--ui-t) var(--ui-ease), opacity 300ms ease; }
.ui-who.off > span { color: var(--ui-ink-3); }
.ui-who.off .ui-who-off { max-width: 64px; margin-left: 8px; opacity: 1; }
/* A word stands at its pill's true middle (RN1390: "a little bit lower than they should be"): its box is trimmed to its
   capitals and its baseline, so the pill centres what the eye reads, by each phone's own font, never a nudge for one */
.ui-chip, :is(.ui-chip, .ui-seg button, .ui-vpill, .ui-who, .ui-glass, .ui-go) > :is(span, b):not(.ui-sr), .ui-kind > :is(.nm, i), .ui-share.ui-li > :is(.ui-share-name, .ui-share-count) { text-box: trim-both cap alphabetic; }
.ui-chip { flex: none; min-height: var(--ui-tap); padding: 0 15px; border-radius: 999px; font: 650 14px var(--ui-font); color: var(--ui-ink-2); white-space: nowrap; background: var(--ui-glass); transition: background-color 180ms, color 180ms, transform 160ms var(--ui-ease); }
.ui-chip:active { transform: scale(0.96); }
.ui-chip[aria-pressed="true"] { color: var(--ui-ink); background: rgba(var(--c-rgb), var(--ui-on-a)); }
.ui-chip small { display: block; font: 500 11px var(--ui-font-num); color: var(--ui-ink-3); margin-top: 2px; }
/* on a filled pill the small line is the pill's own ink a step quieter, as grey ink read as a faint tint on the colour (27 Oct) */
:is(.ui-chip, .ui-who)[aria-pressed="true"] small, .ui-chip.chosen small { color: inherit; opacity: 0.82; }
/* a person or thing with one fact under its name: its symbol, then the name over the quiet line, read from the left, one build in both apps (RN1264) */
/* a pill whose symbol stands in a label before its words sets both on one middle, as the two-line pill does: the label alone
   sat on the words' baseline and drew its symbol 4 px high (27 Oct: the room pills' door) */
.ui-chip:has(> .ui-lab) { display: inline-flex; align-items: center; justify-content: center; }
.ui-chip:has(> svg + span > small) { display: inline-flex; align-items: center; gap: 8px; padding: 0 18px 0 15px; text-align: left; color: var(--ui-ink); }
.ui-chip:has(> svg + span > small) > svg { flex: none; width: 17px; height: 17px; margin: 0; color: var(--ui-ink-2); }
.ui-chip > svg + span:has(> small) { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.ui-chip.day { width: 40px; min-height: 40px; padding: 0; text-align: center; font-size: 13px; }

/* ── track: the fixed options of a setting, one chosen (RN553) ───────────
   One well with bare words in it and a flat lens under the chosen one. The lens slides to the next choice. It holds
   the options themselves, so it never looks like the pill that opened it. Not for a studio's own list: that is chips. */
.ui-seg { position: relative; isolation: isolate; overflow: hidden; flex: none; display: inline-flex; align-items: stretch; max-width: 100%; height: var(--ui-tap); padding: 3px; border-radius: 999px; background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); }
.ui-seg button { position: relative; flex: 1 1 auto; min-width: 0; padding: 0 15px; border-radius: 999px; font: 650 14px var(--ui-font); color: var(--ui-ink-2); white-space: nowrap; transition: color 220ms ease, transform 160ms var(--ui-ease); }
/* the word is 38 tall inside its well; the finger gets the full 44 */
.ui-seg button::after { content: ""; position: absolute; inset: -3px 0; }
/* an option may carry its symbol before its word, or be a symbol alone; a small track sits inside a pill (RN593) */
.ui-seg button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.ui-seg button svg { flex: none; width: 16px; height: 16px; }
.ui-seg.mini { height: 32px; padding: 2px; }
.ui-seg.mini button { padding: 0 9px; }
.ui-seg.mini button::after { inset: -8px 0; }
.ui-seg.mini .lens { top: 2px; bottom: 2px; }
.ui-seg button:active { transform: scale(0.96); }
.ui-seg button[aria-pressed="true"] { color: var(--ui-ink); }
.ui-seg .lens { position: absolute; z-index: -1; left: 0; top: 3px; bottom: 3px; width: 0; border-radius: 999px; background: rgba(var(--c-rgb), var(--ui-on-a)); opacity: 0; pointer-events: none; }
/* until the lens has been measured to its word, the word carries the fill itself, so nothing is ever unlit */
.ui-seg:not(.fit) button[aria-pressed="true"] { background: rgba(var(--c-rgb), var(--ui-on-a)); }
/* the lens moves by UI.lensGo as one piece, never past the track's end (RN1399). It is a solid piece with a little depth,
   as the indicator in CARE's booking form: a lit top edge, a deeper foot and a soft shadow under it */
.ui-seg.fit .lens { opacity: 1; transform-origin: 50% 50%; }
.ui-seg .lens { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), inset 0 -4px 8px -5px rgba(0, 0, 0, 0.3), 0 3px 10px rgba(0, 0, 0, 0.3); }
/* Two levels of a chosen thing (RN1265). Level one is where she is: a track's lens, filled as solidly as he set
   (Glass to solid, --ui-on-a). Level two is a choice made inside it (the people, packages, days or a second track under
   a chosen tab): the same colour as tinted glass, never ringed (a ring means it opens), so the parent stays the strongest
   thing in view. How strong it is: --ui-on-2, his hand control Choice inside a choice. */
:root { --ui-on-2: var(--tune-onsub, 0.5); --ui-on-3: var(--tune-onsub3, 0.4); }
/* Level two is marked by the kit (UI.levels, data-lv="2") wherever a choice stands inside another chosen thing. */
:is(.ui-chip, .ui-who, .ui-vpill.plain, .look-sym, .cal-d)[data-lv="2"][aria-pressed="true"] {
  background: rgba(var(--c-rgb), calc(var(--ui-on-a) * var(--ui-on-2))); box-shadow: none; color: var(--ui-ink);
}
.ui-seg[data-lv="2"] .lens { background: rgba(var(--c-rgb), calc(var(--ui-on-a) * var(--ui-on-2))); box-shadow: none; }
/* Level three is what is chosen inside a level two (Payroll, then Pay, then October and Ava): the same colour, deeper
   still (RN1388, RN1389); how much deeper is his hand control Choice inside that, --ui-on-3 */
:is(.ui-chip, .ui-who, .ui-vpill.plain, .look-sym, .cal-d)[data-lv="3"][aria-pressed="true"] {
  background: rgba(var(--c-rgb), calc(var(--ui-on-a) * var(--ui-on-2) * var(--ui-on-3))); box-shadow: none; color: var(--ui-ink);
}
.ui-seg[data-lv="3"] .lens { background: rgba(var(--c-rgb), calc(var(--ui-on-a) * var(--ui-on-2) * var(--ui-on-3))); box-shadow: none; }
/* a track that fills its row shares the row evenly */
.ui-seg.wide { display: flex; flex: 1 1 auto; }
/* a record of what someone said or did (RN1395): her letter in a ring, the line in the record's own small type */
.ui-rec { display: flex; align-items: flex-start; gap: 8px; margin: 0; color: var(--ui-ink-3); }
.ui-rec-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-rec-line { font: 550 12px/18px var(--ui-font); letter-spacing: 0.01em; font-variant-numeric: tabular-nums; color: var(--ui-ink-3); }
.ui-rec-sub { font: 500 13px/1.4 var(--ui-font); color: var(--ui-ink-2); }
.ui-rec-who { flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1px currentColor; color: var(--ui-ink-2); font: 650 9.5px/1 var(--ui-font); font-style: normal; letter-spacing: 0; }
.ui-rec-who.by-app { box-shadow: none; background: currentColor; transform: scale(0.34); opacity: 0.7; }
.ui-rec + .ui-rec { margin-top: 10px; }
.ui-rec-text { flex: 1 1 auto; }
.ui-rec > .ui-state { margin-left: auto; line-height: 18px; }
.ui-rec > .ui-text-act { flex: none; margin: calc(9px - var(--ui-tap) / 2) 0 calc(9px - var(--ui-tap) / 2) auto; }
.ui-rec-ink { display: block; width: 200px; max-width: 100%; height: 64px; margin-top: 2px; background: var(--ui-ink-2); -webkit-mask: left center / contain no-repeat; mask: left center / contain no-repeat; }
.ui-seg.wide button { flex: 1 1 0; padding: 0 8px; }
/* a track and what ends its row (the calendar's pill) */
/* a track with more words than its row holds: its words stand closer first (--ui-seg-pad, set by the kit), then run
   sideways under the well, and the track fades at the edge it goes on past, as every sideways row does */
/* a running track hugs its choices; standing alone it never stretches to an empty tail (RN1368 scan: My pay · My teaching) */
.ui-seg.run { flex: 0 1 auto; width: max-content; max-width: 100%; min-width: 0; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%); mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%);
  transition: --ui-fl0 280ms ease, --ui-fl 280ms ease, --ui-fr 280ms ease; }
.ui-seg.run::-webkit-scrollbar { display: none; }
.ui-seg.run button { flex: none; padding: 0 var(--ui-seg-pad, 15px); }
/* crowded, its words step down one size before the room around them gets tight (set by the kit) */
.ui-seg.run.close button { font-size: 13px; }
.ui-seg.run.more-l { --ui-fl: 36px; }
.ui-seg.run.more-r { --ui-fr: 36px; }
.ui-segrow { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* The wheel (RN580): a number, or one of a few words, set by a flick. The values stand on a drum that turns under a
   fixed lens, in one well; the values above and below fade into the well, which is all that says "there is more".
   The track's sibling: there the lens goes to the word, here the values come to the lens. Flat like the track: no
   shading on the drum, no bevel. As it appears, each drum settles the last part of a turn, so it is seen to turn. */
.ui-wheel { --wi: 34px; --wh: 98px; --seam: 44.5%; position: relative; isolation: isolate; display: grid; grid-template-columns: minmax(0, var(--seam)) minmax(0, 1fr); min-width: 0; height: var(--wh); padding: 0 6px; border-radius: 24px; overflow: hidden;
  background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); }
.ui-wheel .lens { position: absolute; z-index: -1; left: 5px; right: 5px; top: 50%; height: calc(var(--wi) + 6px); margin-top: calc(var(--wi) / -2 - 3px); border-radius: 999px; background: rgba(var(--c-rgb), var(--ui-on-a)); pointer-events: none; }
/* a drum is as wide as its half of the well, so a flick may start anywhere on it; a wheel with one drum gives it the whole well, and its word stands over it without taking the touch */
.ui-wheel .drum { grid-row: 1; min-width: 0; height: 100%; overflow-y: scroll; overscroll-behavior: contain; scroll-snap-type: y mandatory; scrollbar-width: none; touch-action: pan-y; cursor: grab; outline: none;
  -webkit-mask-image: linear-gradient(transparent 3%, #000 37%, #000 63%, transparent 97%); mask-image: linear-gradient(transparent 3%, #000 37%, #000 63%, transparent 97%); }
.ui-wheel .drum::-webkit-scrollbar { display: none; }
.ui-wheel .drum.drag { scroll-snap-type: none; cursor: grabbing; }
.ui-wheel.one .drum { grid-column: 1 / -1; }
/* while a drum settles in, it holds no detent: a value moved by the settling must not be taken for the chosen one */
.ui-wheel .drum.in { scroll-snap-type: none; }
.ui-wheel .strip { padding: calc((var(--wh) - var(--wi)) / 2) 0; }
.ui-wheel .drum.in .strip { animation: ui-wheel-in var(--ui-t-spring) var(--ui-spring) both; }
.ui-wheel .drum.in.words .strip, .ui-wheel + .ui-wheel .drum.in .strip { animation-delay: 70ms; }
.ui-wheel + .ui-wheel .drum.in.words .strip { animation-delay: 140ms; }
.ui-wheel .drum.words .strip { --ui-turn: -0.85; }
@keyframes ui-wheel-in { from { transform: translateY(calc(var(--wi) * var(--ui-turn, 0.85))); } }
/* the value under the lens is whole; the ones beside it are smaller and fade into the well */
.ui-wheel .strip > span { display: block; height: var(--wi); padding: 0 5px 0 0; font: 400 23px/34px var(--ui-font-num); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; scroll-snap-align: center; color: var(--ui-ink-2);
  transform: scale(0.8); transform-origin: calc(100% - 5px) 50%; transition: color 180ms ease, transform 220ms var(--ui-ease); }
.ui-wheel.one .strip > span { padding-right: calc(100% - var(--seam) + 5px); transform-origin: calc(var(--seam) - 5px) 50%; }
.ui-wheel .strip > span[hidden] { display: none; }
.ui-wheel .strip > span[aria-selected="true"] { color: var(--ui-ink); transform: none; }
.ui-wheel .drum.words .strip > span, .ui-wheel .word { font: 600 14px/34px var(--ui-font); letter-spacing: 0; text-align: left; padding: 0 0 0 5px; }
.ui-wheel .drum.words .strip > span { transform-origin: 5px 50%; }
/* a wheel of one drum with no word beside it centres its values in the lens (RN1368 scan: the bonus starting client stood left of the lens) */
.ui-wheel.one:not(:has(.word)) .strip > span { padding: 0; text-align: center; transform-origin: 50% 50%; }
.ui-wheel .word { grid-column: 2; grid-row: 1; align-self: center; color: var(--ui-ink); white-space: nowrap; pointer-events: none; }
/* twins: two drums of one kind and the word between them, each centred in its half */
.ui-wheel.twin { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); padding: 0 10px; }
.ui-wheel.twin .drum:last-child { grid-column: 3; }
.ui-wheel.twin .word { padding: 0 6px; color: var(--ui-ink-2); }
.ui-wheel.twin .strip > span { padding: 0; font-size: 21px; text-align: center; transform-origin: 50% 50%; }
.ui-wheel .drum:focus-visible { box-shadow: inset 0 0 0 2px rgba(var(--c-rgb), 0.7); border-radius: 18px; }
/* On or off (RN580): a small well with a lens that crosses it, named by what it turns on. */
.ui-onoff { flex: none; display: inline-flex; align-items: center; gap: 9px; min-height: var(--ui-tap); padding: 0 2px; font: 650 12.5px var(--ui-font); color: var(--ui-ink-2); white-space: nowrap; transition: color 200ms ease; }
.ui-onoff > i { position: relative; flex: none; width: 38px; height: 22px; border-radius: 999px; background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); transition: background-color 300ms ease; }
/* the knob crosses as one piece, as the toggle in CARE's booking form does: it leaves quickly and lands softly, and it
   never spreads out on the way (RN1399, which takes back the drop of glass of RN1372) */
.ui-onoff > i::after { content: ""; position: absolute; left: 3px; right: 19px; top: 3px; height: 16px; border-radius: 999px; background: var(--ui-ink-3);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); transition: left 320ms cubic-bezier(0.3, 1, 0.4, 1), right 320ms cubic-bezier(0.3, 1, 0.4, 1), background-color 300ms ease; }
.ui-onoff[aria-checked="true"] { color: var(--ui-ink); }
.ui-onoff[aria-checked="true"] > i { background: rgba(var(--c-rgb), calc(var(--ui-on-a) + 0.3)); }
.ui-onoff[aria-checked="true"] > i::after { left: 19px; right: 3px; background: #fff;
}
/* set where it was, without moving, before it travels to where it is now (UI's switches()) */
.ui-onoff.ui-set > i, .ui-onoff.ui-set > i::after { transition: none !important; }

/* ── colour swatch: a colour to choose, drawn with the shades the app computes from it ── */
.ui-tint { flex: none; display: inline-block; width: 16px; height: 16px; border-radius: 50%; background: var(--t); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22); }
.ui-vpill .ui-tint { margin: 0 3px 0 -3px; }
.ui-tints { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; max-width: 364px; margin: 0 auto; padding: 6px 4px; }
.ui-tint.pick { position: relative; display: grid; place-items: center; width: var(--ui-tap); height: var(--ui-tap); color: var(--t-ink); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  outline: 2px solid transparent; outline-offset: 3px; transition: outline-color 220ms ease, transform 160ms var(--ui-ease); }
.ui-tint.pick:active { transform: scale(0.94); }
.ui-tint.pick[aria-pressed="true"], .ui-tint.pick.on { outline-color: var(--t); }
/* a board of colours of one family: three rows of three, each a full chip of its colour (RN625). The one this thing
   has is ringed; one that another thing already has is dim, carries a check, and cannot be taken again */
.ui-tints.rows { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 6px 5px; }
.ui-tints.rows .ui-tint.pick { width: 100%; border-radius: 999px; }
.ui-tint.pick.used { opacity: 0.36; cursor: default; }
.ui-tint.pick.used:active { transform: none; }
.ui-tint.pick.used svg { width: 19px; height: 19px; stroke-width: 2.2; }
.ui-tint.own:not(.on) { color: var(--ui-ink-2); background: var(--ui-glass); box-shadow: inset 0 0 0 1px var(--ui-edge); }
.ui-tint.own svg { width: 20px; height: 20px; pointer-events: none; }
/* the way to her own colour is open: the circle reads like an open pill until it holds a colour of its own */
.ui-tint.own[aria-expanded="true"]:not(.on) { color: var(--ui-ink); background: rgba(var(--c-rgb), 0.1); box-shadow: inset 0 0 0 1.5px rgba(var(--c-rgb), 0.9); }

/* ── palette: a colour of her own, in place. A field of the colours the app can paint; the knob is the colour ── */
.ui-palette { position: relative; height: 136px; border-radius: 22px; overflow: hidden; touch-action: none; outline: none; cursor: pointer;
  background: var(--ui-well); }
.ui-palette canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* the field is flat like the rest: an even hairline round it */
.ui-palette::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.24); }
.ui-palette .knob { position: absolute; z-index: 1; left: calc(20px + (100% - 40px) * var(--x, 0.5)); top: calc(20px + (100% - 40px) * var(--y, 0)); width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; pointer-events: none;
  background: var(--t); box-shadow: 0 0 0 2.5px #fff, 0 4px 12px -4px rgba(0, 0, 0, 0.5); transition: transform 160ms var(--ui-ease); }
.ui-palette.held .knob { transform: scale(1.2); }
.ui-palette:focus-visible { box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.7); }

/* ── section: what is optional stays folded ───────────────────────────── */
.ui-secs { display: flex; flex-direction: column; border-top: 1px solid var(--ui-line); }
/* rows directly above sections are one run of rows: one line between them, and no gap (the body's gap is 14px) */
.ui-rows + .ui-secs, .ui-row:not([hidden]) + .ui-secs { border-top: 0; margin-top: -14px; }
.ui-sec { border-bottom: 1px solid var(--ui-line); }
.ui-body > .ui-sec, .ui-swap > .ui-sec { border-top: 1px solid var(--ui-line); }
/* sections and rows that follow each other are one run of rows: one line between two, never two lines with the body's gap between them */
.ui-body > :is(.ui-sec, .ui-rows):not([hidden]) + :is(.ui-sec, .ui-rows), .ui-swap > :is(.ui-sec, .ui-rows):not([hidden]) + :is(.ui-sec, .ui-rows) { border-top: 0; margin-top: -14px; }
/* a lone row beside a run of sections joins the run the same way: one line, no band (the trial row over Notes) */
.ui-body > .ui-row:not([hidden]) + :is(.ui-sec, .ui-rows), .ui-swap > .ui-row:not([hidden]) + :is(.ui-sec, .ui-rows) { border-top: 0; margin-top: -14px; }
.ui-body > :is(.ui-sec, .ui-rows):not([hidden]) + .ui-row, .ui-swap > :is(.ui-sec, .ui-rows):not([hidden]) + .ui-row { margin-top: -14px; }
.ui-sec > button { width: 100%; min-height: 52px; display: flex; align-items: center; gap: 8px; padding: 0 2px; text-align: left; font: 650 14px var(--ui-font); color: var(--ui-ink-2); white-space: nowrap; }
/* the title keeps its one line; a long summary gives way to it */
.ui-sec > button .sum { margin-left: auto; min-width: 0; font: 500 13px var(--ui-font); color: var(--ui-ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60%; font-variant-numeric: tabular-nums; }
.ui-sec > button .chev { flex: none; width: 18px; height: 18px; color: var(--ui-ink-3); transition: transform 280ms var(--ui-ease); }
.ui-sec > button .chev { margin-left: auto; }
.ui-sec > button .sum + .chev { margin-left: 2px; }
.ui-sec > .fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 440ms var(--ui-ease); }
/* the fold cuts what it holds while it opens; it is cut a little wider than its rows, so the ring that marks where a search landed has room at their sides */
/* a fold holds its content with the sideways row's full bleed, so a row inside one fades at the edge instead of being cut 10px short of its fade (RN1368 scan) */
.ui-sec > .fold > div { min-height: 0; overflow: hidden; margin: 0 -18px; padding: 0 18px; opacity: 0; filter: blur(10px); transition: opacity 260ms ease, filter 260ms ease; display: flex; flex-direction: column; gap: 10px; }
.ui-sec.open > button { color: var(--ui-ink); }
.ui-sec > button .sum { transition: opacity 220ms ease; }
.ui-sec.open > button .sum { opacity: 0; }
.ui-sec.open > button .chev { transform: rotate(180deg); }
.ui-sec.open > .fold { grid-template-rows: 1fr; }
.ui-sec.open > .fold > div { opacity: 1; filter: none; padding: 2px 18px 14px; }
/* a section inside a section: one quiet row; an act of the outer section may share it at the far end */
.ui-sec.sub { display: grid; grid-template-columns: 1fr auto; align-items: center; border: 0; }
.ui-sec.sub > button { width: auto; justify-self: start; min-height: var(--ui-tap); gap: 6px; padding-right: 10px; font-weight: 600; font-size: 13.5px; color: var(--ui-ink-3); }
.ui-sec.sub.open > button { color: var(--ui-ink-2); }
.ui-sec.sub > button .sum { margin-left: 0; max-width: none; }
.ui-sec.sub.open > button .sum { opacity: 1; }
.ui-sec.sub > button .chev, .ui-sec.sub > button .sum + .chev { margin-left: 0; width: 16px; height: 16px; }
.ui-sec.sub > .fold { grid-column: 1 / -1; }
.ui-sec.sub.open > .fold > div { padding: 0 18px; }

/* ── pick: a value from a list. Its pill opens the list in place, with the fold and blur of a section; the list
   sits in a well under its row, so it reads as the pill's own and not as another card (RN496) ── */
.ui-picks { display: flex; flex-direction: column; }
.ui-pick { border-bottom: 1px solid var(--ui-line); transition: border-color 300ms ease; }
/* open, the well itself closes the row; a rule hugging its foot would be one line too many */
.ui-pick.open { border-bottom-color: transparent; }
/* brought into view, an open piece stops short of the foot instead of tucking its last edge under it */
.ui-pick, .ui-sec { scroll-margin-bottom: 18px; }
.ui-pick > .ui-row { border-bottom: 0; }
.ui-pick .ui-row .side { min-width: 0; max-width: 68%; }
.ui-pick .ui-vpill { min-width: 0; max-width: 100%; }
.ui-pick > .fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 440ms var(--ui-ease); }
.ui-pick > .fold > div { min-height: 0; overflow: hidden; opacity: 0; filter: blur(10px); transition: opacity 260ms ease, filter 260ms ease; }
.ui-pick.open > .fold { grid-template-rows: 1fr; }
.ui-pick.open > .fold > div { opacity: 1; filter: none; }
.ui-pick .well { margin: 0 0 12px; border-radius: 18px; overflow: hidden; background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); }
.ui-pick .well .ui-input { min-height: 48px; border-radius: 0; background: transparent; box-shadow: none; border-bottom: 1px solid var(--ui-line); font-size: 15px; -webkit-appearance: none; appearance: none; }
.ui-pick .well .ui-input::-webkit-search-cancel-button { display: none; }
.ui-pick .well .ui-input:focus { box-shadow: none; border-bottom-color: rgba(255, 255, 255, 0.28); }
.ui-pick .ui-list { position: relative; padding: 0 16px; }
/* half a row shows under the fade, so it is plain that the list goes on */
.ui-pick .ui-list.scroll { max-height: 262px; }
.ui-pick .ui-li { min-height: 46px; font: 600 14.5px var(--ui-font); color: var(--ui-ink-2); transition: color 180ms; }
.ui-pick .ui-li[aria-pressed="true"] { color: var(--ui-ink); }
.ui-pick .ui-li .end svg { width: 18px; height: 18px; stroke-width: 2.2; color: var(--ui-ink); opacity: 0; transform: scale(0.6); transition: opacity 200ms ease, transform 260ms var(--ui-ease); }
.ui-pick .ui-li[aria-pressed="true"] .end svg { opacity: 1; transform: none; }
.ui-pick .ui-li.add { gap: 10px; color: var(--ui-ink-2); }
.ui-pick .ui-li.add svg { flex: none; width: 18px; height: 18px; color: var(--ui-ink); }
/* a choice may carry its own symbol before its word (p.icon) */
.ui-pick .ui-li .ic { display: inline-flex; align-items: center; gap: 12px; }
/* a country's or a language's flag, round and flat (RN607, RN553); one the list does not know is an empty ring */
.ui-flag { position: relative; flex: none; display: inline-block; width: 20px; height: 20px; border-radius: 50%; overflow: hidden; }
.ui-flag svg, .ui-pick .ui-li .ic .ui-flag svg { display: block; width: 100%; height: 100%; }
.ui-flag::after { content: ""; position: absolute; inset: 0; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16); }
.ui-flag.blank::after { box-shadow: inset 0 0 0 1px var(--ui-line); }
.ui-vpill > .ui-flag { width: 18px; height: 18px; margin-left: -4px; }
.ui-vpill > .ui-flag.blank { display: none; }
.ui-pick .ui-li .ic svg { flex: none; width: 21px; height: 21px; color: var(--ui-ink-2); transition: color 180ms; }
.ui-pick .ui-li[aria-pressed="true"] .ic svg { color: var(--ui-ink); }
/* a choice that cannot hold yet says what it needs, under its row (RN575): the pill warns and the field it waits for is
   ringed; the line goes the moment it is met */
.ui-tip { margin: -6px 2px 12px; font: 600 12.5px var(--ui-font); color: var(--ui-warn, #e8c27a); }
.ui-tip:empty { display: none; }
.ui-input.need { box-shadow: inset 0 0 0 1px var(--ui-warn, #e8c27a); }
.ui-input.need:focus { box-shadow: inset 0 0 0 1px var(--ui-warn, #e8c27a), 0 0 0 4px rgba(232, 194, 122, 0.16); }

/* ── picker host: the content under a pill blurs out to its picker ────── */
.ui-swap { position: relative; display: flex; flex-direction: column; gap: 14px; }

/* ── list rows (history, a client's packages, a pick list) ────────────── */
.ui-list { display: flex; flex-direction: column; }
/* a row keeps the height of what it says: a list that scrolls never squeezes a tall row under its own words */
.ui-list > * { flex-shrink: 0; }
.ui-list.scroll { max-height: 216px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-lf, 26px)), transparent); mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-lf, 26px)), transparent); padding-bottom: 14px; }
.ui-list.scroll::-webkit-scrollbar { display: none; }
.ui-li { width: 100%; min-height: 48px; display: flex; align-items: center; gap: 10px; padding: 6px 2px; text-align: left; font: 500 13.5px var(--ui-font); color: var(--ui-ink-2); border-bottom: 1px solid var(--ui-line); }
.ui-li:last-child { border-bottom: 0; }
.ui-li b { font-weight: 650; color: var(--ui-ink); }
/* what a row says is hers to write: a word longer than the row breaks inside it, never runs off the edge (RN642) */
.ui-li > span:not([class]) { min-width: 0; overflow-wrap: anywhere; }
/* the symbol a row is known by stands first, in quiet ink (RN616) */
.ui-li > svg.ui-i:first-child { flex: none; width: 20px; height: 20px; color: var(--ui-ink-2); }
.ui-li .when { flex: none; width: 52px; font: 600 12.5px var(--ui-font-num); color: var(--ui-ink-3); }
.ui-li .end { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 6px; font: 650 13px var(--ui-font-num); color: var(--ui-ink-2); font-variant-numeric: tabular-nums; }
.ui-li .end svg { width: 17px; height: 17px; color: var(--ui-ink-3); }
/* a list whose rows end in a mark keeps the mark's place on every row, so the values stand in one column whether a row has
   its mark or not (28 Oct: a late cancel's −1 stood where a session put its pen) */
.ui-list:has(> .ui-li > .end > svg:last-child) > .ui-li > .end:not(:has(> svg:last-child))::after { content: ''; flex: none; width: 17px; height: 17px; }
.ui-li .dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: rgb(var(--k-rgb, var(--c-rgb))); }
/* facts split by a dot: a fact wraps whole, and no dot starts or ends a line */
/* The dot's room is measured once, in the row's own size, and every fact uses that same room, so a smaller
   second line is never trimmed by the clip that hides the dot at a line's start. */
@property --ui-dot { syntax: '<length>'; inherits: true; initial-value: 0px; }
.ui-facts { --ui-dot: 0.9em; display: flex; flex-wrap: wrap; align-items: baseline; row-gap: 1px; min-width: 0; margin-left: calc(-1 * var(--ui-dot)); clip-path: inset(0 0 0 var(--ui-dot)); }
.ui-facts > * { position: relative; max-width: 100%; padding-left: var(--ui-dot); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-facts > *::before { content: '\00b7'; position: absolute; left: 0; width: var(--ui-dot); text-align: center; font-weight: 500; color: var(--ui-ink-2); }
.ui-li.dim { opacity: 0.55; }
.ui-li .plus { color: var(--ui-ok); } .ui-li .minus { color: var(--ui-ink); }

/* ── action tiles: four in one row ────────────────────────────────────── */
.ui-tiles { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; }
/* An act on a thing (Extend, Transfer, Refund; Bring in, Take out): a round glass button, its symbol large, the word under
   it on the drawer's own ground. A box is earned only by what she presses, so the circle is the box and nothing sits
   in a tile inside the drawer (RN1263: "they should be just much bigger ... a card within a card"). */
/* a drawer's round acts are frosted glass, their words a step quieter than the drawer's own lines, so the row reads
   as a set of buttons and never as more white writing (RN1379) */
.ui-tile { --ui-tile-glass: rgba(255, 255, 255, 0.25); --ui-tile-edge: rgba(255, 255, 255, 0.16); min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 8px; padding: 0; text-align: center; font: 500 12.5px/1.2 var(--ui-font); letter-spacing: -0.005em; color: var(--ui-ink-2); background: transparent; box-shadow: none; }
:root[data-mode="day"] .ui-tile { --ui-tile-glass: rgba(255, 255, 255, 0.72); --ui-tile-edge: color-mix(in srgb, var(--ui-frost-ink) 9%, transparent); }
.ui-tile svg { box-sizing: border-box; flex: none; width: 56px; height: 56px; padding: 15px; border-radius: 50%; color: var(--ui-ink); background: var(--ui-tile-glass); box-shadow: inset 0 0 0 1px var(--ui-tile-edge); -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4); stroke-width: 1.6; transition: transform 160ms var(--ui-ease), background-color var(--ui-t) var(--ui-ease); }
.ui-tile:active svg { transform: scale(0.94); background: rgba(255, 255, 255, 0.34); }
.ui-tile[aria-pressed="true"] svg { color: #fff; background: rgb(var(--c-rgb, 74 124 220)); box-shadow: none; }
.ui-tile small { max-width: 100%; color: var(--ui-ink-3); font: 500 11.5px/1.25 var(--ui-font); text-wrap: balance; }
.ui-tile[disabled] { opacity: 0.3; pointer-events: none; }

/* ── fields ───────────────────────────────────────────────────────────── */
.ui-field { display: flex; flex-direction: column; gap: 8px; }
.ui-field > .top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.ui-field > .top:has(.ui-text-act) { align-items: center; }
.ui-field > .top > .ui-text-act { margin-block: calc((var(--ui-tap) - 1.2em) / -2); }  /* its tap room reaches over the label row, never pushes the field down (RN1360, RN1394) */
.ui-field > .top .note { font: 600 12.5px var(--ui-font-num); color: var(--ui-gold); font-variant-numeric: tabular-nums; }
.ui-field > .top .note.quiet { color: var(--ui-ink-2); }
.ui-field > .top .note.quiet { color: var(--ui-ink-2); }
.ui-input { width: 100%; min-width: 0; min-height: 52px; padding: 0 16px; border: 0; border-radius: 16px; outline: none; font: 600 16px var(--ui-font); color: var(--ui-ink); background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); transition: box-shadow 200ms; }
.ui-input::placeholder { color: var(--ui-ink-3); font-weight: 500; }
.ui-input:focus { box-shadow: inset 0 0 0 1px rgba(var(--c-rgb), 0.85), 0 0 0 4px rgba(var(--c-rgb), 0.16); }
.ui-input.money { font: 300 30px var(--ui-font-num); letter-spacing: -0.02em; min-height: 64px; font-variant-numeric: tabular-nums; }
.ui-money-pill { box-sizing: border-box; display: flex; flex: 1 1 0; align-items: center; gap: 8px; min-width: 0; min-height: 64px; padding: 0 12px; border-radius: 18px; background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); transition: box-shadow var(--ui-t) var(--ui-ease); }
.ui-money-pill:focus-within { box-shadow: inset 0 0 0 1px rgba(var(--c-rgb), 0.85), 0 0 0 4px rgba(var(--c-rgb), 0.16); }
.ui-money-pill > .ui-seg { flex: none; }
.ui-money-pill > .ui-input.money { flex: 1 1 0; width: 0; min-width: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.ui-money-pill > .ui-input.money:focus { box-shadow: none; }
textarea.ui-input { padding: 14px 16px; min-height: 84px; resize: none; font: 500 15px/1.45 var(--ui-font); }
/* a phone has no corner to drag: no field shows a resize grip (RN1368 scan) */
.ui-root textarea { resize: none; }
/* a sentence never leaves one word alone on its last line (RN1368 scan) */
.ui-root p { text-wrap: pretty; }
.ui-stepper { display: inline-flex; align-items: center; gap: 8px; }
.ui-stepper button { width: var(--ui-tap); height: var(--ui-tap); border-radius: 50%; display: grid; place-items: center; font: 400 22px var(--ui-font); color: var(--ui-ink); background: var(--ui-glass); box-shadow: inset 0 0 0 1px var(--ui-edge); transition: transform 160ms var(--ui-ease), background-color 160ms; }
.ui-stepper button svg { width: calc(var(--ui-tap) / 2); height: calc(var(--ui-tap) / 2); }
.ui-stepper button:active { transform: scale(0.92); background: rgba(255, 255, 255, 0.14); }
.ui-stepper output { min-width: 44px; text-align: center; font: 300 30px var(--ui-font-num); font-variant-numeric: tabular-nums; }
.ui-result { font: 500 14px var(--ui-font); color: var(--ui-ink-2); min-height: 22px; }
.ui-result b { color: var(--ui-ink); font-weight: 650; }
.ui-result .gold { color: var(--ui-gold); font-weight: 650; }
.ui-text-act { min-height: var(--ui-tap); padding: 0 4px; display: inline-flex; align-items: center; gap: 2px; font: 650 13.5px var(--ui-font); color: var(--ui-accent-ink, var(--ui-accent)); white-space: nowrap; }
.ui-text-act svg { width: 16px; height: 16px; }
.ui-text-act.danger { color: var(--ui-bad); }

/* ── calendar: the same one wherever a date is chosen ─────────────────── */
.ui-cal { display: flex; flex-direction: column; gap: 8px; padding: 12px 10px 10px; border-radius: 22px; background: var(--ui-well); box-shadow: inset 0 0 0 1px var(--ui-well-edge); }
.ui-cal-head { display: flex; align-items: center; justify-content: space-between; padding: 0 4px; }
.ui-cal-head b { font: 650 15px var(--ui-font); letter-spacing: -0.01em; }
.ui-cal-head button { width: var(--ui-tap); height: var(--ui-tap); border-radius: 999px; display: grid; place-items: center; color: var(--ui-ink-2); }
.ui-cal-head button svg { width: 18px; height: 18px; }
.ui-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); row-gap: 3px; }
.ui-cal-grid .wd { height: 22px; display: grid; place-items: center; font: 650 10px var(--ui-font); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ui-ink-3); }
.ui-cal-grid button { position: relative; height: var(--ui-tap); display: grid; place-items: center; font: 600 14px var(--ui-font-num); color: var(--ui-ink); font-variant-numeric: tabular-nums; }
.ui-cal-grid button[disabled] { color: var(--ui-ink-3); opacity: 0.45; pointer-events: none; }
.ui-cal-grid button.in[disabled] { color: var(--ui-ink-2); opacity: 0.9; }
.ui-cal-grid button::before { content: ""; position: absolute; inset: 3px 0; z-index: -1; transition: background-color 220ms ease; }
.ui-cal-grid button.in::before { background: rgba(var(--c-rgb), 0.34); }
.ui-cal-grid button.in.a::before { border-radius: 999px 0 0 999px; left: 3px; }
.ui-cal-grid button.in.z::before { border-radius: 0 999px 999px 0; right: 3px; }
.ui-cal-grid button.in.a.z::before { border-radius: 999px; }
.ui-cal-grid button.add::before { background: rgba(var(--ui-gold-rgb), 0.38); }
.ui-cal-grid button.add.z::before { border-radius: 0 999px 999px 0; right: 3px; }
.ui-cal-grid button.ice::before { background: rgba(120, 190, 255, 0.28); }
.ui-cal-grid button.ice.a::before { border-radius: 999px 0 0 999px; left: 3px; }
.ui-cal-grid button.ice.z::before { border-radius: 0 999px 999px 0; right: 3px; }
.ui-cal-grid button.pick { color: #10131a; font-weight: 750; }
.ui-cal-grid button.pick::after { content: ""; position: absolute; z-index: -1; width: 36px; height: 36px; border-radius: 50%; background: var(--ui-ink); }
.ui-cal-grid button.pick.gold::after { background: var(--ui-gold); }
.ui-cal-grid button.today:not(.pick)::after { content: ""; position: absolute; bottom: 5px; width: 4px; height: 4px; border-radius: 50%; background: var(--ui-ink-2); }

/* ── signing pad ──────────────────────────────────────────────────────── */
/* Nothing in the box but the ink. At its foot: "Sign here" on the right, which gives way to Clear once there is
   ink; Absent on the left while there is none (RN448). */
.ui-pad { position: relative; height: 278px; border-radius: 22px; overflow: hidden; touch-action: none;
  background: radial-gradient(120% 80% at 50% 0%, rgba(255, 255, 255, 0.045), transparent 62%), rgba(0, 0, 0, 0.26);
  box-shadow: inset 0 0 0 1px rgba(var(--c-rgb), 0.36), inset 0 1px 0 rgba(255, 255, 255, 0.1); }
.ui-pad::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 900ms cubic-bezier(0.3, 0, 0.2, 1); background: rgba(var(--c-rgb), 0.07); box-shadow: inset 0 0 0 1px rgba(var(--c-rgb), 0.7); }
.ui-pad.inked::after { opacity: 1; }
.ui-pad canvas { position: absolute; inset: 0; width: 100%; height: 100%; filter: drop-shadow(0 0 3px rgba(var(--c-rgb), 0.55)); }
.ui-pad .tip { position: absolute; left: 0; top: 0; width: 60px; height: 60px; margin: -30px 0 0 -30px; border-radius: 50%; pointer-events: none; opacity: 0; mix-blend-mode: screen; will-change: transform;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.5), rgba(var(--c-rgb), 0.3) 42%, transparent 100%); transition: opacity 360ms ease; }
.ui-pad.drawing .tip { opacity: 1; transition-duration: 80ms; }
.ui-pad .hint { position: absolute; right: 18px; bottom: 12px; height: 36px; display: inline-flex; align-items: center; font: 650 10.5px var(--ui-font); letter-spacing: 0.13em; text-transform: uppercase; color: var(--ui-ink-3); pointer-events: none; transition: opacity 260ms ease, filter 260ms ease; }
.ui-pad .ui-glass { position: absolute; bottom: 12px; transition: opacity 260ms ease, filter 260ms ease, transform 160ms var(--ui-ease), background-color 220ms ease, box-shadow 220ms ease; }
.ui-pad .clear { right: 12px; opacity: 0; filter: blur(6px); pointer-events: none; }
.ui-pad .absent { left: 12px; }
.ui-pad.inked .hint, .ui-pad.inked .absent { opacity: 0; filter: blur(6px); pointer-events: none; }
.ui-pad.inked .clear { opacity: 1; filter: none; pointer-events: auto; }
.ui-pad.drawing .ui-glass { pointer-events: none; }
.ui-pad.small { height: 120px; pointer-events: none; }
/* a signature on record is its ink on the ground it is shown on: the pad's box is for signing, never for showing (RN1263) */
.ui-pad.small, .ui-pad.small.inked { background: none; box-shadow: none; border-radius: 0; }
.ui-pad.small::after { content: none; }
/* signatures shown back: one well each, side by side when two signed (RN584) */
.ui-sigs { display: flex; gap: 10px; }
.ui-sig { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.ui-sigs:not(.two) .ui-pad.small { height: 136px; }
.ui-sig .ui-pad.off { opacity: 0.55; }
/* alone and absent there is no ink to show: the name and "absent" stand by themselves, with no empty space above */
.ui-sigs:not(.two) .ui-pad.small.off { height: 0; }
/* the signer's name stands under the line, as on paper: never inside the well, where stored ink could cross it */
.ui-sig .who { padding: 0 6px; font: 650 10.5px var(--ui-font); letter-spacing: 0.13em; text-transform: uppercase; color: var(--ui-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ── the lift: a thing floats to the drawer's top, the rest blurs away, what it shows stands under it (RN585).
   Lifted, it wears the look of an opened pill: the class colour as its edge, never a fill of its own. ── */
/* the carried copy keeps the classes of the thing it copies, and a piece's own transition (.ui-text-act's press fade,
   say) came later at the same weight and took the glide's place: the copy stood still, then landed in one frame at its
   home's place in the drawer, 33px under the screen, and rose with the drawer (glide42, the Mina pill). The glide is
   the carry's own, whatever it copies */
.ui-carry { position: absolute; z-index: 5; margin: 0; box-sizing: border-box; pointer-events: none; will-change: transform; border-radius: 999px;
  transition: transform 460ms var(--ui-ease), width 460ms var(--ui-ease), height 460ms var(--ui-ease), padding 460ms var(--ui-ease), min-height 460ms var(--ui-ease), background-color 360ms ease, box-shadow 360ms ease !important; }
.ui-lifted { display: flex; }
.ui-lifted > * { border-radius: 999px; transition: transform 160ms var(--ui-ease); }
.ui-lifted > *:active { transform: scale(0.985); }
.ui-carry, .ui-lifted > * { border-bottom: 0; }
.ui-lifted > *, .ui-carry.lifted { background: rgba(var(--c-rgb), 0.1); box-shadow: inset 0 0 0 1.5px rgba(var(--c-rgb), 0.9); }
.ui-lifted > .ui-li, .ui-li.ui-carry.lifted { padding-left: 16px; padding-right: 14px; }
/* a text act has a 4px side room as a bare word; lifted ("Mina asked about this", "This isn't right", a staff member's rate history) it becomes a pill, so it takes the pill's own: 16px each side, the words centred, as a lifted row's left room and the glass .ui-who have. The carried copy takes it as it lifts, so the words do not jump when it lands. */
.ui-lifted > .ui-text-act, .ui-text-act.ui-carry.lifted { padding-left: 16px; padding-right: 16px; justify-content: center; }
.ui-li.ui-carry .end svg { transition: color 300ms ease; }
.ui-lifted > .ui-li .end svg, .ui-li.ui-carry.lifted .end svg { color: var(--ui-ink); }
/* a small glass pill for an act that sits on top of something else: flat glass, a hairline edge, no bevel, no lift (RN494) */
.ui-glass { position: relative; display: inline-flex; align-items: center; min-height: 36px; padding: 0 15px; border-radius: 999px; font: 650 13px var(--ui-font); color: var(--ui-ink); white-space: nowrap;
  background: var(--ui-glass);
  box-shadow: inset 0 0 0 1px var(--ui-edge); }
.ui-glass::after { content: ""; position: absolute; inset: -5px -3px; }
.ui-glass:active { transform: scale(0.96); }
.ui-glass[aria-pressed="true"] { background: rgba(var(--c-rgb), var(--ui-on-a)); box-shadow: none; }
/* a pill holding only its words (no symbol, no inner piece) lays them as one line, trimmed to the capitals and the
   baseline, at the pill's true middle (RN1390): a flex box cannot trim words that stand loose in it */
:is(.ui-go, .ui-vpill, .ui-glass):not(:has(> *)) { display: inline-block; align-content: center; text-box: trim-both cap alphabetic; }
.ui-vpill:not(:has(> *)) { text-align: start; }
.ui-go:not(:has(> *)) { text-align: center; }

/* ── symbols: bare, one set. dim = nothing to do; full = yours; bounce = now ── */
.ui-sym { position: relative; flex: none; display: inline-grid; place-items: center; width: 34px; height: var(--ui-tap); color: var(--sym, currentColor); }
/* the drawing is 34 wide; the finger gets the full 44 */
.ui-sym::after { content: ""; position: absolute; inset: 0 -5px; }
.ui-sym svg { width: 21px; height: 21px; }
.ui-sym.dim { opacity: 0.42; }
.ui-mark { display: block; flex: none; overflow: visible; }
/* beri's berry (UI.berry): the words it lands on, each giving a little under it; the berry itself, flat bright blue as on
   beri's website, out of the mark while it skips (the mark's own berry hidden meanwhile) (RN1372) */
.ui-berry-w { display: inline-block; transform-origin: 50% 100%; }
.ui-berry { position: absolute; left: 0; top: 0; z-index: 3; border-radius: 50%; background: #2f7bff; box-shadow: 0 1px 6px rgba(29, 108, 237, 0.45); pointer-events: none; will-change: transform; }
.ui-mark.ui-berry-out .ui-mark-berry { opacity: 0; }
/* what needs her now bounces twice, rests three times as long as the two bounces took, and bounces twice again
   (RN621; the rest is the one he chose of three, RN653): up easing out, down gathering speed, the way a thing that
   is thrown moves */
.ui-sym.now svg { animation: ui-bounce 4.8s infinite; transform-origin: 50% 100%; }
@keyframes ui-bounce {
  0%, 12.5% { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  6.25%, 18.75% { transform: translateY(-8px); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.25); }
  25%, 100% { transform: translateY(0); }
}
/* what is close hops the same two hops (UI.hop): within two days at this cadence, three to five days out at half of it,
   resting twice as long (RN1373, RN1376). A word rises a third of its height, a symbol 8 px; never with less motion */
.ui-hop { --hop: -0.32em; animation: ui-hop 4.8s infinite; transform-origin: 50% 100%; }
svg.ui-hop, .ui-hop > svg { --hop: -8px; }
/* a word that hops is its own block, or it would not move (a bare inline span does not) */
span.ui-hop { display: inline-block; }
.ui-hop.slow { animation-name: ui-hop-slow; animation-duration: 9.6s; }
@keyframes ui-hop {
  0%, 12.5% { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  6.25%, 18.75% { transform: translateY(var(--hop)); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.25); }
  25%, 100% { transform: translateY(0); }
}
@keyframes ui-hop-slow {
  0%, 6.25% { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  3.125%, 9.375% { transform: translateY(var(--hop)); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.25); }
  12.5%, 100% { transform: translateY(0); }
}
/* A word never hops (RN1400: the duet card's end date hopping "doesn't work"). A word that is close says so by the slow
   soft wave the low count and the frost's date already carry (operator.css, low-sheen, RN621): lighter in its own
   colour, passing through it and back, never gold, nothing around it. Within two days it comes every 4.8 s, three to
   five days out every 9.6 s, on the beat the symbols still hop to. Only a symbol hops. */
:is(span, b, em, small, strong).ui-hop:not(:has(svg)) { animation: ui-sheen 4.8s cubic-bezier(0.45, 0, 0.55, 1) infinite; transform: none;
  background-image: linear-gradient(105deg, currentColor 0%, currentColor 28%, color-mix(in oklab, currentColor 84%, #fff) 41%, color-mix(in oklab, currentColor 62%, #fff) 50%, color-mix(in oklab, currentColor 84%, #fff) 59%, currentColor 72%, currentColor 100%);
  background-repeat: no-repeat; background-size: 320% 100%; background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
:is(span, b, em, small, strong).ui-hop.slow:not(:has(svg)) { animation-name: ui-sheen; animation-duration: 9.6s; }
@keyframes ui-sheen { 0%, 100% { background-position: 100% 0; } 32% { background-position: 0% 0; } }
@media (prefers-reduced-motion: reduce) { .ui-hop, .ui-sym.now svg { animation: none; } }
svg.ui-i { display: block; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
/* a row's trailing sign has one size everywhere, never the bare drawing at full width (RN1368 scan: Review matches) */
:where(.ui-row .side) > svg.ui-i { flex: none; width: 16px; height: 16px; }

/* ── touch: whatever is touched answers at once (RN553) ──────────────────
   A shape gives a little under the finger, by its size: a round button 0.92 to 0.94, a pill 0.96, the wide action
   0.98. A bare row or word has no body to give, so it dims. A symbol gives like a shape. Nothing touched stays still. */
.ui-sec > button, .ui-row[data-a], .ui-text-act, .ui-name, .ui-state[data-a], .ui-cal-head button { transition: opacity 140ms ease; }
.ui-li[data-a] { transition: opacity 140ms ease, color 180ms; }
.ui-sec > button:active, .ui-row[data-a]:active, .ui-li[data-a]:active, .ui-text-act:active, .ui-name:active, .ui-state[data-a]:active, .ui-cal-head button:active,
/* every line she can tap answers the same way (RN553, RN1263: the eight found with no answer) */
.pk-date-toggle:active, .ui-order-open:active, .app-on:active, .ui-tip[data-a]:active, .cover-away-impact:active, .rc-replaces:active, .rc-replaced:active { opacity: 0.5; }
.ui-sym[data-a], .ui-cal-grid button { transition: transform 160ms var(--ui-ease); }
.ui-sym[data-a]:active { transform: scale(0.86); }
.ui-cal-grid button:active { transform: scale(0.88); }
/* the one just chosen takes its colour while she watches, rather than arriving already lit */
@keyframes ui-chosen { from { background-color: var(--ui-glass); transform: scale(0.95); } }
/* it gives as one piece, never squashed or stretched: a word in it keeps its shape (RN1399, RN1400) */
@keyframes ui-chosen-give { 0%, 100% { transform: none; } 30% { transform: translateY(1px); } 64% { transform: translateY(-0.5px); } }
.ui-chip.just:where(:not(.ui-out)) { transform-origin: 50% 100%; animation: ui-chosen 280ms var(--ui-ease) both, ui-chosen-give 440ms ease-out 200ms; }
/* a number she steps moves the way it went: up from below, down from above, through the one blur */
@keyframes ui-tick { from { opacity: 0; filter: blur(6px); transform: translateY(var(--ui-dy, 7px)); } }
.ui-stepper output, .ui-go output { display: inline-block; }
.ui-stepper output.tick, .ui-go output.tick { animation: ui-tick 260ms var(--ui-ease) both; }
.ui-go .ui-go-says, .ui-go .ui-go-during { display: block; min-width: 0; max-width: 100%; overflow: clip visible; text-overflow: ellipsis; white-space: nowrap; }
.ui-go .ui-go-during { display: none; }
/* a symbol in the main button sits on the line of its words, before them, or after them when the words lead (a way on) */
.ui-go .ui-go-says > svg.ui-i, .ui-go .ui-go-during > svg.ui-i { display: inline-block; vertical-align: -4px; margin: 0 8px 0 0; }
.ui-go .ui-go-says.after > svg.ui-i:last-child { margin: 0 -4px 0 6px; }
.ui-go.is-during .ui-go-says { display: none; }
.ui-go.is-during .ui-go-during { display: block; }
.ui-go .ui-go-says.tick, .ui-go .ui-go-during.tick { animation: ui-tick 260ms var(--ui-ease) both; }

/* ── a short notice after an act ──────────────────────────────────────── */
/* ── a place with areas (RN597): the parts of an area as title words, a dock for the foot, a search. It is as tall
   as what it holds, like every drawer, and glides to its new height as she turns to another area or part (RN636) ── */
/* in a place the head stands still (its title or tabs, and its act): only the area under it scrolls, and dissolves
   under the head as the body does under the drawer's edge */
.ui-body.ui-placed { overflow: hidden; padding-bottom: 0; -webkit-mask-image: none; mask-image: none; }
.ui-body.ui-placed > [data-area] { flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 0 -18px; padding: 2px 18px 20px; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-fb, 22px)), rgba(0, 0, 0, 0.14) calc(100% - var(--ui-fb, 22px) * 0.5), transparent calc(100% - var(--ui-fb, 22px) * 0.1)); mask-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1) calc(var(--ui-ft, 0px) * 0.4), rgba(0, 0, 0, 0.55) calc(var(--ui-ft, 0px) * 0.75), #000 var(--ui-ft, 0px), #000 calc(100% - var(--ui-fb, 22px)), rgba(0, 0, 0, 0.14) calc(100% - var(--ui-fb, 22px) * 0.5), transparent calc(100% - var(--ui-fb, 22px) * 0.1)); }
.ui-body.ui-placed > [data-area]::-webkit-scrollbar { display: none; }
.ui-body.ui-placed > [data-area] > * { flex-shrink: 0; }
.ui-tabs { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 20px; overflow-x: auto; margin: 0 0 0 -18px; padding: 0 18px; scroll-padding: 0 18px; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%); mask-image: linear-gradient(90deg, transparent 0, #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%);
  transition: --ui-fl 280ms ease, --ui-fr 280ms ease; }
.ui-tabs::-webkit-scrollbar { display: none; }
.ui-tabs.more-l { --ui-fl: 36px; }
.ui-tabs.more-r { --ui-fr: 36px; }
.ui-tab { position: relative; flex: none; min-height: 30px; font: 650 21px/1.15 var(--ui-font); letter-spacing: -0.03em; white-space: nowrap; color: var(--ui-ink-3); transition: color 240ms ease, transform 160ms var(--ui-ease); }
.ui-tab::after { content: ""; position: absolute; inset: -9px -8px; }
.ui-tab .amp { font-weight: 300; margin: 0 0.24em; }
.ui-tab[aria-selected="true"] { color: var(--ui-ink); }
.ui-tab[aria-selected="true"] .amp { color: var(--ui-ink-3); }
.ui-tab:active { transform: scale(0.97); }
.ui-dock[hidden] { display: none; }
.ui-dock { flex: 1; min-width: 0; height: 56px; padding: 3px; display: flex; align-items: stretch; border-radius: 999px; background: var(--ui-glass); box-shadow: inset 0 0 0 1px var(--ui-edge); }
/* The search bar is one bar wherever it stands (RN673): frost, ink on it, its lens in the system colour while she
   searches (RN641; of five answers he chose the quietest, RN653). On the page of packages it stands open. In a dock
   of parts it is folded to its lens, and a touch opens it into the same bar: same ground, same lens, same room
   before the words. */
.ui-dock-tabs { --ui-dock-label-base: 10.5px; flex: 1 1 0; min-width: 0; display: flex; padding-left: 8px; overflow: hidden; border-radius: 999px 0 0 999px; transition: flex-grow 380ms var(--ui-ease), opacity 200ms ease, filter 260ms ease; }
.ui-dock-tabs button { flex: 1 1 auto; min-width: 44px; padding: 0 3px; display: grid; justify-items: center; align-content: center; gap: 3px; border-radius: 999px; font: 600 10.5px var(--ui-font); white-space: nowrap; color: var(--ui-ink-3); transition: color 220ms ease, transform 160ms var(--ui-ease); }
/* The studio's five short names share equal columns; words may extend into a
   column's spare space, but dockFit checks their actual separation. */
.ui-dock-tabs.even:not(.signs) { padding-left: 0; overflow: visible; }
.ui-dock-tabs.even button { flex: 1 1 0; min-width: 0; grid-template-columns: minmax(0, 1fr); }
@media (max-width: 374px) { .ui-dock-tabs.even { --ui-dock-label-base: 10px; } .ui-dock-tabs.even button { font-size: 10px; letter-spacing: -0.1px; } }
.ui-dock-tabs button svg { width: 22px; height: 22px; }
.ui-dock-tabs button > span { font-size: min(1em, var(--ui-dock-text-cap, 1em)); }
.ui-dock-tabs.large-text button > span { text-align: center; }
.ui-dock-tabs button:active { transform: scale(0.93); }
.ui-dock-tabs button[aria-current="page"] { color: var(--ui-accent-ink, var(--ui-accent)); }
/* more areas than the dock holds with ease (ui.js, dockFit): closer first; then the symbol alone for an area she is not
   in, its word kept in the row's height so every symbol stays on one line */
.ui-dock-tabs.close { padding-left: 6px; }
.ui-dock-tabs.close button { min-width: 38px; padding: 0 1px; }
/* a symbol without its word may stand as close as its own width and a little room, so six areas and the search fit whole
   at 360 (27 Oct); where even that does not fit (six at 320) the row runs sideways and fades at the edge it goes on past,
   as every sideways row does, and a symbol is never cut */
.ui-dock-tabs.signs button { flex: 1 1 0; min-width: 36px; }
.ui-dock-tabs.signs button:not([aria-current="page"]) { min-width: 28px; }
.ui-dock-tabs.signs.roll { overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%); mask-image: linear-gradient(90deg, transparent 0, transparent var(--ui-fl0), #000 var(--ui-fl), #000 calc(100% - var(--ui-fr)), transparent 100%);
  transition: flex-grow 380ms var(--ui-ease), opacity 200ms ease, filter 260ms ease, --ui-fl0 280ms ease, --ui-fl 280ms ease, --ui-fr 280ms ease; }
.ui-dock-tabs.roll::-webkit-scrollbar { display: none; }
.ui-dock-tabs.roll.more-l { --ui-fl: 28px; }
.ui-dock-tabs.roll.more-r { --ui-fr: 28px; }
.ui-dock-tabs.signs button span { max-width: 0; overflow: hidden; opacity: 0; transition: opacity 220ms ease; }
/* A symbol-only page has no name slot in the layout; its accessible name stays in the DOM. */
.ui-dock-tabs.signs button:not([aria-current="page"]) > span { position: absolute; }
.ui-dock-tabs.signs button[aria-current="page"] { flex: 0 0 auto; padding: 0 4px; }
.ui-dock-tabs.signs button[aria-current="page"] span { max-width: none; overflow: visible; opacity: 1; }
.ui-dock-tabs.wrap.signs button[aria-current="page"] > span { min-width: min-content; max-width: var(--ui-dock-label-max); white-space: normal; overflow-wrap: normal; }
.ui-dock-find { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; border-radius: 999px; background: rgba(255, 255, 255, 0); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0); transition: flex-grow 380ms var(--ui-ease), background-color 300ms ease, box-shadow 300ms ease; }
.ui-dock-find button { flex: none; width: 42px; height: 50px; padding: 0; display: grid; place-items: center; border-radius: 50%; color: var(--ui-ink-2); transition: transform 160ms var(--ui-ease), color 200ms ease, width 380ms var(--ui-ease), padding 380ms var(--ui-ease); }
.ui-dock-find button:active { transform: scale(0.9); }
.ui-dock-find button svg { width: 21px; height: 21px; transition: width 380ms var(--ui-ease), height 380ms var(--ui-ease); }
.ui-dock-find input { flex: 1 1 0; width: 0; min-width: 0; height: 100%; padding: 0; border: 0; outline: 0; border-radius: 0; background: none; font: 600 16px var(--ui-font); color: var(--ui-frost-ink); opacity: 0; transition: opacity 220ms ease; }
.ui-dock-find input::placeholder { color: var(--ui-frost-ink-2); }
.ui-dock-find input::-webkit-search-cancel-button { display: none; }
.finding .ui-dock-tabs { flex-grow: 0; padding-left: 0; opacity: 0; filter: blur(8px); pointer-events: none; }
.finding .ui-dock-find { flex-grow: 1; background: var(--ui-frost); box-shadow: inset 0 0 0 1px var(--ui-frost-edge); }
.finding .ui-dock-find button { width: 44px; color: var(--ui-accent); }
.finding .ui-dock-find button svg { width: 19px; height: 19px; }
.ui-drawer.finding .ui-back { color: var(--ui-accent-ink, var(--ui-accent)); }
.finding .ui-dock-find input { opacity: 1; padding-right: 16px; transition-delay: 120ms; }
.is-place .ui-body { transition: opacity 240ms ease, filter 300ms ease; }
/* the search of a place leaves what is above it as it is (RN613). While pills stand over the bar, what is behind them
   dissolves into the drawer a little earlier (the same fade the foot of a scroller always has, grown): no veil, no
   band, nothing laid over her page */
.ui-drawer.has-found { --ui-fb: 128px; }
/* What the app brings her hops in the way beri's berry skips across the studio's name (RN1386: "the playful
   bouncing... like the little berry in the logo"; "intelligence and being alive and upbeat"). The blur says a thing
   changed; the hop says the app found or made it for her: a pill the search brings up, the people found, the ways to
   reach someone. It leaves the bar in a little leap as one solid piece (never stretched or squashed: the words in it
   keep their shape, RN1399, RN1400), lands, rebounds once and rests, each a beat after the one before, so a row of them
   reads left to right like the berry going word to word. Once, never again until it is brought anew; only what
   needs her keeps hopping (UI.hop). */
.ui-bub { transform-origin: 50% 100%; animation: ui-bub-hop 640ms both, ui-bub-clear 240ms ease both; animation-delay: calc(var(--i, 0) * 50ms); }
@keyframes ui-bub-hop {
  0% { transform: translateY(16px); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  40% { transform: translateY(-5px); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.25); }
  62% { transform: translateY(1px); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  80% { transform: translateY(-1px); animation-timing-function: ease-in-out; }
  100% { transform: none; }
}
@keyframes ui-bub-clear { from { opacity: 0; filter: blur(5px); } }
/* a thing that becomes hers (a pill chosen, a name that takes its check) gives once under it, the berry's landing */
/* the beri hop in place: a small crouch, up, down, settled (UI.hopOnce), as one piece: a name in it keeps its shape */
.ui-hop-once { transform-origin: 50% 100%; animation: ui-hop-once 620ms 150ms both; }
@keyframes ui-hop-once {
  0% { transform: none; animation-timing-function: ease-out; }
  14% { transform: translateY(1px); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  42% { transform: translateY(-7px); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.3); }
  64% { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.75, 0.4, 1); }
  82% { transform: translateY(-1.5px); animation-timing-function: ease-in-out; }
  100% { transform: none; } }
@keyframes ui-give { 0%, 100% { transform: none; } 32% { transform: translateY(1px); } 66% { transform: translateY(-0.5px); } }
.ui-who.done.just:where(:not(.ui-out)) { transform-origin: 50% 100%; animation: ui-give 460ms ease-out 640ms both; }
.ui-found { position: relative; z-index: 3; flex: none; height: 0; }
.ui-found-row { position: absolute; left: 0; right: 0; bottom: 6px; display: flex; gap: 8px; overflow-y: hidden; }
.ui-found-row.ui-chips.scroll { margin: 0; padding: 6px 18px; scroll-padding: 0 44px 0 18px; }
.ui-found-row::-webkit-scrollbar { display: none; }
.ui-found-row .ui-vpill { flex: none; gap: 7px; padding: 0 16px 0 12px; background: color-mix(in srgb, var(--ui-sheet) 94%, transparent); }
.ui-found-row .ui-vpill svg { width: 18px; height: 18px; color: var(--ui-ink-2); }
.ui-found-none { position: absolute; left: 20px; bottom: 18px; margin: 0; font: 600 13.5px var(--ui-font); color: var(--ui-ink-3); }
/* a thing she was taken to, and what a line speaks of, are pointed at in one way: everything else goes soft once
   (UI.eye in ui.js, RN962). It has no style here: the softness is laid over each thing's own look as it runs. */
@media (prefers-reduced-motion: reduce) { .ui-dock-tabs, .ui-dock-find, .ui-dock-find button, .ui-dock-find button svg, .ui-dock-find input, .is-place .ui-body { transition-duration: 1ms; } }
.ui-toast { position: absolute; z-index: 60; left: 50%; top: calc(var(--safe-top, 12px) + 10px); width: max-content; max-width: calc(100% - 36px); transform: translate(-50%, calc(-100% - var(--safe-top, 12px) - 10px)); padding: 12px 18px; border-radius: 22px; font: 650 13.5px/1.35 var(--ui-font); color: #f5f7fb; white-space: normal; overflow-wrap: anywhere; text-wrap: balance; text-align: center; background: rgba(20, 26, 38, 0.94); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), 0 18px 40px -16px rgba(0, 0, 0, 0.9); opacity: 0; filter: blur(8px); pointer-events: none; transition: opacity 200ms ease, transform 200ms var(--ui-exit), filter 200ms ease; }
/* it drops from above the edge on the kit's spring: quick, a breath past its place, then slowly to rest (RN1024) */
.ui-toast.on { opacity: 1; transform: translate(-50%, 0); filter: none; transition: opacity 260ms ease, transform var(--ui-t-spring) var(--ui-spring), filter 260ms ease; }
/* the toast stands against what is behind it (RN940): dark glass with the light ink over something light, and over
   something dark the frost, the search bar's own white glass and ink. ui.js reads which, each time one shows */
.ui-toast.frost { color: var(--ui-frost-ink); background: var(--ui-frost); box-shadow: inset 0 0 0 1px var(--ui-frost-edge), 0 18px 40px -16px rgba(0, 0, 0, 0.9); }
/* The toast speaks from the top (RN951), where a screen's first row stands. That row goes behind a veil while the
   toast speaks: the veil a drawer puts over a page, over the top band only and fading out beneath it, so nothing is
   read through the toast and no word is cut by it. Its height is set to the toast's each time (ui.js). */
.ui-toast-veil { position: absolute; z-index: 59; left: 0; right: 0; top: 0; height: 96px; background: rgba(3, 6, 14, 0.56); -webkit-backdrop-filter: blur(14px) saturate(0.9); backdrop-filter: blur(14px) saturate(0.9); -webkit-mask-image: linear-gradient(#000 calc(100% - 26px), transparent); mask-image: linear-gradient(#000 calc(100% - 26px), transparent); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 260ms ease, visibility 0s 260ms; }
.ui-toast-veil.on { opacity: 1; visibility: visible; transition: opacity 260ms ease; }
:root[data-mode="day"] .ui-toast-veil { background: rgba(246, 249, 249, 0.66); }
/* behind an open drawer the page is veiled already: only the blur is added */
.ui-has-drawer > .ui-toast-veil, :root[data-mode="day"] .ui-has-drawer > .ui-toast-veil { background: none; }

/* a weekday heading a day (UI.wd): its letter on a phone, its short name where a tablet has the room (RN1378) */
.ui-wd > .s { display: none; }
@media (min-width: 680px) { .ui-wd > .n { display: none; } .ui-wd > .s { display: inline; } }
/* from the tablet line (680, an Android tablet upright; RN1371, RN1380) a drawer is a centred sheet, never a phone's
   drawer stretched across the screen */
@media (min-width: 680px) {
  #device .ui-drawer { left: 50%; right: auto; width: min(100%, 620px); transform: translate(-50%, calc(100% + 80px + var(--ui-size-y))); }
  #device .ui-drawer.open { transform: translate(-50%, var(--ui-size-y)); }
  #device .ui-toast { max-width: min(480px, calc(100% - 36px)); white-space: normal; text-align: center; }
}
/* held sideways it is a sheet at the right that fits what it holds and rises from the bottom like the phone's, so a
   short drawer leaves no empty band above its foot (RN1379) */
@media (min-width: 900px) {
  #device .ui-drawer {
    top: auto; right: 16px; bottom: 16px; left: auto; width: 440px; max-height: calc(100% - 32px); border-bottom: 1px solid var(--ui-sheet-edge); border-radius: 28px;
    transform: translate(calc(100% + 16px), var(--ui-size-y));
    transition: transform 200ms var(--ui-exit), translate 200ms var(--ui-exit), visibility 0s linear 200ms, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease;
  }
  #device .ui-drawer.open {
    transform: translate(0, var(--ui-size-y));
    transition: transform var(--ui-t) var(--ui-ease), translate var(--ui-t) var(--ui-ease), visibility 0s, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease;
  }
  /* the box stands at its tallest below its shown edge (--ui-size-y); beside the page that edge is its rounded foot */
  #device .ui-drawer { clip-path: inset(0 0 var(--ui-size-y) 0 round 28px); }
  #device .ui-drawer.ui-size-glide { transition: transform var(--ui-t-drawer) var(--ui-ease), translate 560ms var(--ui-ease), clip-path var(--ui-t-drawer) var(--ui-ease), visibility 0s, border-color 900ms cubic-bezier(0.3, 0, 0.2, 1), --ui-fb 360ms ease; }
  /* the page stays visible beside the drawer, softened as the kit points at something */
  #device.ui-has-drawer .page { filter: blur(6px) opacity(0.58); transform: none; transition: filter var(--ui-t) var(--ui-ease); }
  #device.ui-has-drawer > .ui-scrim { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-in { --ui-blur: 0px; }
  .ui-in, .ui-out { animation-duration: 1ms; }
  .ui-carry { transition-duration: 1ms !important; }
  .ui-seg.fit .lens { transition-duration: 1ms; }
  .ui-chip.just, .ui-stepper output.tick, .ui-wheel .drum.in .strip { animation: none; }
  .ui-who .ui-who-tick, .ui-who.done .ui-who-tick path, .ui-who .ui-who-off, .ui-chips.scroll, .ui-pad .hint, .ui-pad .ui-glass { transition-duration: 1ms; transition-delay: 0s; }
  .ui-sym.now svg, .ui-who.done.just::before, .ui-who.done.just, .ui-hop-once { animation: none; }
  .ui-bub { animation: ui-bub-clear 240ms ease both; }
  .ui-drawer, .ui-scrim, .ui-sec > .fold, .ui-sec > .fold > div { transition-duration: 1ms; }
  .ui-drawer.ui-size-glide { transition-duration: 1ms; }
}

/* Labelled share: the existing value-pill body extended with an honest fraction behind its facts. */
.ui-root { --ui-pill-radius: 999px; --ui-share-name-size: 15px; --ui-share-symbol-size: 18px; --ui-share-detail-size: 13px; --ui-share-wash: 0.5; --ui-share-edge: 0.5; }
.ui-share.ui-li { --share-colour: rgb(var(--k-rgb)); position: relative; isolation: isolate; min-height: var(--ui-tap); padding: 0 12px; gap: 7px; border: 1px solid color-mix(in srgb, var(--share-colour) calc(var(--ui-share-edge) * 100%), transparent); border-radius: var(--ui-pill-radius); background: var(--ui-well); box-shadow: none; white-space: nowrap; color: var(--ui-ink); overflow: hidden; }
.ui-share.ui-li:not(.ui-carry) { transition: transform 160ms var(--ui-ease); }
.ui-share-fill { position: absolute; z-index: -1; inset: -1px auto -1px -1px; width: calc(100% + 2px); border-radius: var(--ui-pill-radius); background: color-mix(in srgb, var(--share-colour) calc(var(--ui-share-wash) * 100%), transparent); transform: translateX(calc(var(--w) - 100%)); }
/* the fill is the whole pill drawn back to its share: a small share is a clean sliver in the pill's own end, never a round blob */
.ui-share-fill[hidden] { display: none; }
.ui-share-name { min-width: 0; overflow: clip visible; text-overflow: ellipsis; font-size: var(--ui-share-name-size); font-weight: 650; }
.ui-share-count { flex: none; font-size: var(--ui-share-detail-size); color: var(--ui-ink-2); }
.ui-share.ui-li .end { color: var(--ui-ink); font-size: var(--ui-share-detail-size); }
.ui-share.ui-li .dot { background: var(--share-colour); }
.ui-share.ui-li > .ui-i:first-of-type { flex: none; width: var(--ui-share-symbol-size); height: var(--ui-share-symbol-size); color: var(--ui-ink-2); }
button.ui-share:active { transform: scale(0.985); }
.ui-share:has(.ui-share-name:nth-last-child(2)) .ui-share-name { flex: 1; }
.fresh .ui-share-fill { animation: ui-share-grow var(--ui-t-spring) var(--ui-ease) both; }
.ui-carry .ui-share-fill, .ui-lifted .ui-share-fill { animation: none; }
@keyframes ui-share-grow { from { transform: translateX(-100%); } }
:root[data-mode="day"] .ui-share { --ui-share-wash: var(--ui-on-a); --share-colour: color-mix(in oklab, rgb(var(--k-rgb)) 80%, var(--ui-frost-ink)); }
@media (max-width: 375px) { .ui-share.ui-li { padding-inline: 10px; gap: 5px; } }
@media (prefers-reduced-motion: reduce) { .fresh .ui-share-fill { animation: none; } }

.ui-share-count[hidden] { display: none; }
/* The owner prototype has no day selector yet; the shared drawer accepts the same day roles. */
:root[data-mode="day"] .ui-root { --ui-warn: #8a5f0e; --ui-bad: #b23f42; --ui-ok: #137a61; --ui-ink: var(--ui-frost-ink); --ui-ink-2: var(--ui-frost-ink-2); --ui-ink-3: var(--ui-frost-ink-2); --ui-sheet: var(--ui-on-accent); --ui-sheet-edge: var(--ui-on-accent); --ui-line: color-mix(in srgb, var(--ui-frost-ink) 10%, transparent); --ui-well: color-mix(in srgb, var(--ui-frost-ink) 5.5%, transparent); --ui-edge: color-mix(in srgb, var(--ui-frost-ink) 16%, transparent); --ui-glass: color-mix(in srgb, var(--ui-frost-ink) 5%, transparent); --ui-on-a: 0.15; }

/* ── an act's answer (RN917) ── The thing touched waits: it stays as pressed and its word breathes (the sign-in's own
   scan breath). A no is the kit's one no: blur and return, the code's. The line is one line in quiet ink (RN595):
   over the foot for the main act, under its own block for a control in the body. Nothing is red and nothing spins. */
.ui-held { pointer-events: none; opacity: 0.72; transition: opacity 160ms ease; }
.ui-waits { pointer-events: none; animation: ui-waits var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-waits { to { opacity: 0.45; } }
.ui-drawer.ui-waits { pointer-events: auto; opacity: 1; animation: none; }
.ui-drawer.ui-waits .ui-lit { animation: ui-waits-light var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-waits-light { from { filter: brightness(1); } to { filter: brightness(calc(1 + var(--ui-wait-strength) / 3)); } }
.ui-go.ui-held { position: relative; opacity: 1; transform: scale(0.98); filter: brightness(0.92); }
.ui-go.ui-waits { animation: none; }
/* A choice not yet made leans toward chosen at once and breathes there. It never dims: that would read as leaving. */
.ui-chip[aria-pressed="false"].ui-held, .ui-seg button[aria-pressed="false"].ui-held { opacity: 1; color: var(--ui-ink); background-color: rgba(var(--c-rgb), calc(var(--ui-on-a) * 0.42)); transition: background-color 180ms ease, color 180ms ease; }
.ui-chip[aria-pressed="false"].ui-waits, .ui-seg button[aria-pressed="false"].ui-waits { animation: ui-leans var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-leans { to { background-color: rgba(var(--c-rgb), calc(var(--ui-on-a) * 0.14)); } }
.ui-pick .ui-li[aria-pressed="false"].ui-held { opacity: 1; color: var(--ui-ink); }
.ui-pick .ui-li[aria-pressed="false"].ui-held .end svg { opacity: 0.62; transform: scale(0.84); }
.ui-pick .ui-li[aria-pressed="false"].ui-waits { animation: none; }
.ui-pick .ui-li[aria-pressed="false"].ui-waits .end svg { animation: ui-leans-tick var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-leans-tick { to { opacity: 0.2; } }
.ui-tint.pick.ui-held:not([aria-pressed="true"]):not(.on) { opacity: 1; outline-color: color-mix(in srgb, var(--t) 62%, transparent); }
.ui-tint.pick.ui-waits:not([aria-pressed="true"]):not(.on) { animation: ui-leans-ring var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-leans-ring { to { outline-color: color-mix(in srgb, var(--t) 18%, transparent); } }
/* A switch leans: its knob stands half way, from either side, and breathes there. */
.ui-onoff.ui-held { opacity: 1; }
.ui-onoff.ui-held > i { background: rgba(var(--c-rgb), calc((var(--ui-on-a) + 0.3) * 0.5)); }
.ui-onoff.ui-held > i::after, .ui-onoff[aria-checked="true"].ui-held > i::after { left: 11px; right: 11px; background: var(--ui-ink-2); }
.ui-onoff.ui-waits { animation: none; }
.ui-onoff.ui-waits > i::after { animation: ui-waits var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
.ui-go::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: inherit; opacity: 0; pointer-events: none; transition: opacity 200ms var(--ui-exit); }
.ui-go.ui-waits::after { animation: ui-waits-veil var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-waits-veil { to { opacity: var(--ui-wait-strength); } }
/* The main act is the top of the hierarchy (RN1266): lighter than the chosen tab above it, with lighter shades of its own
   colour drifting slowly inside, as on the hero button of CARE's website. The shades are the act's own colour added to
   itself (his blue, a cancel's red, a class colour), so they are brighter and as rich, never white over it: the white
   read as overexposed (RN1399). A lit top edge and a deeper foot give it body. Only the layer's transform moves.
   The three levels: the act lives and is lightest; a chosen tab is solid; a choice inside it is tinted glass. */
:root { --ui-act-light: var(--tune-actlight, 0.3); --ui-act-drift: 26s; }
.ui-go { position: relative; isolation: isolate; }
.ui-go { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -8px 14px -10px rgba(0, 0, 0, 0.4); }
.ui-go::before { content: ""; position: absolute; z-index: -1; left: -25%; right: -25%; top: -110%; bottom: -110%; pointer-events: none;
  background: inherit; mix-blend-mode: plus-lighter; opacity: calc(var(--ui-act-light) * 1.6);
  -webkit-mask-image: radial-gradient(26% 30% at 34% 46%, #000, transparent 70%), radial-gradient(24% 26% at 66% 56%, rgba(0, 0, 0, 0.62), transparent 72%), radial-gradient(34% 22% at 50% 40%, rgba(0, 0, 0, 0.4), transparent 74%);
  mask-image: radial-gradient(26% 30% at 34% 46%, #000, transparent 70%), radial-gradient(24% 26% at 66% 56%, rgba(0, 0, 0, 0.62), transparent 72%), radial-gradient(34% 22% at 50% 40%, rgba(0, 0, 0, 0.4), transparent 74%);
  animation: ui-act-drift var(--ui-act-drift) ease-in-out -6s infinite; transition: opacity 260ms ease; }
.ui-go[disabled]::before, .ui-go.ui-guides::before { opacity: 0; animation-play-state: paused; }
@keyframes ui-act-drift {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  28% { transform: translate(9%, -4%) rotate(9deg); }
  54% { transform: translate(-7%, 5%) rotate(-6deg); }
  78% { transform: translate(5%, 3%) rotate(4deg); }
}
@media (prefers-reduced-motion: reduce) { .ui-go::before { animation: none; } }
.ui-no { animation: ui-no 0.46s var(--ui-ease); }
@keyframes ui-no { 38% { filter: blur(9px); opacity: 0.25; } }
.ui-root.ui-sending .ui-body, .ui-root.ui-sending .ui-go { pointer-events: none; }
.ui-said { flex: none; display: grid; grid-template-rows: 0fr; padding: 0 20px; transition: grid-template-rows 0.36s var(--ui-ease); transform: translateY(calc(-1 * var(--ui-size-y, 0px))); }
/* the line said over the foot rides with the foot while the drawer's edge is held, so it stands over the button, never under it or below the screen (RN1368 scan) */
.ui-drawer.ui-size-glide > .ui-said { transition: grid-template-rows 0.36s var(--ui-ease), transform var(--ui-t-drawer) var(--ui-ease); }
.ui-said.on { grid-template-rows: 1fr; }
.ui-said > div { min-height: 0; overflow: hidden; }
/* the line is the app speaking (RN941): lighter and a step larger than a label, in the full ink, centred over the
   main act, with the same room above it as beneath it */
.ui-said p { margin: 0; padding: 0 0 18px; font: 500 15px/1.4 var(--ui-font); color: var(--ui-ink); text-align: center; text-wrap: balance; overflow-wrap: anywhere; opacity: 0; filter: blur(8px); transition: opacity 0.3s ease, filter 0.3s ease; }
.ui-said.on p { opacity: 1; filter: none; }
.ui-said-row.across { grid-column: 1 / -1; }
/* a line is written in, a character at a time (RN941): each clears in its turn; the line is given whole to a screen reader */
.ui-ch { opacity: 0; animation: ui-write 240ms ease forwards; }
@keyframes ui-write { to { opacity: 1; } }
.ui-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .ui-ch { animation: none; opacity: 1; } }
.ui-said-row.still { animation: none; }
.ui-said-row { margin: 0 6px; font: 500 15px/1.4 var(--ui-font); color: var(--ui-ink); text-align: center; text-wrap: balance; overflow-wrap: anywhere; animation: ui-in var(--ui-t) var(--ui-ease) both; }
.ui-said-row.off { animation: ui-out 200ms var(--ui-exit) both; }
.ui-toast.says { width: max-content; max-width: calc(100% - 36px); white-space: normal; text-align: center; text-wrap: balance; line-height: 1.35; border-radius: 22px; }
/* A request known to be waiting stays clear enough to read and breathes at its outline. */
.ui-last-pending { outline: 1px solid rgba(var(--c-rgb), 0.42); outline-offset: -1px; animation: ui-last-pending var(--ui-t-wait) var(--ui-ease-wait) infinite alternate; }
@keyframes ui-last-pending { to { outline-color: rgba(var(--c-rgb), 0.12); } }
.ui-more { justify-content: center; color: var(--ui-ink-3); font-weight: 500; }
.ui-more[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .ui-last-pending { animation: none; } }
/* the first fill, and a fill that cannot be had: the app's own ground and the mark; nothing made up stands in */
.ui-fill { position: absolute; inset: 0; z-index: 90; display: grid; place-content: center; justify-items: center; padding: 0 36px; background: inherit; transition: opacity var(--ui-t) ease, filter var(--ui-t) ease; }
.ui-fill.gone { opacity: 0; filter: blur(var(--ui-blur)); pointer-events: none; }
.ui-fill .ui-mark { width: 44px; height: 44px; opacity: 0; transition: opacity 0.4s ease, filter 0.4s ease; }
.ui-fill.felt .ui-mark { opacity: 1; animation: ui-waits var(--ui-t-wait) var(--ui-ease-wait) 0.4s infinite alternate; }
.ui-fill.unread .ui-mark { animation: none; opacity: 0.5; filter: saturate(0.2); }
.ui-fill p { margin: 18px 0 0; font: 500 15px/1.4 var(--ui-font); color: var(--ui-ink); text-align: center; text-wrap: balance; }
.ui-fill p:empty { display: none; }
.ui-fill .ui-text-act { margin-top: 2px; }
.ui-fill .ui-text-act[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .ui-waits, .ui-waits .end svg, .ui-waits > i::after, .ui-go.ui-waits::after, .ui-drawer.ui-waits .ui-lit, .ui-fill.felt .ui-mark { animation: none; } .ui-go.ui-waits::after { opacity: 0; } }

/* the sign for no connection, in the line and in the toast (RN917, RN919) */
.ui-said p svg.ui-i, .ui-said-row svg.ui-i, .ui-toast svg.ui-i { display: inline-block; width: 15px; height: 15px; margin: 0 6px 0 0; vertical-align: -2.5px; }

/* a drawer's top right may hold its word and one sign beside it (RN1017: a session's drawer leads to the calendar).
   The sign's own edge stands on the drawer's edge; its room to tap reaches past it */
.ui-top-end { flex: none; display: inline-flex; align-items: center; gap: 6px; }
.ui-text-act.ui-sign-act { min-width: var(--ui-tap); padding: 0; justify-content: center; margin-right: -11px; }
.ui-text-act.ui-sign-act svg { width: 22px; height: 22px; stroke-width: 1.8; }

/* the way on, in the line under a setting that did not save (RN1027 to RN1031): the app's own text act, written
   in after the line, with a whole finger's room around it */
.ui-said-go { position: relative; display: inline-block; margin-left: 6px; padding: 0; font: 650 15px/1.4 var(--ui-font); color: var(--ui-accent-ink, var(--ui-accent)); white-space: nowrap; opacity: 0; animation: ui-write 320ms ease forwards; transition: transform 160ms var(--ui-ease); }
.ui-said-go::after { content: ''; position: absolute; inset: -13px -10px; }
.ui-said-go:active { transform: scale(0.94); }
.ui-said-row.still .ui-said-go { animation: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ui-said-go { animation: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) { .ui-toast, .ui-toast.on { transition-duration: 1ms; } }
/* a field whose value does not say what it is carries a symbol at its start (RN1212): a client's district */
.ui-field-sym { position: relative; display: block; flex: 1.2 1 0; min-width: 0; }
.ui-field-sym > svg.ui-i { position: absolute; left: 14px; top: 50%; width: 18px; height: 18px; margin-top: -9px; color: var(--ui-ink-3); pointer-events: none; }
.ui-field-sym > .ui-input { width: 100%; padding-left: 40px; }

/* ── the lighter look (RN1239, 17 Oct 2026) ─────────────────────────────
   The same app without the frosted glass, for a phone that is slow to draw it, or a person who has asked her phone
   for less transparency. It is one app, never a second version: every surface that floated over the screen with a
   blur behind it stands solid in its own colour, and what arrives fades and moves without blurring. The layout, the
   words, the colours and the motion's timing stay as they are.
   Since RN1246 the everyday look keeps its glass only where it shows (the note above .ui-drawer), so this look is a
   safety net. It turns on by itself (ui.js sets data-lite-auto) only when the phone asks for less transparency, never
   from counting frames (RN1251: that count took the blur off his Pixel 10). Whatever floats keeps a solid ground in it
   (operator.css, client.css), so nothing shows through. His hand control "Look on this phone" can hold it on (data-lite="on") or off (data-lite="off"). */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) *,
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) *::before,
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
/* nothing arrives or leaves through a blur; the pointing dims the rest without softening it (ui.js reads the same) */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-root { --ui-blur: 0px; --ui-point-in-filter: none; }
/* a drawer is its own colour all the way through: nothing behind it reads through */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-root { --ui-sheet: rgb(10, 13, 21); }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"]))[data-mode="day"] .phone { --ui-sheet: #fff; }
/* the dimming behind a drawer does the blur's work by depth alone */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-scrim { background: var(--ui-scrim-lite, rgba(2, 5, 12, 0.7)); }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"]))[data-mode="day"] .ui-scrim { --ui-scrim-lite: rgba(236, 240, 242, 0.78); }
/* the toast and the veil behind it are solid enough that no word is read through them */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-toast { background: rgb(22, 28, 40); }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-toast.frost { background: #f4f6fa; }
/* without the blur, the band the toast speaks over is the ground itself, and deep enough to take a large figure whole */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-toast-veil { background: rgb(3, 6, 14); min-height: 110px; }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"]))[data-mode="day"] .ui-toast-veil { background: rgb(246, 249, 249); }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-has-drawer > .ui-toast-veil { background: rgba(10, 13, 21, 0.9); }
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"]))[data-mode="day"] .ui-has-drawer > .ui-toast-veil { background: rgba(255, 255, 255, 0.92); }
/* the search bar's white glass is white */
:root:is([data-lite="on"], [data-lite-auto]:not([data-lite="off"])) .ui-root { --ui-frost: #f4f6fa; }

/* the stand-in that holds the keyboard while a drawer changes (RN1286): never seen, never touched; 16px so Safari does not zoom */
.ui-keys-hold { position: fixed; top: 0; left: 0; width: 1px; height: 1px; padding: 0; border: 0; opacity: 0; font-size: 16px; caret-color: transparent; pointer-events: none; }

/* A line and its one act share one row: the words at the left wrap, the act stands at the end (RN1360, FILTER 4) */
.ui-say { display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: var(--ui-tap); }
.ui-say > :first-child { flex: 1 1 auto; min-width: 0; margin: 0; text-wrap: pretty; }
.ui-say > .ui-text-act { flex: none; margin-right: -4px; }
.ui-say[hidden] { display: none; }
/* A line in a head with its quiet act at the end keeps the head's own rhythm: the act's tap room reaches over the line, never pushes it (RN1360, RN1394) */
.ui-head > .ui-say { min-height: 0; }
.ui-head > .ui-say > .ui-text-act { margin-block: calc((var(--ui-tap) - 1.2em) / -2); }
/* a closed section whose head carries an act at its end while open (Notes: Add note; RN1360) */
.ui-sec.has-side { position: relative; }
.ui-sec.has-side > .side { position: absolute; z-index: 1; top: 0; right: 24px; height: 52px; display: inline-flex; align-items: center; transition: opacity 220ms ease; }
.ui-sec.has-side:not(.open) > .side { opacity: 0; pointer-events: none; }
.ui-sec.has-side.open > button .sum { opacity: 0; }   /* open, the head's end is the act; closed, it is the summary */

/* An empty placeholder never takes a gap (RN1383, RN1394: one rhythm everywhere). A block that a part fills later
   (a swap, a wheel, a summary) is gone from the stack while it holds nothing and stands the moment it is filled.
   Census 26 Oct: W/p3j/gaps/table.json. Grid cells and pushers that hold a place on purpose are left alone. */
.ui-body > div:empty, .ui-swap > div:empty, .area-body > div:empty, .cal-top > div:empty, .pl > div:empty,
.pl-use > div:empty, .g > .ui-chips:empty, .g > .taxis:empty, .ui-head > .ui-title:empty, .ui-tx:empty { display: none; }
.team-hours-links > .say:empty, .perm-end > span:empty, .ui-top-end > [data-corner]:empty, .pol-title-row > .pol-dots:empty,
.pol-booking > .pol-dots:empty, .c-id > .c-name:empty, .s-blk > .s-sub:empty, .branch-calendar-row:empty { display: none; }

/* a field outside a drawer brings the keys: what stands at the page's foot (the owner's dock and what it finds, the client's
   foot search) stands on them, by a move of its own layer only (RN1412; --ui-room from ui.js) */
.dock, .d-found, .r4-dock-search { transition: translate 300ms var(--ui-ease); }
:root[data-room] :is(.dock, .d-found, .r4-dock-search) { translate: 0 calc(-1 * var(--ui-room, 0px)); }

/* A call to look (RN1407 to RN1409, UI.call): its own element. A round mark in the attention colour holds the symbol he
   picked; the count stands in the numeral's weight, the words after it a step quieter, in the ordinary ink. Lit while it
   points. Never a warning triangle. */
.ui-call { display: inline-flex; align-items: center; gap: 8px; min-height: 42px; padding: 0 16px 0 6px; border: 0; border-radius: 999px; white-space: nowrap;
  color: var(--ui-ink); font: 500 13.5px var(--ui-font); letter-spacing: 0.005em;
  background: color-mix(in srgb, var(--ui-warn, #e8c27a) 11%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-warn, #e8c27a) 30%, transparent);
  transition: background-color 260ms ease, box-shadow 260ms ease, transform 160ms var(--ui-ease); }
.ui-call:active { transform: scale(0.96); }
.ui-call[aria-pressed="true"] { background: color-mix(in srgb, var(--ui-warn, #e8c27a) 22%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-warn, #e8c27a) 56%, transparent); }
.ui-call-sym { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; color: #1d1608; background: var(--ui-warn, #e8c27a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), inset 0 -3px 6px -3px rgba(0, 0, 0, 0.28); }
.ui-call-sym > .ui-i { grid-area: 1 / 1; width: 17px; height: 17px; stroke-width: 2; display: none; }
.ui-call-sym > .o-own { display: block; }
:root[data-attnsym] .ui-call-sym > .o-own { display: none; }
:root[data-attnsym="hand"] .ui-call-sym > .o-hand, :root[data-attnsym="person"] .ui-call-sym > .o-person, :root[data-attnsym="ring"] .ui-call-sym > .o-ring,
:root[data-attnsym="dot"] .ui-call-sym > .o-dot, :root[data-attnsym="bell"] .ui-call-sym > .o-bell { display: block; }
.ui-call > b { font: 650 15px var(--ui-font-num, var(--ui-font)); font-variant-numeric: tabular-nums; color: var(--ui-warn, #e8c27a); }
.ui-call > span:not(.ui-call-sym) { color: var(--ui-ink-2); }
/* the count and its words read as one phrase: a word space between them, not the pill's gap */
.ui-call > b + span { margin-left: calc(0.28em - 8px); }
:root[data-mode="day"] .ui-call-sym { color: #fff; }

/* A toast's link shares the sentence baseline; its invisible tap area keeps the touch floor. */
.ui-toast .ui-toast-act { display: inline; position: relative; min-height: 0; padding: 0; line-height: inherit; font: inherit; vertical-align: baseline; white-space: nowrap; }
.ui-toast-act::before { content: ''; position: absolute; width: max(100%, 48px); height: 48px; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.ui-toast-under { visibility: hidden; }
