/* =====================================================================================================
   On site, by voice (#on-site, part "phone", js/phone.js). SPEC 7.6. Owner: phone builder.
   A CSS-drawn phone running the Duit mobile app: the project manager talks (mic, live waveform, words
   appear), Duit shows what it heard, updates the apps (~ then *), drafts the customer message (waits for the
   passkey) and tells the office. A tablist switches the trade; each trade's script plays in the same phone.

   LAYOUT   .ph-grid: head, controls (.ph-ctl: tabs, the play control, .ph-who caption), the panel (phone),
            the points. Wide (>= 1000px): copy left, phone right, copy centred against the phone; the phone
            fits whole under the header after the "On site" jump (--ph-top). Tablet (740-999px): head and
            controls on top, phone left, points right. Narrow: one column, phone between controls and points.
            .ph-ctl is a size container: under 470px the play control becomes a square icon button (its text
            stays for screen readers) and the tabs share the rest of the row, so they never wrap.
   SIZE     The phone is all em on one knob: .ph-device's font-size, at most 12.5px (346 x 711px), never wider
            than its column (.ph-panel is the inline-size container: 100cqi / 27.9) and, down to 10px, short
            enough to sit in the view under the header (100svh; wide: under the header and --ph-top, with 32px
            to spare). Nothing inside is px except hairlines, so the phone scales as one picture.
   STATES   Base styles are the finished state (reduced motion and no-JS show it; no-JS also keeps the
            .ph-ctl-row of tabs and the play control hidden, since only JS makes them work). JS toggles [hidden]
            on the beats, .is-on on .ph-idle (the start screen, until Duit has heard), .is-tap on .ph-mic (the
            press), .is-live on .ph-said and .ph-dock while listening, .is-paused on the .dw screen whenever the
            clock is stopped (paused by the visitor, off screen, tab hidden), and data-state on .ph-play.
   ===================================================================================================== */

/* ---------- Section layout ---------- */
.ph-grid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "ctl" "panel" "points";
  row-gap: 28px;
}
.ph-grid > .sec-head { grid-area: head; margin: 0; }
.ph-ctl { grid-area: ctl; min-width: 0; max-width: 480px; container: ph-ctl / inline-size; }
.ph-panel { grid-area: panel; min-width: 0; container-type: inline-size; display: grid; justify-items: center; border-radius: 12px; }
.ph-panel:focus-visible { outline-offset: 8px; }
.ph-points { grid-area: points; min-width: 0; max-width: 560px; }

@media (min-width: 1000px) {
  /* After the "On site" jump the section's top sits under the header, so the whole phone (mic included) must
     fit below it. --ph-top is the section's top padding: the room a full-size phone (711px) leaves under the
     header, split evenly above and below it, never under 32px nor over the usual --sec-pad. On short laptop
     screens (720, 768) the phone then shrinks to what is left (see .ph-device below). */
  .sec.ph { --ph-top: clamp(32px, (100svh - var(--head-h) - 711px) / 2, var(--sec-pad)); padding-top: var(--ph-top); }
  /* the empty first and last rows centre the copy against the phone; gaps are margins so they add nothing */
  .ph-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto auto auto minmax(0, 1fr);
    grid-template-areas: ". panel" "head panel" "ctl panel" "points panel" ". panel";
    column-gap: clamp(48px, 6vw, 96px); row-gap: 0;
  }
  .ph-ctl, .ph-points { margin-top: 36px; }
  /* start, not centre: if the copy runs taller than a shrunken phone, the phone stays at the top, in view */
  .ph-panel { align-self: start; }
  .ph .ph-device { font-size: min(100cqi / 27.9, max(10px, min(12.5px, (100svh - var(--head-h) - var(--ph-top) - 32px) / 56.9))); }
}
/* short laptop screens: tighten the copy beside the phone so it ends about where the phone does */
@media (min-width: 1000px) and (max-height: 820px) {
  .ph-ctl, .ph-points { margin-top: 24px; }
  .ph .ph-who { margin-top: 12px; }
  .ph .ph-points li { padding: 10px 0 11px; }
}
@media (min-width: 740px) and (max-width: 999px) {
  .ph-grid {
    grid-template-columns: 352px minmax(0, 1fr);
    grid-template-areas: "head head" "ctl ctl" "panel points";
    column-gap: clamp(32px, 5vw, 56px);
  }
  .ph-panel { justify-items: start; }
  .ph-points { align-self: center; }
}

/* ---------- Controls: trade tabs, Replay, who is talking ---------- */
.ph-ctl-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 14px; }
.ph-tabs {
  display: inline-flex; max-width: 100%; padding: 3px; gap: 2px;
  border: 1px solid var(--faint); border-radius: 9px; background: var(--surface);
}
.ph-tab {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 0; min-height: 44px; padding: 0 16px; border: 1px solid transparent; border-radius: 6px;
  background: transparent; color: var(--soft);
  font-family: var(--mono); font-size: 13px; font-weight: 700; line-height: 1; letter-spacing: .02em; white-space: nowrap;
  transition: background-color .15s, border-color .15s, color .15s;
}
.ph-tab:hover { color: var(--text); }
.ph-tab::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--faint); transition: background-color .15s; }
.ph-tab[aria-selected="true"] { background: var(--sel); border-color: var(--line-strong); color: var(--text); }
.ph-tab[aria-selected="true"]::before { background: var(--accent); }
.ph-tab:focus-visible { outline-offset: 1px; }
/* The play control: Pause while the script plays, Play once paused, Replay at the end (data-state, set by
   phone.js; its text is its accessible name). It matches the tab group's height (3 + 44 + 3 + 2 borders)
   and is as wide as its longest word, so the row does not shift as the word changes. */
.ph-play { min-width: 112px; min-height: 52px; padding: 0 18px; border-radius: 9px; }
.ph-play::after { display: none; }
.ph-play svg { display: none; width: 14px; height: 14px; }
.ph-play[data-state="pause"] .ph-i-pause, .ph-play[data-state="play"] .ph-i-play, .ph-play[data-state="replay"] .ph-i-replay { display: block; }
@container ph-ctl (max-width: 469px) {
  .ph-ctl-row { flex-wrap: nowrap; gap: 8px; }
  .ph-tabs { flex: 1 1 auto; min-width: 0; }
  .ph-tab { flex: 1 1 auto; padding: 0 8px; gap: 7px; }
  .ph-play { flex: none; width: 52px; min-width: 0; padding: 0; }
  .ph-play svg { width: 16px; height: 16px; }
  .ph-play-txt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@container ph-ctl (max-width: 339px) {
  .ph-tab { padding: 0 6px; }
  .ph-tab::before { display: none; }
}
.ph-who { max-width: 52ch; margin-top: 16px; font-size: 15px; line-height: 1.55; color: var(--soft); }
.ph-ctl-row[hidden] + .ph-who { margin-top: 0; } /* no JS: the tabs row stays hidden, the caption leads */
.ph-who b { font-weight: 400; color: var(--text); }

/* ---------- Points ---------- */
.ph-points { border-top: 1px solid var(--faint); }
.ph-points li { padding: 14px 0 15px; border-bottom: 1px solid var(--faint); font-size: 15px; line-height: 1.55; color: var(--soft); }
.ph-pt { display: block; margin-bottom: 3px; font-family: var(--mono); font-size: 14px; font-weight: 700; line-height: 1.4; letter-spacing: -.005em; color: var(--text); }

/* ---------- The phone ---------- */
.ph-device {
  position: relative; flex: none;
  font-size: 12.5px; font-size: min(100cqi / 27.9, max(10px, min(12.5px, (100svh - 120px) / 56.9)));
  width: 27.7em; height: 56.9em; padding: .62em;
  border: 1.5px solid var(--line-strong); border-radius: 4.3em;
  background: #000;
  box-shadow: inset 0 0 0 .2em #15171f; /* the frame band, flat */
}
/* side buttons: volume (left), power (right) */
.ph-device::before, .ph-device::after { content: ""; position: absolute; width: 3px; border-radius: 2px; background: var(--line-strong); }
.ph-device::before { left: -4px; top: 9.5em; height: 4.2em; box-shadow: 0 5.4em 0 var(--line-strong); }
.ph-device::after { right: -4px; top: 12.5em; height: 6.2em; }

.ph-screen.dw {
  --dw-fs: 1em;
  height: 100%; border: 0; border-radius: 3.7em;
  font-size: 1em;
}

/* status bar and the island */
.ph-status {
  position: relative; flex: none; display: flex; align-items: center; justify-content: space-between;
  height: 3.6em; padding: .25em 2.2em 0 2.5em;
}
.ph-time { font-size: 1.04em; font-weight: 600; letter-spacing: .01em; font-variant-numeric: tabular-nums; }
.ph-island {
  position: absolute; top: .85em; left: 50%; width: 7.6em; height: 2.2em; margin-left: -3.8em;
  border-radius: 2em; background: #000; box-shadow: 0 0 0 1px #000;
}
.ph-island::after {
  content: ""; position: absolute; top: 50%; right: .75em; width: .78em; height: .78em; margin-top: -.39em;
  border-radius: 50%; background: #141826; box-shadow: inset 0 0 0 1px #262b3b;
}
.ph-sys { display: inline-flex; align-items: center; gap: .45em; }
.ph-sig { display: inline-flex; align-items: flex-end; gap: .16em; height: .85em; }
.ph-sig i { display: block; width: .22em; border-radius: .08em; background: var(--text); }
.ph-sig i:nth-child(1) { height: 35%; }
.ph-sig i:nth-child(2) { height: 55%; }
.ph-sig i:nth-child(3) { height: 78%; }
.ph-sig i:nth-child(4) { height: 100%; background: var(--dim); }
.ph-batt { position: relative; width: 1.9em; height: .95em; border: 1px solid var(--soft); border-radius: .3em; }
.ph-batt::before { content: ""; position: absolute; inset: 1.5px; right: 35%; border-radius: .15em; background: var(--text); }
.ph-batt::after { content: ""; position: absolute; top: 50%; right: -.22em; width: .14em; height: .36em; margin-top: -.18em; border-radius: 0 .1em .1em 0; background: var(--soft); }

/* the app's header */
.ph-app {
  flex: none; display: flex; align-items: center; gap: .5em; min-width: 0;
  height: 3em; padding: 0 1.15em; border-bottom: 1px solid var(--faint);
}
.ph-app .dw-mark { margin: 0; }
.ph-app b { color: var(--text); }
.ph-co { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--soft); }
.ph-co::before { content: "· "; content: "· " / ""; }
.ph-app .dw-tag { margin-left: auto; }

/* the conversation: newest at the bottom, the oldest slides up under a soft top edge */
.ph-convo {
  position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: .9em 1.15em .85em;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 2.2em);
  mask-image: linear-gradient(to bottom, transparent, #000 2.2em);
}
.ph-feed { flex: none; display: flex; flex-direction: column; gap: .7em; }

/* the start screen: centred in the space the transcript does not use; hidden in the finished state */
.ph-idle {
  position: absolute; top: 0; right: 0; left: 0; bottom: 11em;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 0 1.6em; text-align: center; pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(-.6em);
  transition: opacity .35s var(--ease), transform .5s var(--ease), visibility 0s .5s;
}
.ph-idle.is-on { opacity: 1; visibility: visible; transform: none; transition: opacity .35s var(--ease), transform .5s var(--ease); }
.ph-idle-mark { width: 2.6em; height: 2.6em; margin-bottom: 1.2em; color: var(--soft); }
.ph-idle > .ph-idle-hi { font-size: 1.6em; line-height: 1.25; letter-spacing: -.01em; color: var(--text); }
.ph-idle > .ph-idle-ask { margin-top: .3em; font-size: 1.08em; line-height: 1.45; color: var(--soft); }
.ph-idle > .ph-idle-at { margin-top: 1.4em; }
.ph-idle-at .dw-cite { height: 2em; margin-left: 0; font-size: .9em; }

.ph-said .dw-bubble { max-width: 90%; min-width: 3.4em; min-height: 2.9em; }
.ph-said .dw-who-user { display: inline-flex; align-items: baseline; gap: .1em; }
.ph-said-live { display: none; }
.ph-said.is-live .ph-said-live { display: inline; }
.ph-said.is-live .ph-said-done { display: none; }
.ph-said .dw-caret { display: none; width: .14em; margin-left: .2em; background: var(--accent); }
.ph-said.is-live .dw-caret { display: inline-block; }

.ph-heard {
  padding: .7em .9em .78em; border: 1px solid var(--line-strong); border-radius: 10px;
}
.ph-heard .dw-label { display: flex; align-items: center; gap: .55em; margin-bottom: .3em; }
.ph-heard .dw-label .dw-mark { width: 1.15em; height: 1.15em; margin: 0; vertical-align: 0; }
.ph-job { color: var(--text); }
.ph-sum { font-size: .93em; line-height: 1.5; color: var(--soft); }

.ph-steps .dw-step { padding-block: .45em; }
.ph-steps .dw-step::before { top: .45em; }
.ph-step-busy .dw-state { visibility: hidden; }

.ph-draft .dw-draft { padding: .6em .75em .72em; }
.ph-draft .dw-draft-head { margin-bottom: .45em; }
.ph-draft .dw-confirm { margin-top: .6em; padding-top: 0; border-top: 0; }
.ph-draft .dw-confirm-state { gap: .45em; }
.ph-office { padding: 0 .1em; }
.ph-office .g { width: 1.1ch; }

/* the mic dock: waveform, mic, waveform; the home indicator under it */
.ph-dock {
  position: relative; flex: none;
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: .9em;
  padding: .8em 1.15em 2em; border-top: 1px solid var(--faint);
}
.ph-dock::after {
  content: ""; position: absolute; left: 50%; bottom: .6em; width: 9.6em; height: .3em; margin-left: -4.8em;
  border-radius: 1em; background: var(--dim);
}
.ph-wave { display: flex; align-items: center; gap: .3em; height: 2.6em; overflow: hidden; }
.ph-wave:first-child { justify-content: flex-end; }
.ph-wave i {
  display: block; flex: none; width: .24em; height: 100%; border-radius: .2em;
  background: var(--line-strong); transform: scaleY(.12);
}
.ph-dock.is-live .ph-wave i { background: var(--soft); }
.ph-mic {
  position: relative; display: grid; place-items: center; width: 4.4em; height: 4.4em;
  border: 2px solid var(--accent); border-radius: 50%;
  background: var(--surface); color: var(--text);
  transition: background-color .2s, color .2s, transform .2s var(--ease);
}
.ph-mic svg { width: 1.75em; height: 1.75em; }
.ph-mic::after {
  content: ""; position: absolute; inset: -2px; border: 2px solid var(--accent); border-radius: 50%;
  opacity: 0; pointer-events: none;
}
.ph-mic.is-tap { transform: scale(.92); background: var(--sel); }
.ph-dock.is-live .ph-mic { background: var(--accent-fill); color: var(--on-accent); }
.ph-dock.is-live .ph-mic::after { animation: ph-pulse 1.6s var(--ease) infinite; }
/* window.css's .dw.is-paused freezes the screen's animations, but * does not reach pseudo-elements */
.ph-screen.is-paused .ph-mic::after { animation-play-state: paused; }
@keyframes ph-pulse { from { opacity: .55; transform: scale(1); } to { opacity: 0; transform: scale(1.5); } }

/* ---------- Narrow ---------- */
@media (max-width: 479px) {
  .ph-who { font-size: 14px; }
}
