/* ==========================================================================
   dz.css
   THE HOME MEDICATION CONTAINER, four designs. It replaces Tonight.

   WHY TONIGHT IS GOING. On the deployed home page it renders four numbered
   lines, Build a two hour plan / Schedule a check in / Open craving coach /
   Message support, which are hardcoded on the server, identical for every
   client in every risk band, and are plain divs with no href, no button and no
   handler. Not one of them can be pressed. It is the only container on home
   with no controls at all.

   WHAT REPLACES IT has exactly one job: the next thing you have to do about
   your medicine, and a way to do it without leaving home.

   THE THREE RULES ALL FOUR OBEY.

   1. NO SCORE. There is a run of days kept because people like seeing one, and
      there is no percentage, no compliance figure and no total to fall short
      of. Nothing here divides one number by another. A missed dose says what
      to do next, never what was failed, and it is never red: red on a person's
      own medicine reads as an accusation.
   2. NO PROMISE THE APP CANNOT KEEP. A static page has no service worker and
      there is no push sender, so a reminder cannot wake a phone that is not
      looking at us. Every design says that where it offers the reminder,
      rather than letting somebody find out by missing a dose.
   3. WHAT SOMEBODY ADDS IS THEIRS. The vitamins, the inhaler and the note
      about the bus are on their record and shared with nobody unless they
      choose. Said on the sheet where they type it, not in a settings page.

   Colour: magenta is the action. Teal marks a dose already answered, because
   that is a live positive state. Gold marks one that is late, and late is a
   fact rather than a fault. There is no red on this container anywhere.
   ========================================================================== */

/* HEIGHT IS AUTO BY DEFAULT, AND 100% ONLY IN THE ROW.
   height:100% was here so the card fills its grid cell on home and the footer
   sits at the bottom of it. On the medication PAGE there is no cell to fill,
   and 100% resolved up a chain that ended at the viewport: the card came out
   1000px tall with one medicine on it and 800px of nothing under the rows. A
   card should be as tall as what is in it unless something is asking it to
   match a neighbour. */
.dz { display: flex; flex-direction: column; min-width: 0;
  padding: 26px 28px; border-radius: var(--r-lg); background: var(--raise);
  border: 1px solid var(--hair); }
.row-2 .dz, .row-1 .dz { height: 100%; }
.dz-kick { font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); display: block; }
.dz-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dz-count { font-size: 12px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums; }
.dz-mid { font-family: var(--display); font-size: clamp(21px, 2.4vw, 27px); line-height: 1.2;
  margin: 9px 0 0; }
.dz-sub { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin: 11px 0 0; }
.dz-empty { font-size: 13.5px; line-height: 1.6; color: var(--ink-3); margin: 14px 0 0; }

.dz-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: auto; padding-top: 16px; border-top: 1px solid var(--hair);
  font-size: 12.5px; color: var(--ink-3); }
/* THE SPACE HAS TO SIT ABOVE THE RULE, NOT BELOW IT. The footer's padding-top
   is inside the border, so it does nothing for the gap between the content and
   the line. margin-top:auto pushes the footer down only when the card has
   spare height, and since the height measurement was fixed the card is exactly
   its content, so auto collapses to nothing and the rule sat hard against the
   bottom of the collection pill. The gap belongs to whatever is immediately
   above the footer, whichever element that happens to be on that face. */
/* Same shape, same exclusion. In the empty state the last child is the
   invitation, which is absolutely positioned, so the second-from-last is the
   blurred ghost and a bottom margin on it pushes the shape away from the
   bottom of the card for no reason. */
.dz > *:nth-last-child(2):not(.dz-ghost) { margin-bottom: 22px; }
.dz-foot a { color: var(--secondary-soft); font-weight: 600; text-decoration: none; }
.dz-foot a:hover, .dz-foot a:focus { text-decoration: none; }

/* The collection line. It is the one thing on this container that comes from
   the prescribed side rather than the person's own list, so it is marked as a
   different kind of fact rather than sitting in the same run of rows. */
.dz-collect { display: flex; align-items: flex-start; gap: 9px; margin-top: 16px;
  padding: 11px 13px; border-radius: var(--r-md); background: rgba(0,119,200,.1);
  border: 1px solid rgba(0,119,200,.26); font-size: 13px; line-height: 1.55;
  color: var(--ink-2); }
.dz-collect svg { flex: none; margin-top: 1px; color: var(--cyan-soft); }

/* ---- a dose row --------------------------------------------------------- */
.dz-rows { display: flex; flex-direction: column; margin-top: 16px; }
.dz-row { display: grid; grid-template-columns: 62px minmax(0, 1fr) auto; gap: 14px;
  align-items: center; padding: 12px 0; border-top: 1px solid var(--hair); }
.dz-row:first-child { border-top: 0; }
.dz-time { font-size: 13px; font-weight: 600; color: var(--ink-2);
  font-variant-numeric: tabular-nums; }
.dz-what { min-width: 0; }
.dz-what b { display: block; font-size: 14.5px; font-weight: 600; }
.dz-what span { display: block; font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.dz-row.is-done .dz-time, .dz-row.is-done .dz-what b { color: var(--ink-3); }
.dz-row.is-late .dz-time { color: #E0BC72; }
.dz-done { font-size: 12.5px; font-weight: 600; color: var(--teal-soft); }
.dz-acts { display: flex; gap: 8px; align-items: center; }

/* Both properties on every control, always. A button that sets only one reads
   as unstyled in whichever theme it was not designed in. */
.dz-tick { display: inline-flex; align-items: center; gap: 7px; padding: 8px 13px;
  border-radius: 999px; font-size: 12.5px; font-weight: 600; cursor: pointer;
  background: var(--secondary); color: #fff; border: 1px solid var(--secondary);
  transition: filter .16s var(--ease); }
.dz-tick:hover { filter: brightness(1.08); }
.dz-skip { padding: 8px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  cursor: pointer; background: var(--raise-2); color: var(--ink-3);
  border: 1px solid var(--hair); }
.dz-skip:hover { color: var(--ink-2); }
.dz-tick:focus-visible, .dz-skip:focus-visible { outline: 2px solid var(--secondary-soft);
  outline-offset: 2px; }

/* ==========================================================================
   A, THE NEXT DOSE. One thing, at headline size.
   ========================================================================== */
.dz-big { font-family: var(--display); font-size: clamp(26px, 3.4vw, 38px); line-height: 1.1;
  letter-spacing: -.015em; margin: 10px 0 0; }
.dz-big span { display: block; color: var(--secondary-soft); }
.dz-lead-acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; }

/* ==========================================================================
   C, THE RUN. A shape, deliberately not a number.
   ========================================================================== */
.dz-marks { display: flex; gap: 5px; margin-top: 18px; }
.dz-mark { flex: 1 1 0; min-width: 0; height: 26px; border-radius: 6px;
  background: var(--raise-2); border: 1px solid var(--hair); }
.dz-mark.is-kept { background: var(--teal); border-color: var(--teal); }
.dz-mark.is-today { border-color: var(--secondary); border-width: 2px; }
.dz-nextline { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 18px; padding: 13px 15px; border-radius: var(--r-md);
  background: var(--raise-2); border: 1px solid var(--hair); font-size: 13.5px;
  color: var(--ink-2); flex-wrap: wrap; }
.dz-nextline b { color: var(--ink); }

/* ==========================================================================
   D, THE REMINDER. Times first, and the truth about what they can do.
   ========================================================================== */
.dz-times { display: flex; flex-direction: column; margin-top: 16px; }
.dz-mrow { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 0; border-top: 1px solid var(--hair); flex-wrap: wrap; }
.dz-mrow:first-child { border-top: 0; }
.dz-mname b { display: block; font-size: 14.5px; font-weight: 600; }
.dz-mname span { display: block; font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.dz-chips { display: flex; gap: 7px; flex-wrap: wrap; }
.dz-chip { padding: 7px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  cursor: pointer; background: var(--raise-2); color: var(--ink-2);
  border: 1px solid var(--hair); }
.dz-chip:hover { background: var(--hair); color: var(--ink); }
.dz-chip.is-on { background: var(--secondary); color: #fff; border-color: var(--secondary); }
.dz-chip.is-add { color: var(--secondary-soft); border-style: dashed; }
.dz-chip:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 2px; }

.dz-addmed { display: inline-flex; align-items: center; gap: 8px; margin-top: 16px;
  padding: 11px 16px; border-radius: var(--r-md); font-size: 13.5px; font-weight: 600;
  cursor: pointer; background: var(--raise-2); color: var(--ink); border: 1px dashed var(--hair-2); }
.dz-addmed:hover { background: var(--hair); }

.dz-notify { margin-top: 18px; padding: 14px 16px; border-radius: var(--r-md);
  background: rgba(0,119,200,.09); border: 1px solid rgba(0,119,200,.24); }
.dz-ntop { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dz-ntop b { font-size: 14px; font-family: var(--display); }
.dz-on { font-size: 12.5px; font-weight: 700; color: var(--teal-soft); }
.dz-notify p { margin: 8px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }

/* ==========================================================================
   THE ADD SHEET. Branded, never a native dialog, and never a native select.
   ========================================================================== */
.dz-back { position: fixed; inset: 0; z-index: 80; background: rgba(4,7,14,.6);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
/* WIDER AND TALLER, AND THE BUTTONS ARE PINNED. At 520px and 86vh the form
   ran past the bottom on a laptop and clipped Cancel and Add it: the sheet
   scrolled, so they were reachable, but a control you have to discover by
   scrolling is a control most people will not find. Height alone would not
   have fixed it either, because the form grows when a medicine is picked and
   its strengths appear. So the body scrolls and the actions are stuck to the
   bottom of the sheet, which fits any content at any height. */
.dz-sheet { position: fixed; z-index: 81; left: 50%; bottom: 0; transform: translateX(-50%);
  width: min(640px, 100vw); max-height: 92vh;
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--glass);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--hair-2); border-bottom: 0;
  animation: dzUp .34s var(--spring) both; }
/* The hidden state lives in the `from` keyframe and the resting state is
   visible, so a browser that never runs the animation still shows the sheet. */
@keyframes dzUp { from { transform: translate(-50%, 22px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .dz-sheet { animation: none; } }

.dz-shd { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 20px 22px 6px; }
.dz-shd h4 { margin: 0; font-family: var(--display); font-size: 19px; }
.dz-x { background: none; border: 0; color: var(--ink-3); cursor: pointer; padding: 4px;
  line-height: 0; }
.dz-x:hover { color: var(--ink); }
.dz-sbody { padding: 8px 24px 20px; display: flex; flex-direction: column; gap: 15px;
  overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.dz-f { display: flex; flex-direction: column; gap: 7px; }
.dz-f > span { font-size: 12px; font-weight: 600; color: var(--ink-3); }
.dz-f input { width: 100%; padding: 11px 13px; border-radius: var(--r-md);
  background: var(--raise); color: var(--ink); border: 1px solid var(--hair);
  font: inherit; font-size: 14.5px; }
.dz-f input:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 1px; }
.dz-fine { margin: 0; font-size: 12px; line-height: 1.6; color: var(--ink-3); }
/* Stuck to the foot of the sheet, inside the scroller, so it is on screen
   whatever the form is doing above it. The negative margins take it back out
   to the sheet's own edges so its rule spans the full width, and the safe
   area inset keeps it off a phone's home indicator. */
/* ONE SURFACE. The actions are a flex sibling of the scroller rather than a
   sticky child of it, so they sit on the sheet's own glass and carry NO fill
   of their own. The sticky version needed an opaque background, because a
   sticky element floats over the content beneath it, and an opaque panel on a
   glass sheet is a grey strip that reads as a different material bolted on the
   bottom. Nothing here can scroll underneath, so nothing needs covering. */
.dz-sacts { flex: none; display: flex; justify-content: flex-end; gap: 10px;
  padding: 16px 24px calc(20px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--hair); background: transparent; }

/* ==========================================================================
   THE CONSOLE.
   ========================================================================== */
.dz-console { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 13px 15px; border-radius: var(--r-md); background: var(--raise);
  border: 1px dashed var(--hair-2); margin-bottom: 20px; }
.dz-console b { font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-3); margin-right: 4px; }
.dz-cbtn { padding: 7px 13px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  background: var(--raise-2); color: var(--ink-2); border: 1px solid var(--hair);
  cursor: pointer; }
.dz-cbtn:hover { background: var(--hair); color: var(--ink); }

/* ==========================================================================
   E, THE PAIR THAT TURNS OVER.
   A and B in one container, changing face on their own every thirty seconds.
   ========================================================================== */
/* THE CARD CHROME MOVES OUT TO THE CAROUSEL, so the pips sit INSIDE the
   container rather than floating on the page underneath it. They belong to the
   pair, not to either face, and a switcher that sits outside the box it
   switches reads as page furniture rather than part of the card. The faces
   keep their layout and give up their border, padding and fill, because a card
   inside a card is a border inside a border. */
.dz-e { padding: 22px 24px; background: var(--raise); border: 1px solid var(--hair); }
.dz-e-stage { position: relative; flex: 1 1 auto; min-height: 0; }
.dz-face > .dz.is-face { padding: 0; background: transparent; border: 0; }

/* Both faces are laid on top of each other and the stage is pinned to the
   taller one, measured after they render. Two faces of different heights
   turning over makes the whole page jump, and on home that moves every
   container underneath it. */
.dz-face { position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transition: opacity .5s var(--ease); }
.dz-face.is-on { position: relative; opacity: 1; visibility: visible; }
.dz-face > .dz.is-face { height: 100%; }
@media (prefers-reduced-motion: reduce) {
  .dz-face { transition: none; }
}

/* NO RULE OF ITS OWN. The face already ends with its footer's border, so a
   second line under the pips put two hairlines within fourteen pixels of each
   other, which reads as a mistake rather than as a division. */
.dz-pips { display: flex; justify-content: center; gap: 8px; margin-top: 14px;
  flex: none; }
.dz-pip { width: 30px; height: 5px; padding: 0; border-radius: 999px; cursor: pointer;
  background: var(--hair-2); border: 0;
  transition: background .25s var(--ease), width .25s var(--ease); }
.dz-pip:hover { background: var(--ink-3); }
.dz-pip.is-on { background: var(--secondary); width: 44px; }
.dz-pip:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 3px; }

/* A footer button that reads as a link. It sets both colour and background,
   because a bare background:none button inherits the user agent's grey in one
   of the two themes. */
.dz-link { background: transparent; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--secondary-soft); }
.dz-link:hover { color: var(--secondary); }
.dz-link:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 3px;
  border-radius: 4px; }

/* ---- the add control, on every face, at the top -------------------------
   It was a text link in the footer, which on the day face sits below however
   many doses there are: on a busy day the way to add a medicine was the last
   thing on the card. Beside the eyebrow it is in the same place on every face
   and never moves as the content grows. */
.dz-hd-r { display: inline-flex; align-items: center; gap: 12px; }
.dz-add { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px 6px 9px;
  border-radius: 999px; font-size: 12px; font-weight: 700; cursor: pointer;
  background: rgba(181,37,85,.16); color: var(--secondary-soft);
  border: 1px solid rgba(181,37,85,.36); white-space: nowrap;
  transition: background .16s var(--ease), color .16s var(--ease); }
.dz-add:hover { background: var(--secondary); color: #fff; border-color: var(--secondary); }
.dz-add:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 2px; }

/* The rest of today, folded. A home container is not a page. */
.dz-more { display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; margin-top: 4px; padding: 11px 0; border-radius: var(--r-md);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
  background: var(--raise-2); color: var(--ink-2); border: 1px solid var(--hair); }
.dz-more:hover { background: var(--hair); color: var(--ink); }
.dz-more:focus-visible { outline: 2px solid var(--secondary-soft); outline-offset: 2px; }

/* The carousel wrapper must NOT take .dz's height:100%. It is a frame around
   two faces, and letting it stretch to the grid row is the other half of the
   circular measurement described in dz-core's fit(). */
.dz-e { height: auto; }

/* The skip control is an icon, not a second labelled pill. Two pills could not
   fit the third grid column at the container's real width, so they wrapped and
   turned every dose row from 57px into 107px, which is most of the reason the
   whole thing was too tall. The label survives as aria-label and title. */
.dz-skip { display: inline-grid; place-items: center; width: 34px; height: 34px;
  padding: 0; border-radius: 50%; }

/* ---- the medicine typeahead ---------------------------------------------
   A built combobox, not a native datalist. This host does not use system UI
   anywhere, and a datalist renders differently in every browser and cannot be
   styled at all. The list is a help and never a gate: whatever is typed is
   what gets saved, matched or not, because a box that refuses somebody's
   medicine is worse than no box, they stop entering it, and the reminder they
   wanted stops working with it. */
.dz-combo { position: relative; }
.dz-cwrap { position: relative; }
.dz-hint { margin: 7px 0 0; font-size: 11.5px; line-height: 1.55; color: var(--ink-3); }
.dz-list { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 3;
  max-height: 258px; overflow: auto; border-radius: var(--r-md);
  /* OPAQUE, not glass. A translucent list over the hint paragraph underneath
     let both sets of words show through each other, which is unreadable and
     looks like a rendering fault. Built from tokens so it still themes: the
     canvas colour with the card fill laid over it. */
  background-color: var(--canvas);
  background-image: linear-gradient(var(--raise-2), var(--raise-2));
  border: 1px solid var(--hair-2); box-shadow: 0 16px 40px rgba(0,0,0,.5); }
.dz-list[hidden] { display: none; }
.dz-opt { padding: 11px 14px; cursor: pointer; border-top: 1px solid var(--hair); }
.dz-opt:first-child { border-top: 0; }
.dz-opt b { display: block; font-size: 14px; font-weight: 600; }
.dz-opt span { display: block; font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.dz-opt:hover, .dz-opt.is-on { background: rgba(181,37,85,.2); }
.dz-opt.is-on b { color: var(--secondary-soft); }

.dz-strengths { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dz-strengths[hidden] { display: none; }
.dz-slab { font-size: 11.5px; font-weight: 600; color: var(--ink-3); margin-right: 2px; }

/* A write that is away, and one that did not land. Neither may be silent on a
   medication record: a tick that paints and fails quietly is somebody
   believing they logged a dose they did not. */
.dz-tick.is-sending, .dz-skip.is-sending { opacity: .55; cursor: default; }
.dz-nosave { margin: 8px 0 0; font-size: 12px; line-height: 1.55; color: #E0BC72;
  grid-column: 1 / -1; }

/* ==========================================================================
   THE EMPTY STATE. The container appears even with nothing on the list and no
   prescribing, because most people on the caseload are not on a substitute
   prescription and every one of them takes something.

   WHAT IS BEHIND THE OVERLAY IS A SHAPE, NOT A RECORD: blurred bars with no
   words in them. A blurred list of plausible medicine names would still be a
   list of medicines somebody does not take, and blur is not a safety
   property, it is a few pixels of CSS away from being read. So there is
   nothing there to read.
   ========================================================================== */
.dz-empty-state { position: relative; overflow: hidden; }

.dz-ghost { margin-top: 14px; filter: blur(4px); opacity: 1; pointer-events: none;
  user-select: none; }
.dz-sk { display: grid; grid-template-columns: 52px minmax(0, 1fr) 92px; gap: 14px;
  align-items: center; padding: 13px 0; border-top: 1px solid var(--hair); }
.dz-sk:first-child { border-top: 0; }
/* Bright enough to survive a 4px blur AND the scrim over it. At the card
   fill's own opacity the bars were invisible under both, so the container
   just looked half empty, which is the opposite of showing somebody what it
   becomes. */
.dz-sk span { display: block; height: 12px; border-radius: 999px; background: var(--hair-2); }
.dz-sk .b { background: none; display: flex; flex-direction: column; gap: 8px; }
.dz-sk .b i { display: block; height: 12px; border-radius: 999px; background: var(--hair-2); }
.dz-sk .b i.s { height: 10px; width: 58%; background: var(--hair); }
.dz-sk .c { height: 32px; border-radius: 999px; background: rgba(181,37,85,.5); }

/* The invitation sits over the shape. It is the only thing here that can be
   read or reached. */
/* A SCRIM, NOT A LID. The first version faded to solid canvas by a third of
   the way down, so the blurred shape behind it was invisible and the card
   simply looked half empty. The point of the shape is that somebody can see
   what this becomes. Glass plus the shell's own blur keeps the words fully
   legible while the rows stay visible underneath. */
.dz-invite { position: absolute; left: 0; right: 0; bottom: 0; top: 62px;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center; gap: 10px; padding: 0 28px 26px;
  /* Lighter at the top so the shape reads, heavier behind the words so they
     stay legible. */
  background: linear-gradient(to bottom, rgba(8,12,21,.34), rgba(8,12,21,.9) 60%);
  backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px); }
.dz-invite h3 { margin: 0; font-family: var(--display); font-size: 20px; }
.dz-invite p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-2);
  max-width: 42ch; }
.dz-invite .btn { margin-top: 6px; }

/* ---- the add rail, pulled up from the bottom ----------------------------
   The same grab handle the rest of this host puts on its sheets, so the
   affordance is one people have already met on the crisis page and the coach.
   The handle and the title bar are the drag surface; the body is not, because
   the form is taller than a phone screen and a drag started there would fight
   the body's own scroll every time. */
.dz-grab { padding: 10px 0 2px; cursor: grab; touch-action: none; }
.dz-grab span { display: block; width: 38px; height: 5px; margin: 0 auto;
  border-radius: 3px; background: var(--ink-3); opacity: .5; }
.dz-sheet.is-dragging .dz-grab { cursor: grabbing; }
.dz-sheet.is-dragging { transition: none; }
.dz-shd { cursor: grab; touch-action: none; user-select: none; }
.dz-sheet.is-dragging .dz-shd { cursor: grabbing; }
/* The head keeps its own cursor on the things inside it that are not the
   drag surface. */
.dz-shd h4 { cursor: inherit; }
.dz-x { cursor: pointer; touch-action: auto; }

/* On a wide screen it is still a sheet rather than a card floating in the
   middle, because the pull gesture only makes sense against an edge. */
@media (min-width: 640px) {
  .dz-sheet { bottom: 0; border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-bottom: 0; }
}

/* ---- KEEP THE CONTROLS CLEAR OF THE FLOATING TAB BAR ---------------------
   Found on a phone, and it was real rather than a harness artifact: scrolling
   the container into view parked "Add a medicine" at y803 in an 844 viewport,
   while the floating tab bar starts at y765. elementFromPoint at the button's
   own centre returned a tab link, so tapping Add navigated to /goals.

   The page reserves 170px at its foot for the bar, which protects the END of
   the page and does nothing for a mid-page element that a scrollIntoView, or
   a person's thumb, happens to leave down there. scroll-margin keeps any
   programmatic scroll from stopping with the container under the bar. */
.dz, .dz-e, .dz-e-stage, #dzLive, .dz-live { scroll-margin-bottom: 150px; }
/* AND ON THE CONTROLS THEMSELVES, which is the part that actually mattered.
   scroll-margin applies to the element being scrolled TO, and what gets
   scrolled to is a button: by the browser when it takes focus from the
   keyboard, by assistive technology, and by any code that calls
   scrollIntoView on it. Putting it only on the container left every one of
   those cases parking the button under the bar. */
.dz-add, .dz-tick, .dz-skip, .dz-more, .dz-pip, .dz-link,
.dz-invite .btn, .dz-lead-acts .btn, .dz-chip, .dz-addmed {
  scroll-margin-bottom: 150px; scroll-margin-top: 90px; }

/* ---- how often, and when ------------------------------------------------ */
.dz-routines .dz-chip.is-on { background: var(--secondary); color: #fff;
  border-color: var(--secondary); }
.dz-times-edit { display: flex; flex-direction: column; gap: 8px; }
.dz-trow { display: flex; align-items: center; gap: 8px; }
.dz-trow input[type="time"] { flex: 1 1 auto; padding: 11px 13px; border-radius: var(--r-md);
  background: var(--raise); color: var(--ink); border: 1px solid var(--hair);
  font: inherit; font-size: 14.5px; }
.dz-trow input[type="time"]:focus-visible { outline: 2px solid var(--secondary-soft);
  outline-offset: 1px; }
.dz-tdel { flex: none; display: inline-grid; place-items: center; width: 36px; height: 36px;
  border-radius: 50%; cursor: pointer; background: var(--raise-2); color: var(--ink-3);
  border: 1px solid var(--hair); }
.dz-tdel:hover { color: var(--ink); background: var(--hair); }
.dz-addtime { align-self: flex-start; display: inline-flex; align-items: center; gap: 7px;
  margin-top: 9px; padding: 8px 13px; border-radius: 999px; font-size: 12.5px;
  font-weight: 600; cursor: pointer; background: var(--raise-2); color: var(--ink-2);
  border: 1px dashed var(--hair-2); }
.dz-addtime:hover { background: var(--hair); color: var(--ink); }

/* THE SENTENCE. A routine built out of chips and clock fields cannot be
   checked by looking at the chips, so it is said back in the words somebody
   would use. It is the only way to catch "every Monday at 8pm" when they
   meant every day. */
.dz-when { margin: 2px 0 0; padding: 11px 13px; border-radius: var(--r-md);
  background: rgba(0,119,200,.1); border: 1px solid rgba(0,119,200,.24);
  font-size: 13.5px; line-height: 1.5; color: var(--ink); font-weight: 600; }

/* A row that has lost one of its two cells becomes a row of one, rather than
   leaving the survivor pinned in its column with a hole beside it. */
.row-2.is-solo { grid-template-columns: minmax(0, 1fr); }
