/* Components. Flat by design: depth is a hairline on white over warm paper.
   The only shadow in the product is the sheet, because on touch a bordered sheet
   with no shadow reads as part of the board underneath it. */

/* ------------------------------------------------------------ pictures */
.plate { color: var(--c-mark); flex: none; }
[data-on-forest] .plate, .greenbar .plate { color: var(--c-on-forest); }

/* ------------------------------------------------------------ focus, on a fill
   A RING HAS TO BE VISIBLE ON THE THING IT IS AROUND. base.css draws every focus
   ring in --c-mark, which is deep forest on a light surface, and the four loudest
   controls in the product are FILLED with that same forest: the welded green bar,
   the full width act, a ladder's fix pill and the Undo key on the dark toast. The
   ring was landing at about 1:1 on all four, so a keyboard, a switch or a head
   pointer walked the product's main acts with no indicator at all. The ink that
   already sits on each fill is the ring on each fill. */
.greenbar .gb-btn:focus-visible,
.big-act:focus-visible,
.ladder-fix:focus-visible { outline-color: var(--c-on-forest); }
/* The bar is welded to the bottom edge, so a ring 3px OUTSIDE it is off the glass. */
.greenbar .gb-btn:focus-visible { outline-offset: -5px; }
.big-act[data-tone="quiet"]:focus-visible { outline-color: var(--c-mark); }
.big-act[data-tone="red"]:focus-visible { outline-color: var(--c-paper); }
.toast-undo:focus-visible { outline-color: var(--c-on-toast); }
.chip-act:focus-visible, .quiet-act:focus-visible { outline-color: var(--c-mark); }

/* ------------------------------------------------------------ shapes */
.shape { display: inline-flex; flex: none; line-height: 0; }
.shape svg { fill: currentColor; }
.shape[data-state="record"] { color: var(--c-ink50); }
.shape[data-state="start"]  { color: var(--c-leaf); }
.shape[data-state="due"]    { color: var(--c-amber); }
/* THE BAR IS INK, NOT RED. CLAUDE.md: red exists in three places only, blanking
   the TV, removing a person, and no prescriber on site while somebody is being
   watched. Past the mark is none of those, and a treatment board with a red bar
   on the chair that is simply past two hours spends the loudest colour in the
   product on the most ordinary event in the room. The bar shape plus the word
   'Over' carries it. */
.shape[data-state="stop"]   { color: var(--c-ink); }
/* Ink on a forest fill is about 1.1 to 1: one shade off the thing it sits on.
   .plate has carried the on-forest rule since a call sheet came out ink on
   forest; the shapes never got it, and the stop bar is the one that collides,
   because the other four are already a green, an amber or the mark. Same rule,
   same token, and it is the fill that decides, so nothing on a card moves. */
[data-on-forest] .shape[data-state="stop"],
.greenbar .shape[data-state="stop"],
.big-act .shape[data-state="stop"] { color: var(--c-on-forest); }
.shape[data-state="done"]   { color: var(--c-mark); }

.shapecard { display: grid; gap: var(--s3); grid-template-columns: repeat(5, minmax(0, 1fr)); }
.shapecard > div { display: grid; justify-items: center; gap: var(--s2); text-align: center; }
.shapecard .shape svg { width: 26px; height: 26px; }
.shapecard b { font-size: var(--t-label); font-weight: 600; }
.shapecard span { font-size: var(--t-fine); color: var(--c-ink70); }

/* ------------------------------------------------------------ tiles */
.tilepad {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
@media (min-width: 768px) {
  .tilepad { grid-template-columns: repeat(3, var(--tile)); justify-content: start; }
}

.tile {
  position: relative; display: grid; align-content: center; justify-items: center;
  gap: var(--s2); padding: var(--s4);
  min-width: var(--touch); min-height: var(--touch);
  background: var(--c-card); color: var(--c-ink);
  border: var(--hair); border-radius: var(--r-tile);
  text-align: center; transition: border-color var(--d-fast) var(--e-out), background var(--d-fast) var(--e-out);
}
@media (min-width: 768px) { .tile { width: var(--tile); height: var(--tile); } }
.tile:hover:not([aria-disabled="true"]) { border-color: color-mix(in srgb, var(--c-mark) 32%, var(--c-hair)); }
.tile-word { font-size: var(--t-label); font-weight: 700; letter-spacing: .005em; line-height: 1.2; }
.tile-fact { font-size: var(--t-fine); color: var(--c-ink70); }
.tile-shape { position: absolute; top: 10px; right: 10px; }
.tile-pic { line-height: 0; }

/* A tile whose choices are all the same idea puts what tells them apart where
   the picture would be: a numeral, a weekday, a dose. Four identical calendars
   in a 2x2 grid are four pictures carrying nothing, and there are only 24 to
   spend. Same box, same word underneath, same 180pt target. */
.tile[data-big="yes"] .tile-pic { line-height: 1; }
.tile-big {
  display: block; font-size: clamp(2.25rem, 7vw, 3.25rem); font-weight: 600;
  font-family: var(--font-serif); line-height: 1; letter-spacing: -.02em;
  color: var(--c-mark);
}
.tile-big.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: 500; }
/* ONE SIZE PER LENGTH. A numeral and a phrase cannot share a font size: '7'
   wants to be enormous and 'Doctor one-pager' at that size runs straight off a
   180pt tile. Two lanes had each written their own font-size over this one
   (the clinician's relation row, the outreach piece pad), which is how one
   product ends up with three sizes of the same control. */
.tile[data-biglen="word"] .tile-big { font-size: clamp(1.4rem, 3.2vw, 1.85rem); }
.tile[data-biglen="phrase"] .tile-big {
  font-size: clamp(1.05rem, 2.4vw, 1.3rem); line-height: 1.1; letter-spacing: -.01em;
  overflow-wrap: anywhere; text-wrap: balance;
}
.tile[data-lit="yes"] .tile-big { color: var(--c-mark); }
.tile[aria-disabled="true"] .tile-big { color: var(--c-ink70); }

.tile[data-lit="yes"] {
  border-color: var(--c-mark);
  box-shadow: var(--glow-lit);
}
.tile[data-lit="yes"] .tile-word { color: var(--c-mark); }
/* A blocked tile keeps its picture and its word and stays tappable, because the tap is
   how it gets to say why. aria-disabled, not [disabled]: a disabled button swallows the
   event, so the block haptic and the ladder would never fire. */
.tile[aria-disabled="true"] {
  background: var(--c-mist); color: var(--c-ink70); cursor: not-allowed;
  border-color: var(--c-hair);
}
.tile[aria-disabled="true"] .plate { color: var(--c-ink70); }
.tile:active:not([aria-disabled="true"]) { background: var(--c-mist); }

/* ------------------------------------------------------------ the green bar */

/* THE ROOM THE WELDED BAR TAKES, IN ONE NUMBER.
   Everything that ends at the bottom edge of the glass reads this and nothing
   else: the screen, the tab row, a toast, a sheet's scroller. --bar-h-real is
   what the bar measured itself to be (components.js publishes it on every set),
   the token is the floor before the first paint, and the home indicator is
   added HERE so no rule has to remember it. A control under the bar is a
   control nobody can press, and every time it happened it was a second place
   that had typed 88px into a stylesheet. */
:root {
  --bar-room: calc(var(--bar-h-real, var(--bar-h)) + env(safe-area-inset-bottom, 0px));
}

.greenbar {
  position: fixed; inset: auto 0 0 0; z-index: 40;
  background: var(--c-forest);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.greenbar[data-on="no"] { display: none; }
/* A SHEET THAT CARRIES ITS OWN ACT TAKES THE SHELL BAR AWAY.
   A sheet is 760px of glass in the middle of an iPad, so the green bar behind
   it is still lit at both ends, still says an act, and is under the scrim: the
   tap it invites shuts the sheet and throws the work away. Two welded acts is
   also two main actions on one screen. components.js raises this the moment a
   sheet holds a full width act and drops it when the last one closes. */
body[data-sheet-act="yes"] .greenbar { display: none; }
/* THE BAR GROWS TO WHAT IT SAYS. It was a fixed 88px holding 89px of act, fact
   and why, so on a 390pt phone the last line was cut in half at the bottom edge
   of the glass ("...and the clock is runni"). A welded bar may not clip the one
   sentence it exists to say: 88px is the floor, not the ceiling, the word wraps
   to two lines and no further, and the safe area is the .greenbar's own padding
   underneath so a real home indicator eats the padding and not the why line. */
.gb-btn {
  display: flex; align-items: center; gap: var(--s4);
  width: 100%; min-height: var(--bar-h);
  padding-block: var(--s3);
  padding-inline: max(var(--gutter), env(safe-area-inset-left, 0px)) var(--gutter);
  color: var(--c-on-forest); text-align: left;
}
.gb-pic { line-height: 0; flex: none; }
.gb-text { display: grid; gap: 2px; min-width: 0; }
.gb-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--s3); min-width: 0; }
.gb-word {
  font-family: var(--font-serif); font-size: clamp(1.25rem, 4.4vw, 1.5rem); font-weight: 600;
  line-height: 1.12;
  /* THE ACT WINS. flex-basis auto with NO min-width override, so the word may wrap
     but a flex row can never squeeze it below its own content. It wraps to a second
     line before it ever truncates, because half an instruction is worse than none. */
  flex: 1 1 auto;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
/* The fact is what you need to DO the act, and it is useless with the act cut in
   half above it. It gives way first: it shrinks, then it clips, and when
   barFactPlacement() says it cannot ride beside the word it takes its own line. */
.gb-fact {
  font-size: var(--t-label); color: color-mix(in srgb, var(--c-on-forest) 78%, transparent);
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gb-line[data-fact="below"] .gb-fact { flex-basis: 100%; white-space: normal; }
.gb-why { font-size: var(--t-fine); color: color-mix(in srgb, var(--c-on-forest) 70%, transparent); }
.gb-btn:active { background: color-mix(in srgb, var(--c-on-forest) 8%, var(--c-forest)); }

/* ------------------------------------------------------------ the ladder */
.ladder { list-style: none; padding: 0; display: grid; gap: var(--s2); }
.ladder-row {
  display: flex; align-items: center; gap: var(--s3);
  min-height: 64px; padding: var(--s3) var(--s4);
  background: var(--c-card); border: var(--hair); border-radius: 12px;
  border-left: 2px solid var(--c-hair);
}
.ladder-row[data-state="done"] {
  background: transparent; border-color: transparent;
  border-left: 2px solid var(--c-leaf);
  color: var(--c-ink70);
}
.ladder-row[data-state="done"] .plate { color: var(--c-ink70); }
/* The missing rule is the one thing on the row that says "this is what is left", so it
   carries the amber that clears AA, not the fill amber that reads at 4.4:1. */
.ladder-row[data-state="missing"] { border-left-color: var(--c-amber-text); background: var(--c-card); }
/* Started, and in somebody else's hands: paperwork that is on the patient iPad
   right now. Not amber, because there is nothing for the desk to do; not the
   quiet done row either, because nobody has signed anything yet. */
.ladder-row[data-state="waiting"] { border-left-color: var(--c-info); background: var(--c-card); }
.ladder-row[data-state="waiting"] .ladder-word { font-weight: 600; }
.ladder-word { flex: 1; font-size: var(--t-body); font-weight: 600; }
.ladder-row[data-state="done"] .ladder-word { font-weight: 400; }
.ladder-fix {
  flex: none; min-height: var(--touch-min); padding: 10px 18px;
  border-radius: var(--r-pill); background: var(--c-forest); color: var(--c-on-forest);
  /* The outline is invisible over the forest fill in light and is the only thing that
     separates the pill from a dark card in room mode. */
  border: 1.5px solid var(--c-mark);
  font-size: var(--t-label); font-weight: 700;
}
.ladder-fix:active { background: color-mix(in srgb, var(--c-on-forest) 14%, var(--c-forest)); }
/* A WAITING rung is not asking for anything: the paperwork is on the patient
   iPad right now and the desk has nothing to do about it. Its fix is an escape
   hatch ("They did it on paper"), not the act, so it is quiet. Two forest
   fills on one sheet is two main actions, and the loud one has to be the act
   the sheet exists for. */
.ladder-row[data-state="waiting"] .ladder-fix {
  background: var(--c-card); color: var(--c-mark); border-color: var(--c-hair);
}
.ladder-row[data-state="waiting"] .ladder-fix:active { background: var(--c-mist); }
/* A rung and its fix do not fit on one line of a phone. "Nobody has asked about
   sedating medicines today." beside a pill wraps to four lines of two words, and
   the pill ends up a thumb wide. Under 520 the sentence takes the width it needs
   and the fix is a full width target under it. */
@media (max-width: 519px) {
  .ladder-row { flex-wrap: wrap; row-gap: var(--s2); padding-block: var(--s3); }
  .ladder-word { flex: 1 1 0; min-width: 0; }   /* 1 1 0, not auto: a long sentence wraps beside its picture and star instead of orphaning them on their own lines */
  .ladder-fix { flex: 1 0 100%; width: 100%; }
}

/* ------------------------------------------------------------ sheet */
/* THE ACT STAYS ABOVE THE KEYBOARD. A sheet is fixed, and iOS does not move a
   fixed element when the keyboard comes up: it shrinks the visual viewport and
   leaves the layout one alone, so the one button the sheet exists for ends up
   behind the keys somebody is typing on. design/keyboard.js publishes
   --keyboard-h from visualViewport; the sheet simply stands on top of it. */
.sheet {
  position: fixed; inset: 0; z-index: 60; display: grid; align-items: end;
  padding-bottom: var(--keyboard-h, 0px);
}
.sheet[data-open="no"] { display: none; }
.sheet-scrim { position: absolute; inset: 0; background: var(--scrim); }
.sheet-panel {
  position: relative; width: min(760px, 100%); margin-inline: auto;
  max-height: min(88vh, calc(100dvh - var(--keyboard-h, 0px) - var(--s5)));
  overflow: hidden;
  /* grip, head, the scroller, and the act welded to the foot. The act is its
     own row OUTSIDE the scroller, so it cannot sit on top of the last thing in
     the body: a welded act that overlaps what it is about is how a ladder's one
     unmet rung ended up under the one bar saying everything was ready. */
  display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto;
  background: var(--c-card); border-radius: 20px 20px 0 0;
  box-shadow: var(--sheet-shadow);
  /* The bottom padding belongs to the BODY now, because the body is the scroller
     and the act welded to the foot of a sheet measures itself against it. */
  padding: var(--s3) var(--s5) 0;
}
.sheet-grip { width: 44px; height: 4px; border-radius: 999px; background: var(--c-hair); margin: 0 auto var(--s3); }
/* One hairline, the product's only depth device, because the head does not move and
   the body does: without it a scrolled sheet clips a line of text half a glyph under
   the title and reads as a broken screen rather than as a header with more below. */
.sheet-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding-bottom: var(--s3); border-bottom: var(--hair); margin-bottom: var(--s4);
}
.sheet-title { font-size: var(--t-h3); }
/* The body scrolls and the head above it does not. A sheet that scrolls whole carries
   its own Close button off the top of the glass, and then the way out of a long sheet
   is a guess at where the scrim starts. The body keeps the side and bottom padding the
   panel used to hold, so everything that bled to the panel's edges still does. */
/* The scroller ends with room for whatever is welded below it. --sheet-foot is
   what components.js measured a sheet's own act to be (0 when it has none), so
   the last row of a long sheet can always be scrolled out from under it. */
.sheet-body {
  min-height: 0; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch;
  margin-inline: calc(var(--s5) * -1);
  padding: 0 var(--s5) calc(var(--sheet-foot, 0px) + var(--s6) + env(safe-area-inset-bottom, 0px));
}
/* The act welded to the foot of a sheet: the green bar's twin, in the panel and
   not in the scroller. It bleeds to the panel's edges and takes the home
   indicator as its own padding, exactly as the bar does. */
.sheet-foot {
  margin-inline: calc(var(--s5) * -1);
  border-radius: 0 0 20px 20px;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.sheet-foot:empty { display: none; }
/* A printed sheet is one page, not a scrollport with a hidden second half. */
@media print { .sheet-body { overflow: visible; max-height: none; } }
.sheet-close {
  min-height: var(--touch-min); padding: 8px 16px; border-radius: var(--r-pill);
  border: 1.5px solid var(--c-hair); font-size: var(--t-label); font-weight: 600; color: var(--c-ink70);
}

/* ------------------------------------------------------------ the full width act
   The act inside a sheet, where the green bar cannot reach. It was written out
   three times, in three lane stylesheets, and the three had drifted: the desk's
   was centred serif with no room for a fact, the operations one was left set
   sans with one, and a phone got whichever stylesheet happened to load last.
   One definition, here, and a lane only refines it. */
.big-act {
  display: flex; align-items: center; gap: var(--s4);
  width: 100%; min-height: var(--touch); padding: var(--s3) var(--s5);
  background: var(--c-forest); color: var(--c-on-forest);
  border: 1.5px solid var(--c-mark); border-radius: var(--r-tile);
  font-size: var(--t-lead); font-weight: 700; text-align: left;
  /* One of these is an <a> (a tel: link), and a browser underline on it makes
     one act in the stack look unlike every other act in the same stack. */
  text-decoration: none;
  /* THE LABEL WRAPS INSIDE THE GLASS. "Remove Marnie from Practice Clinic" is
     34 characters on a 390pt phone: it has to take a second line and grow the
     button, never run off the end of it. */
  overflow-wrap: anywhere;
}
.big-act > span { min-width: 0; }
/* A picture's one solid accent is leaf green, which all but disappears on a
   forest fill, so every act that fills with forest lifts the accent for itself
   rather than changing what leaf means anywhere else. */
.big-act { --c-leaf: color-mix(in srgb, var(--c-on-forest) 72%, transparent); }
.big-act .plate { color: var(--c-on-forest); }
.big-act[data-tone="quiet"] {
  background: var(--c-card); color: var(--c-ink);
  border-color: var(--c-hair); border-style: solid;
  --c-leaf: var(--c-mark);
}
.big-act[data-tone="quiet"] .plate { color: var(--c-mark); }
/* Red is one of three places in the whole product, so it has to be the only
   colour in it: leaf on alert is a muddy green dot on a red button. */
.big-act[data-tone="red"] {
  background: var(--c-alert); border-color: var(--c-alert); color: var(--c-paper);
  --c-leaf: var(--c-paper);
}
.big-act[data-tone="red"] .plate { color: var(--c-paper); }
.big-act[aria-disabled="true"] { opacity: .55; }
.big-act:active { filter: brightness(1.08); }
.big-act .big-act-fact { margin-left: auto; font-size: var(--t-fine); font-weight: 400; opacity: .82; }
/* A word and its fact will not sit side by side on a phone, so the fact goes
   under the word instead of squeezing it to one syllable a line.
   The class used to be doubled here to beat a second copy of .big-act in
   web/screens/ops/lane.css, which is appended to the head at runtime. That copy
   is gone, so this is one class again. */
@media (max-width: 599px) {
  .big-act {
    display: grid; grid-template-columns: 34px minmax(0, 1fr);
    align-items: center; gap: 2px var(--s3); padding: var(--s3) var(--s4);
  }
  .big-act:not(:has(.plate)) { grid-template-columns: minmax(0, 1fr); }
  .big-act .big-act-fact { grid-column: -2; margin-left: 0; }
}
.act-stack { display: grid; gap: var(--s3); }

/* ------------------------------------------------------------ toasts
   Undo is a control, so it obeys the same rule as everything else: it sits on
   top of the room the bar really takes, never on top of the 88px the token
   guesses. A two line act grew the bar to 114 and put Undo inside it. */
.toasts {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px));
  z-index: 70; display: grid; gap: var(--s2); width: min(520px, calc(100% - 2 * var(--gutter)));
}
body[data-greenbar="on"] .toasts { bottom: calc(var(--bar-room) + var(--s4)); }
.toast {
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s3) var(--s3) var(--s3) var(--s4);
  background: var(--c-toast); color: var(--c-on-toast);
  border-radius: 14px; font-size: var(--t-label);
}
.toast-word { font-weight: 600; }
.toast-undo {
  min-height: var(--touch-min); padding: 8px 18px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--c-on-toast) 16%, transparent);
  color: var(--c-on-toast); font-weight: 700;
}
.toast-bar {
  position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: var(--c-toast-rule); transform-origin: left center; transform: scaleX(1);
}

/* ------------------------------------------------------------ PIN pad
   Six digits is the honest cost of a shared iPad, so the pad is the whole screen:
   one centred column, the face of the person whose code this is at the top, big dots,
   and keys a gloved thumb cannot miss. */
.pinpad {
  display: grid; gap: var(--s4); justify-items: center;
  width: min(432px, 100%); margin-inline: auto;
  --face-size: 96px;
}
.pin-who { display: grid; justify-items: center; gap: var(--s2); }
.pin-who-name {
  font-family: var(--font-sans); font-size: var(--t-h3); font-weight: 700;
  letter-spacing: -.005em; line-height: 1.2; color: var(--c-ink);
}
.pin-say { font-size: var(--t-label); color: var(--c-ink70); }
.pin-dots { display: flex; gap: var(--s4); min-height: 24px; align-items: center; }
.pin-dot {
  width: 20px; height: 20px; border-radius: 999px;
  border: 2.5px solid var(--c-mark); background: transparent;
  transition: background var(--d-fast) var(--e-out), transform var(--d-fast) var(--e-out);
}
.pin-dot[data-on="yes"] { background: var(--c-mark); transform: scale(1.14); }
.pin-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s4); width: 100%; }
.pin-key {
  display: grid; place-content: center; justify-items: center; gap: 6px;
  min-height: 84px; border-radius: 20px; background: var(--c-card); border: var(--hair);
  font-family: var(--font-mono); font-size: 1.875rem; font-weight: 500; color: var(--c-ink);
  transition: background var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
/* Clear and Back are KEYS. The same box, the same fill and the same line as a digit,
   each with a picture and a plain word, because printed as flat grey captions they
   read as labels on the paper and a first-day hire with somebody waiting at the
   podium never finds out they can be pressed at all. The picture is the pad's own
   dots: Clear shows the code gone, Back shows one coming off the end. */
.pin-key[data-key="clear"], .pin-key[data-key="back"] {
  font-family: var(--font-sans); color: var(--c-ink);
  background: var(--c-card); border: var(--hair);
}
.pin-key-pic { display: flex; align-items: center; gap: 5px; line-height: 0; }
.pin-key-dot {
  width: 10px; height: 10px; border-radius: 999px;
  border: 2px solid var(--c-mark); background: transparent;
}
.pin-key-dot[data-on="yes"] { background: var(--c-mark); }
.pin-key[data-key="back"] .pin-key-dot:last-child { border-style: dashed; }
.pin-key-word { font-size: var(--t-label); font-weight: 700; line-height: 1.1; }
.pin-key:active { background: var(--c-mist); }
/* The way back off the pad, and like every other button it is a picture and a word. */
.pin-back {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 60px; padding: 0 var(--s5);
  border: 1.5px solid var(--c-hair); border-radius: var(--r-pill);
  background: var(--c-card); color: var(--c-ink);
  font-size: var(--t-body); font-weight: 700;
}
.pin-back:active { background: var(--c-mist); border-color: var(--c-mark); }
/* An iPad: 96pt keys, and the pad still has to fit inside 820pt of landscape glass
   with a face, a name and a way back on it, so the keys grow only when the glass is
   tall enough to take them. */
@media (min-width: 768px) {
  .pinpad { width: min(468px, 100%); gap: var(--s5); --face-size: 112px; }
  .pin-key { min-height: 96px; font-size: 2.125rem; }
  .pin-dot { width: 24px; height: 24px; }
  .pin-who-name { font-size: var(--t-h2); }
  .pin-say { font-size: var(--t-body); }
}
@media (min-width: 768px) and (min-height: 900px) {
  .pinpad { gap: var(--s6); --face-size: 128px; }
  .pin-key { min-height: 112px; font-size: 2.375rem; }
}
/* iPad landscape is 820 points of glass with a face, a name, six dots, four rows of
   96pt keys and a way back to fit inside it. Everything above the keys gives ground
   before the keys do, because the keys are the thing a thumb has to hit. */
@media (min-width: 768px) and (max-height: 899px) {
  .pinpad { gap: var(--s4); --face-size: 96px; }
  .pin-who-name { font-size: var(--t-h3); }
  .pin-say { font-size: var(--t-label); }
}

/* ------------------------------------------------------------ faces
   A face is a real photograph at a size you can recognise from arm's length, or the
   same disc with initials in it. There is no third state: a picture that will not
   load drops out and the initials take over, so a broken image never reaches glass. */
/* Flex and not grid, on purpose: a last row of three under a row of four has to be
   centred under it, and a grid leaves it hanging off the left. --wall-cols is how
   many fit before it wraps, which is the same number either way. */
.facewall {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: start;
  gap: var(--s6) var(--s5);
  width: 100%; max-width: calc(var(--wall-cols, 3) * 208px); margin-inline: auto;
  --face-size: 128px;
}
.face-btn {
  display: grid; justify-items: center; gap: var(--s3); padding: var(--s2);
  width: 184px;
}
.face {
  display: grid; place-items: center; overflow: hidden; flex: none;
  width: var(--face-size, 112px); height: var(--face-size, 112px);
  border-radius: 999px; background: var(--c-mist);
  border: 2px solid var(--c-hair); color: var(--c-mark);
  transition: border-color var(--d-fast) var(--e-out), transform var(--d-fast) var(--e-out);
}
.face-img { width: 100%; height: 100%; object-fit: cover; }
.face-ini {
  font-family: var(--font-serif); font-weight: 600; letter-spacing: .02em;
  font-size: calc(var(--face-size, 112px) * .34); line-height: 1; color: var(--c-mark);
}
.face-name { font-size: var(--t-lead); font-weight: 700; letter-spacing: -.005em; }
.face-btn:active .face { border-color: var(--c-mark); transform: scale(.97); }
.face-btn:hover .face { border-color: color-mix(in srgb, var(--c-mark) 38%, var(--c-hair)); }
@media (min-width: 768px) {
  .facewall { --face-size: 160px; gap: var(--s7) var(--s6); max-width: calc(var(--wall-cols, 3) * 248px); }
  .face-btn { width: 216px; }
  .face-name { font-size: var(--t-h3); }
}
/* An iPhone is two across whatever the wall decided, or the faces are thumbnails. */
@media (max-width: 599px) {
  .facewall { --face-size: 108px; gap: var(--s4) var(--s3); max-width: 340px; }
  .face-btn { width: 148px; gap: var(--s2); padding: var(--s1); }
  .face-name { font-size: var(--t-body); }
}

/* ------------------------------------------------------------ chair tile */
.chairs { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.chair {
  display: grid; gap: var(--s2); justify-items: center; padding: var(--s4);
  background: var(--c-card); border: var(--hair); border-radius: var(--r-card);
  min-height: 260px; align-content: start; text-align: center;
}
.chair-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); width: 100%; }
.chair-no { font-size: var(--t-label); font-weight: 600; color: var(--c-ink70); }
.chair-no b { font-family: var(--font-mono); font-size: 1.125rem; font-weight: 600; color: var(--c-ink); }
.chair-dialwrap { position: relative; width: 150px; height: 150px; display: grid; place-items: center; }
.chair-dial { position: absolute; inset: 0; width: 100%; height: 100%; }
.chair-track { stroke: var(--c-hair); }
.chair-center { display: grid; justify-items: center; gap: 2px; }
.chair-count { font-size: 1.625rem; font-weight: 500; letter-spacing: -.02em; }
.chair-name { font-size: var(--t-body); font-weight: 700; }
.chair-ask {
  font-size: var(--t-fine); font-weight: 600; line-height: 1.3;
  padding: 8px 12px; border-radius: 10px;
  background: var(--fill-due); color: var(--c-amber-text); border: 1px solid var(--line-due);
}
/* FIVE STATES, FIVE FACES. The amber box is the WARNING, and it belongs to one
   of them. "Everything is ready. Give the dose." used to sit in an amber
   warning box under an amber triangle, on the most ready chair in the room. */
.chair[data-state="empty"] { background: var(--c-mist); border-style: dashed; }
.chair[data-state="empty"] .chair-name { color: var(--c-ink70); font-weight: 400; }
/* Ready: forest. The act is a go, so it reads like one. */
.chair[data-state="ready"] { border-color: var(--c-mark); box-shadow: var(--glow-lit); }
.chair[data-state="ready"] .chair-ask { background: var(--c-mist); color: var(--c-mark); border-color: var(--c-leaf); }
/* Watching on time: no warning at all. A sentence, not a box. */
.chair[data-state="running"] .chair-ask {
  background: transparent; color: var(--c-ink70); border-color: transparent;
}
/* Due: the one amber box on the board. */
.chair[data-state="due"] { border-color: var(--line-due); }
/* Over: ink, not red and not a second amber. The bar in the head and the word
   'Over' in the dial are the whole signal. */
.chair[data-state="over"] .chair-ask {
  background: var(--c-mist); color: var(--c-ink); border-color: var(--c-hair);
}
.chair[data-state="done"] .chair-ask {
  background: transparent; color: var(--c-ink70); border-color: transparent;
}
/* Past the mark. The ring is closed rather than empty, in amber rather than on the
   pathway gradient, because the pathway is the run and this chair is no longer on it.
   A presentation attribute on the circle loses to any author rule, which is how the
   gradient stroke set in the markup gives way here without the markup knowing. */
.chair[data-over="yes"] .chair-ring { stroke: var(--c-amber); }
/* 'Over 1h 20m' is three times the width of a countdown, and at the countdown's
   size it walks straight out through the ring. Past the mark the number is the
   message, so the face inside the dial gives ground and the words wrap inside. */
.chair[data-over="yes"] .chair-center { gap: 4px; }
.chair[data-over="yes"] .chair-center .face { --face-size: 36px; width: 36px; height: 36px; }
.chair[data-over="yes"] .chair-center .face-ini { font-size: 13px; }
.chair[data-over="yes"] .chair-count {
  font-size: .9375rem; line-height: 1.2; letter-spacing: 0; color: var(--c-amber-text);
  max-width: 92px; text-align: center; overflow-wrap: break-word;
}

/* ------------------------------------------------------------ the quiet chair
   Read from the far side of a lobby by somebody who is not signed in: a number, a
   draining ring and a countdown, and nothing that could belong to a person. */
/* Flex and not grid, for the same reason the face wall is: a row that does not fill
   has to be centred under the one above it. A grid leaves the odd chair hanging off
   the left margin of a board the whole waiting room is looking at. */
.qboard { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s5); }
.qchair {
  display: grid; justify-items: center; gap: var(--s3); padding: var(--s4) var(--s3);
  flex: 0 0 auto; min-width: 0;
  background: transparent; border: 0; border-radius: var(--r-card);
}
.qchair-dialwrap { position: relative; width: 176px; height: 176px; display: grid; place-items: center; }
.qchair-dial { position: absolute; inset: 0; width: 100%; height: 100%; }
.qchair-track { stroke: var(--c-hair); }
.qchair-no {
  font-size: 4rem; font-weight: 500; line-height: 1; letter-spacing: -.03em; color: var(--c-ink);
}
.qchair-count {
  font-size: 1.75rem; font-weight: 500; letter-spacing: -.01em; color: var(--c-ink);
}
.qchair[data-use="no"] .qchair-no { color: var(--c-ink70); }
/* ONE ROW OF FOUR RINGS, ONE WAY OF WRITING. An empty chair printed "OPEN" in
   spaced capitals while the chair beside it printed "Seated" in sentence case,
   so the lobby board carried two voices on one line. The words already come
   from one function (clock.js chairWords); the case does too now. Everything
   else about this state stays: it is still the quiet one, in the sans, at
   label size, in ink70. */
.qchair[data-use="no"] .qchair-count {
  font-family: var(--font-sans); font-size: var(--t-label); font-weight: 700;
  letter-spacing: .02em; color: var(--c-ink70);
}
.qchair[data-use="no"] .qchair-track { stroke-dasharray: 3 9; stroke-linecap: round; }
.qchair:active .qchair-dialwrap { transform: scale(.98); }
/* An iPad stood on its end is 820 points wide. Four chairs at the landscape size do
   not fit in it, and four chairs wrapped 3 and 1 is not a board, so the dial gives
   ground instead and the whole room stays on one line. */
@media (min-width: 600px) and (max-width: 899px) {
  .qboard { gap: var(--s4); }
  .qchair-dialwrap { width: 144px; height: 144px; }
  .qchair-no { font-size: 3.25rem; }
  .qchair-count { font-size: 1.375rem; }
}
@media (max-width: 599px) {
  .qboard { gap: var(--s4); }
  .qchair-dialwrap { width: 132px; height: 132px; }
  .qchair-no { font-size: 2.75rem; }
  .qchair-count { font-size: 1.375rem; }
}

/* ------------------------------------------------------------ chips
   A short fact lifted out of a longer one: an answer off a web form, a site name.
   It is a label and never a button, so it carries the amber that clears AA. */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: var(--r-pill);
  background: var(--fill-due); border: 1px solid var(--line-due);
  font-size: var(--t-fine); font-weight: 700; color: var(--c-amber-text);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }

/* ------------------------------------------------------------ person rows */
.plist { display: grid; gap: var(--s2); }
.prow {
  display: flex; align-items: center; gap: var(--s4);
  width: 100%; min-height: 76px; padding: var(--s3) var(--s4); text-align: left;
  background: var(--c-card); border: var(--hair); border-radius: 14px;
}
.prow-main { flex: 1; display: grid; gap: 1px; min-width: 0; }
.prow-name { font-size: var(--t-body); font-weight: 700; }
.prow-word { font-size: var(--t-fine); color: var(--c-ink70); }
.prow-time { font-size: var(--t-label); color: var(--c-ink70); flex: none; }
.prow:active { background: var(--c-mist); }

/* ------------------------------------------------------------ numbers */
.stats { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.stat {
  display: grid; gap: var(--s1); padding: var(--s5);
  background: var(--c-card); border: var(--hair); border-radius: var(--r-card);
}
.stat-label {
  font-size: var(--t-eyebrow); font-weight: 700; letter-spacing: .15em;
  text-transform: uppercase; color: var(--c-amber-text);
}
.stat-value { font-size: 2.5rem; font-weight: 500; letter-spacing: -.02em; line-height: 1.05; }
.stat-sentence { font-size: var(--t-fine); color: var(--c-ink70); max-width: 34ch; }
.stat[data-unknown="yes"] .stat-value {
  font-family: var(--font-sans); font-size: 1.5rem; font-weight: 600; color: var(--c-ink70);
}
.stat[data-unknown="yes"] .stat-label { color: var(--c-ink70); }
.spark { width: 100%; height: 28px; margin-top: var(--s2); }

/* ------------------------------------------------------------ room mode
   Into and out of the dim room over 600ms, never a flip at a dissociating patient's
   face. roomMode() raises data-room-shift for exactly the length of the crossfade and
   then drops it again, so nothing else in the product inherits a 600ms color change. */
html[data-room-shift="yes"] body,
html[data-room-shift="yes"] #chrome,
html[data-room-shift="yes"] #banner,
html[data-room-shift="yes"] #tabs,
html[data-room-shift="yes"] #tabs button,
html[data-room-shift="yes"] #screen *,
html[data-room-shift="yes"] .greenbar,
html[data-room-shift="yes"] .greenbar * {
  transition:
    background-color var(--d-room) var(--e-out),
    color var(--d-room) var(--e-out),
    border-color var(--d-room) var(--e-out),
    fill var(--d-room) var(--e-out),
    stroke var(--d-room) var(--e-out) !important;
}

/* ------------------------------------------------------------ not live */
html[data-live="no"] .tile,
html[data-live="no"] .chair,
html[data-live="no"] .prow,
html[data-live="no"] .ladder-row,
html[data-live="no"] .face {
  border-style: dashed; border-width: 1.5px;
}
/* The quiet chair has no border to dash, so its ring carries the same fact. This is
   the one board that sits on the glass all day with nobody signed in to notice, so a
   stale chair number has to LOOK stale rather than look like the room. */
html[data-live="no"] .qchair .qchair-track { stroke-dasharray: 3 9; stroke-linecap: round; }
html[data-live="no"] .qchair .qchair-ring { stroke-opacity: .45; }
html[data-live="no"] .qchair .qchair-no,
html[data-live="no"] .qchair .qchair-count { color: var(--c-ink70); }
html[data-live="no"] .greenbar { outline: 1.5px dashed color-mix(in srgb, var(--c-on-forest) 55%, transparent); outline-offset: -3px; }

.notlive-band {
  display: none; align-items: center; gap: var(--s2);
  padding: 10px var(--gutter); background: var(--fill-due);
  border-bottom: 1px solid var(--line-due); color: var(--c-amber-text);
  font-size: var(--t-fine); font-weight: 700;
}
html[data-live="no"] .notlive-band { display: flex; }

/* ------------------------------------------------------------ the quiet act
   The product's answer to the text link. There were three underlined phrases
   in it ("Add a number to call", "Type it instead", and the outreach picker's
   own), and an underline is a web page's grammar, not this one's: a first day
   hire has no reason to believe underlined type is a button. One box, one
   picture, one plain word, one weight down from the act above it. */
.quiet-act {
  display: inline-flex; align-items: center; gap: var(--s3);
  justify-self: start; align-self: start;
  min-height: var(--touch-min); padding: 10px var(--s4);
  background: var(--c-card); color: var(--c-ink);
  border: 1.5px solid var(--c-hair); border-radius: var(--r-pill);
  font-size: var(--t-label); font-weight: 700; text-align: left;
  text-decoration: none; overflow-wrap: anywhere;
}
.quiet-act .plate { color: var(--c-mark); }
.quiet-act-pic { line-height: 0; flex: none; }
.quiet-act-fact { font-weight: 400; font-size: var(--t-fine); color: var(--c-ink70); }
.quiet-act:active { background: var(--c-mist); }
/* A phone gives it the whole line rather than a pill floating in white space. */
@media (max-width: 519px) {
  .quiet-act { width: 100%; justify-content: flex-start; }
}

/* ------------------------------------------------------------ phrase chips
   Talking came off every patient screen (browser dictation ships the sound to
   Apple or Google with no BAA), so what is left is somebody holding an iPad
   with no keyboard. Three to six of the lines a clinic writes over and over,
   one tap each, above the keyboard. The word is the picture: these are words,
   and the word tile rule says a word may be its own picture. */
.chips-row { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip-act {
  min-height: var(--touch-min); padding: 10px var(--s4);
  background: var(--c-mist); color: var(--c-mark);
  border: 1.5px solid var(--c-hair); border-radius: var(--r-pill);
  font-size: var(--t-label); font-weight: 700; text-align: left;
}
.chip-act:active { background: var(--c-card); border-color: var(--c-mark); }

/* ------------------------------------------------------------ the typed note
   Talking came off every screen in this product for a privacy reason (browser
   dictation ships the sound of somebody saying a patient's name to Apple or
   Google with no BAA), so what is left is a person holding an iPad with no
   keyboard. This component is on three sheets in three different lanes: the
   session sheet, the call sheet and the ask-someone sheet. It used to be styled
   inside the CLINICIAN lane's stylesheet, which only that lane loads, so the
   same box came up as a bare browser textarea on the other two. */
.note { display: grid; gap: var(--s3); }
.note-label { font-size: var(--t-label); font-weight: 700; }
.note-fine { margin: 0; color: var(--c-ink70); }
.note-type {
  width: 100%; min-height: 140px; padding: var(--s4);
  background: var(--c-card); border: 2px solid var(--c-hair); border-radius: var(--r-input);
  /* Reading size, not label size: somebody is checking what they wrote against
     a person sitting in front of them. */
  font: inherit; font-size: var(--t-lead); line-height: 1.45; color: var(--c-ink);
  resize: vertical;
}
/* The box thickens AND keeps the product's one focus ring. It used to trade the
   ring for a 26 percent glow, which is the one substitution this product is not
   allowed to make: a focus indicator at a quarter of an alpha over white is
   under 3:1, so the person who most needs to know where the keyboard is was the
   one who could not see it. base.css draws the ring; this only says which box. */
.note-type:focus-visible { border-color: var(--c-mark); outline: 3px solid var(--c-mark); outline-offset: 2px; }
.note-heard { color: var(--c-mark); font-weight: 600; }
/* With the keyboard up the box takes what is left rather than pushing the
   welded act off the panel. min-height alone never did this: a textarea with
   rows="4" is 146px tall on its own, a floor of 96 does not cap anything, and
   the box went on standing four rows tall inside a 267px scroller, so the line
   somebody was typing scrolled under the welded act while they typed it.
   A height does cap it, and resize:vertical still lets a long note be dragged
   open when the keyboard is away. */
html[data-keyboard="up"] .note-type { min-height: 0; height: 96px; }

/* ------------------------------------------------------------ the red band
   One of the three red places: nobody who can prescribe is on site while somebody is being
   watched. One band for every screen that says so (components.js stopBand). */
.stop-band {
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s5); border-radius: var(--r-card);
  background: var(--fill-stop); border: 1px solid var(--line-stop);
}
.stop-band .plate { color: var(--c-alert); }
.stop-band b { display: block; font-size: var(--t-lead); font-weight: 700; color: var(--c-alert); }
.stop-band-fine { font-size: var(--t-fine); color: var(--c-ink70); }
