/* PTR AI Studio - the pieces specific to this site.
   Everything shared (brand field, glass, dock, drawer, hero, gate, panels)
   lives in ptr-core.css and is byte-identical with the PTR Labs site. */

/* ------------------------------------------------------------- CONNECT ---- */
/* `height: 100%` measured against the panel body while the tab row sat ABOVE
   it with a 10px bottom margin, so the grid plus that margin was always 10px
   taller than the box and the app scrolled by exactly that much at every
   viewport. A flex child sized from the REMAINING space cannot overshoot. */
.panel-body:has(> .connect-grid) { display: flex; flex-direction: column; }
.connect-grid { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 14px; align-items: stretch; min-height: 0; flex: 1 1 0; height: auto; }
.connect-grid > * { min-height: 0; }
@media (max-width: 950px) {
  /* WAS `height: auto`, which let the two stacked cards grow past the panel and
     scroll the app. A phone gets a rows grid that FITS: the presence card takes
     what it needs, the conversation takes the rest and scrolls internally. */
  .connect-grid { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); height: 100%; }
  /* A 260px portrait ring eats most of a phone screen before a word is read.
     QUALIFIED WITH `.connect-grid` BECAUSE THIS RULE WAS INERT. A media query
     adds no specificity, so this `.presence` tied with the base `.presence`
     below - and the base one is LATER in the file, so it won and the ring stayed
     260px on a phone. Measured at a 375px viewport, not read off the source. */
  .connect-grid .presence { max-width: 128px; margin-bottom: 8px; }
  .presence-card { padding: 12px; }
}

.presence-card { text-align: center; }
.presence {
  position: relative;
  width: 100%; max-width: 260px;
  aspect-ratio: 1;
  margin: 0 auto 14px;
  display: grid; place-items: center;
}
.presence canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.presence-mark {
  position: relative;
  width: 30%; height: auto;
  opacity: .92;
  filter: drop-shadow(0 0 18px rgba(128, 237, 239, .35));
}
#presenceLabel { display: block; }
#presenceNote { margin-top: 6px; }

/* AVATAR mode: the same presence, given the room to be one.
   The ONLY difference between this and voice is size. There is no second
   canvas, no video element and no second code path - the ring is the same
   analyser on the same audio, drawn bigger, which is why the copy can call it
   a voice presence and be exactly right.
   The column rule is scoped to the wide layout on purpose: below 950px the
   grid is a rows layout, and a class here would otherwise win on specificity
   and put two columns back on a phone. */
@media (min-width: 951px) {
  .connect-grid.presence-lg { grid-template-columns: minmax(0, 42%) minmax(0, 1fr); }
  .connect-grid.presence-lg .presence { max-width: 380px; }
}
@media (max-width: 950px) {
  .connect-grid.presence-lg .presence { max-width: 190px; }
}

/* ---------------------------------------------------------- CONNECT book -- */
/* The booking request shares the conversation's card and swaps with it, so the
   panel never grows a second column or scrolls the page. `[hidden]` needs
   saying out loud for all three: `.messages` and `.composer` set a `display`,
   and a class beats the user agent's `[hidden] { display: none }`. */
#connectMessages[hidden], #connectForm[hidden], #connectStatus[hidden], .book-form[hidden] {
  display: none;
}
/* THE MICROPHONE BUTTON HAS NEVER ACTUALLY HIDDEN. studio.js has set
   `mic.hidden` on the chat tab since CONNECT shipped, and `.mic-btn` sets
   `display: grid`, which beats the user agent's `[hidden] { display: none }` -
   so a mode that takes no microphone still showed one. Found by opening the
   page, not by a test: nothing throws, the button is simply there. */
#connectMic[hidden] { display: none; }

.book-form {
  display: flex; flex-direction: column; gap: 12px;
  min-height: 0; overflow-y: auto; padding-right: 4px;
}
.book-form h3 { margin: 2px 0 0; font-size: clamp(18px, 2.4vw, 24px); letter-spacing: -.02em; }
.book-form .micro { margin: 0; }
.book-form input, .book-form textarea {
  width: 100%; min-width: 0;
  border: 1px solid rgba(255,255,255,.12); border-radius: 14px;
  background: rgba(255,255,255,.04); color: #fff; outline: none;
  font: inherit; font-size: 15px; line-height: 1.5;
}
.book-form input { height: 48px; padding: 0 14px; }
.book-form textarea { min-height: 76px; resize: vertical; padding: 12px 14px; }
.book-form input:focus, .book-form textarea:focus { border-color: rgba(128,237,239,.6); }
.book-form input::placeholder, .book-form textarea::placeholder { color: rgba(255,255,255,.38); }

.book-field { display: grid; gap: 6px; }
.book-timing { border: 0; padding: 0; margin: 0; display: grid; gap: 8px; }
.book-timing legend { padding: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  border: 1px solid rgba(255,255,255,.12); border-radius: 999px;
  background: rgba(255,255,255,.035); color: rgba(255,255,255,.68);
  padding: 8px 14px; cursor: pointer;
  font: inherit; font-size: 13px;
}
.chip:hover { color: #fff; border-color: rgba(255,255,255,.24); }
.chip.active { background: rgba(128,237,239,.12); border-color: rgba(128,237,239,.5); color: #fff; }

.book-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 2px; }
/* The failure line has to read as one. A refused booking that looks like a
   caption is a refused booking the visitor walks away thinking succeeded. */
.book-form .micro.err { color: #F58BFF; }
.book-sent { margin: 0; color: var(--ptr-ink-2); line-height: 1.55; }

/* ------------------------------------------------------------- CONSULT ---- */
/* Same defect the connect grid had: height:100% is measured against whatever
   is above it and the stacked breakpoint then handed it height:auto, which
   lets it grow past the panel. Sized from the space that is LEFT instead. */
.panel-body:has(> .consult-grid) { display: flex; flex-direction: column; }
.consult-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; align-items: stretch; min-height: 0; flex: 1 1 0; height: auto; }
.consult-grid > * { min-height: 0; }
@media (max-width: 950px) { .consult-grid { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); height: 100%; } }

.progress { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.progress-track {
  flex: 1; height: 4px; border-radius: 99px;
  background: rgba(255,255,255,.1); overflow: hidden;
}
.progress-track i {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, #80EDEF, #41BBF5, #6D57FF, #A567F1);
  transition: width .4s cubic-bezier(.22,1,.36,1);
}
#consultQuestion h3 { font-size: 22px; line-height: 1.3; margin: 0 0 6px; letter-spacing: -.015em; }
#consultQuestion .why { margin: 0 0 14px; color: var(--ptr-ink-3); font-size: 13px; }
#consultQuestion textarea {
  width: 100%; min-height: 108px; resize: vertical;
  border: 1px solid rgba(255,255,255,.16); border-radius: 14px;
  background: rgba(255,255,255,.04); color: #fff; padding: 12px 14px; outline: none;
  line-height: 1.5;
}
#consultQuestion textarea:focus { border-color: rgba(128,237,239,.7); box-shadow: 0 0 0 3px rgba(65,187,245,.15); }
.consult-nav { display: flex; gap: 8px; justify-content: space-between; margin-top: 12px; }

.answered { margin-top: 16px; display: grid; gap: 8px; }
.answered .row {
  display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: start;
  padding: 10px 12px; border-radius: 14px;
  background: rgba(255,255,255,.035); border: 1px solid rgba(255,255,255,.08);
}
.answered .row p { margin: 0; font-size: 13px; }
.answered .row .q { color: var(--ptr-ink-3); }
.answered .row .a { color: #fff; margin-top: 3px; }
.answered .row button {
  border: 0; background: none; color: var(--ptr-cyan);
  font-size: 12px; cursor: pointer; padding: 2px 4px;
}

.brief-card h3 { font-size: 24px; margin: 8px 0 4px; letter-spacing: -.02em; }
.brief-card h4 { font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.55); margin: 18px 0 8px; }
.brief-card p { color: var(--ptr-ink-2); line-height: 1.55; margin: 0 0 8px; }
.opp {
  border-left: 2px solid var(--ptr-cyan);
  padding: 2px 0 2px 12px; margin: 12px 0;
}
.opp strong { display: block; margin-bottom: 3px; }
.opp .why-now { color: var(--ptr-ink-2); font-size: 14px; }
.opp .first-step, .opp .people { font-size: 13px; color: rgba(255,255,255,.7); margin-top: 4px; }
.risk { border-left: 2px solid var(--ptr-magenta); padding-left: 12px; margin: 10px 0; }
.caveat {
  margin-top: 16px; padding: 10px 12px;
  border: 1px solid rgba(255,255,255,.1); border-radius: 12px;
  background: rgba(255,255,255,.03);
  font-size: 13px; color: rgba(255,255,255,.66);
}
.brief-actions { display: flex; gap: 8px; margin-top: 14px; }

/* ----------------------------------------------------------- COLLABORATE -- */
.panel-body:has(> .collab-grid) { display: flex; flex-direction: column; }
.collab-grid { display: grid; grid-template-columns: 400px minmax(0, 1fr); gap: 14px; align-items: stretch; min-height: 0; flex: 1 1 0; height: auto; }
.collab-grid > * { min-height: 0; }
/* MEASURED before this: the collaborate panel overflowed by 356px at 980x700,
   44px at 375x667 and 49px at 360x640, because the stacked breakpoint set
   height:auto and the board card then grew to whatever it wanted. */
@media (max-width: 1100px) { .collab-grid { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); height: 100%; } }

#transcript {
  width: 100%; margin: 8px 0 12px; resize: vertical;
  border: 1px solid rgba(255,255,255,.14); border-radius: 14px;
  background: rgba(255,255,255,.04); color: #fff; padding: 12px 14px; outline: none;
  line-height: 1.55; font-size: 15px;
}
#transcript:focus { border-color: rgba(128,237,239,.6); }
.collab-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.question-box {
  margin-top: 14px; padding: 12px 14px;
  border: 1px solid rgba(128,237,239,.28); border-radius: 14px;
  background: rgba(128,237,239,.07);
}
.question-box strong { display: block; margin-top: 4px; font-weight: 500; line-height: 1.45; }

.live-notes { margin-top: 16px; display: grid; gap: 12px; }
.note-group h5 {
  margin: 0 0 5px; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
}
.note-group ul { margin: 0; padding-left: 18px; }
.note-group li { margin: 3px 0; font-size: 14px; color: rgba(255,255,255,.82); line-height: 1.45; }
.note-group.goal p { margin: 0; font-size: 16px; }

.board-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.board-actions input {
  height: 40px; min-width: 240px; flex: 1;
  border: 1px solid rgba(255,255,255,.14); border-radius: 12px;
  background: rgba(255,255,255,.04); color: #fff; padding: 0 12px; outline: none; font-size: 14px;
}
.board-wrap {
  margin-top: 10px;
  border-radius: 18px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.12);
  background: #fff;
}
#board { display: block; width: 100%; height: auto; }
@media (max-width: 520px) {
  .board-actions { width: 100%; }
  .board-actions input { min-width: 0; }
}

/* --------------------------------------------------------- CONSULT entry -- */
/* The one choice made before the consultation starts. It occupies the same
   card the questions will, so answering does not move the panel under the
   visitor. */
.consult-entry { display: grid; gap: 10px; align-content: start; }
.consult-entry h3 { margin: 2px 0 0; font-size: clamp(18px, 2.4vw, 24px); letter-spacing: -.02em; }
.entry-choice { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.entry-choice button { flex: 1 1 180px; }

/* What the map was grounded on. Quiet by design: it is provenance, not a
   selling point, and it must not compete with the map itself. */
.sources { margin-top: 12px; border-top: 1px solid rgba(255,255,255,.09); padding-top: 10px; }
.sources ul { margin: 6px 0 0; padding-left: 18px; }
.sources li { color: var(--ptr-ink-3); font-size: 12px; line-height: 1.6; }

.brief-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ============================================================================
   SHORT PHONE: THE PANEL IS ONE VIEW
   ============================================================================
   MEASURED, not guessed. The state-acceptance harness scored 306 checks with
   8 red, and every red one is VERTICAL inner overflow inside the active panel:

     viewport   connect  consult  collaborate
     360x640      133      109       193
     375x667      106       82       176
     375x812        0        0        43
     390x844        0        0        20
     430x932     clean    clean     clean
     4 desktops  clean    clean     clean

   The gradient is the diagnosis. Between 360x640 and 375x667 the connect and
   consult numbers fall by exactly 27, which is the difference in viewport
   HEIGHT and nothing else, so the content above the overflow is a fixed height
   that refuses to give ground while the space around it shrinks. That is a
   height-driven defect, so the rules below are keyed off height, not width.

   THE THREE THINGS THAT WOULD NOT SHRINK
     CONNECT      a 128px portrait presence ring plus its two captions, sitting
                  in an `auto` grid row above the conversation. An `auto` track
                  is content-sized and cannot be squeezed, so the conversation
                  pane below it collapsed and #connectMessages overflowed.
     CONSULT      `.entry-choice` carries `flex: 1 1 180px`, and 180 + 180 + a
                  10px gap does not fit a 312px card, so the two buttons stood
                  on two rows and cost about 53px a short phone does not have.
     COLLABORATE  a `rows="7"` textarea (189px, fixed) in row one and a canvas
                  whose height is derived from its WIDTH in row two. Neither
                  is sized from the space that is left, so together they asked
                  for roughly 700px inside a 498px panel body.

   THE PATTERN, matched from ptr-labs-launch PR #63 and from the connect and
   consult fixes already in this file: SIZE FROM THE REMAINDER. A grid whose
   tracks are `minmax(0, 1fr)`, cards that are flex columns with `min-height:0`,
   and exactly ONE nominated child per card carrying `flex: 1 1` so it absorbs
   the difference. The ancestors between `.panel-body` and the overflow already
   carried `min-height: 0`; what was missing is that the CARDS were never flex
   containers at all, so nothing inside them could be sized from a remainder.

   NO CHEATING. There is no `zoom`, no `transform: scale()` and no change to
   the viewport meta anywhere below. Every saving is ordinary responsive
   sizing: a smaller ring, a tighter gap, buttons that fit on one row, and
   media sized from the space that is actually left.

   WHY TWO BANDS AND NOT ONE
     `(max-width: 850px) and (max-height: 900px)` matches exactly the four
     phones that fail and nothing else in the matrix: 430x932 is excluded by
     the height, and every desktop the harness drives is 1280 wide or more, so
     all four are excluded by the width. COLLABORATE is red at all four, so its
     structural fix lives here.
     `(max-width: 850px) and (max-height: 700px)` narrows to 360x640 and
     375x667, the only two viewports where CONNECT and CONSULT fail. Compaction
     that would be too aggressive at 812 tall stays inside this band, where
     every panel is already red and nothing clean can be harmed.
   ============================================================================ */

@media (max-width: 850px) and (max-height: 900px) {
  /* ------------------------------------------------------- COLLABORATE ----
     Both rows flexible, both cards flex columns, one nominated child each.
     WAS `auto minmax(0, 1fr)`: the transcript card sized itself from its own
     content, took about 371px of a 498px body, and left the board card 113px
     to put a 195px canvas in. Two `minmax(0, 1fr)` tracks divide the panel
     instead, so neither card can take space the other one needs. */
  .collab-grid {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
  }
  .collab-grid > .card { display: flex; flex-direction: column; min-height: 0; }
  /* The chrome takes what it needs and gives none of it back. Without this a
     flex column shrinks EVERY child, and the mic button and the two actions
     would be the first things squeezed. */
  .collab-grid > .card > * { flex: 0 0 auto; }
  /* THE TRANSCRIPT IS THE ONE THING IN THE FIRST CARD THAT MAY GIVE GROUND.
     `rows="7"` is a starting size, not a requirement; `min-height` is the floor
     below which the field stops being usable, and a flex item cannot shrink
     past its automatic minimum unless that floor is stated. */
  .collab-grid > .card > #transcript { flex: 1 1 auto; min-height: 64px; }
  /* THE BOARD CONTAINS THE DRAWING INSTEAD OF DICTATING THE BOX.
     `#board { height: auto }` derives the wrapper height from the canvas's
     1600x1000 ratio and the card's WIDTH, which is why more width made the
     collaborate overflow worse rather than better: 375x812 was 43 over and
     390x844 was 20, and the 15px of extra width put about 9px of that back.
     Sized from the remainder and drawn with `object-fit: contain`, the board
     keeps its aspect ratio without deciding how tall the panel is. */
  .collab-grid > .board-card > .board-wrap { flex: 1 1 0; min-height: 96px; margin-top: 8px; }
  .collab-grid > .board-card > .board-wrap > #board {
    width: 100%; height: 100%; object-fit: contain;
  }
  /* An empty notes list still spent its 16px top margin. */
  #liveNotes:empty { margin-top: 0; }
}

@media (max-width: 850px) and (max-height: 700px) {
  /* -------------------------------------------------------- panel head ----
     An eyebrow under a mode row that already says CONNECT in capitals is the
     product name printed twice on a 640px screen. The heading stays, because
     it is the only place the panel says what it is FOR; the duplicate goes.
     Scoped to this band, so nothing taller than 700px changes. */
  .panel-head .eyebrow { display: none; }
  .panel-head { margin: 0 2px 6px; }
  .panel-head h2 { font-size: clamp(15px, 4vw, 18px); line-height: 1.2; }

  /* ----------------------------------------------------------- CONNECT ----
     THE PRESENCE BECOMES A STATUS STRIP.
     A 128px ring with a label and a caption stacked under it is about 180px of
     an `auto` row, above a conversation that then had roughly 102px to render
     a greeting needing 235. Laid out as a strip - ring on the left, label and
     note beside it - the same row is about 64px, and every pixel saved goes to
     the messages pane, which is the box that was overflowing. Nothing is
     hidden: #presenceCanvas still has a real box, which is what the harness
     requires of it. */
  .connect-grid { gap: 10px; }
  .connect-grid > .presence-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto;
    align-items: center; align-content: center;
    column-gap: 12px; row-gap: 2px;
    text-align: left; padding: 8px 12px;
  }
  /* `.presence-lg` is named explicitly: the avatar mode's own rule is
     `.connect-grid.presence-lg .presence` at (0,3,0) and would otherwise beat
     a plain descendant selector and put a 190px ring back into the strip. */
  .connect-grid > .presence-card > .presence,
  .connect-grid.presence-lg > .presence-card > .presence {
    grid-column: 1; grid-row: 1 / 3;
    width: 48px; max-width: 48px; margin: 0;
  }
  .connect-grid > .presence-card > #presenceLabel { grid-column: 2; grid-row: 1; margin: 0; }
  .connect-grid > .presence-card > #presenceNote  { grid-column: 2; grid-row: 2; margin: 0; }

  /* The tab row is chrome, and it was wearing desktop padding on two rows. */
  .panel-body:has(> .connect-grid) > .tabs { margin-bottom: 8px; gap: 6px; }
  .panel-body:has(> .connect-grid) > .tabs button,
  .panel-body:has(> .connect-grid) > .tabs .tab-link { padding: 8px 12px; font-size: 14px; }

  /* 44px is the floor for a touch target, so the composer stops at 44 and not
     at whatever would have fitted. */
  .connect-grid .card:has(> .messages) > .messages { margin-bottom: 8px; }
  .connect-grid .composer input { height: 44px; }
  .connect-grid .composer .mic-btn { width: 44px; height: 44px; }

  /* ----------------------------------------------------------- CONSULT ----
     THE TWO ENTRY BUTTONS FIT ON ONE ROW.
     `flex: 1 1 180px` needs 370px of a 312px card, so they wrapped and the
     entry card paid about 53px for it. A 120px basis puts them side by side
     with room to spare and they still grow to fill the row. `min-width: 0`
     keeps a long label from re-introducing the wrap through the automatic
     minimum size. */
  .consult-grid { gap: 10px; }
  .consult-entry { gap: 7px; }
  .consult-entry h3 { font-size: 16px; line-height: 1.25; }
  .consult-entry .micro { margin-top: 6px; }
  .entry-choice { margin-top: 2px; }
  .entry-choice button { flex: 1 1 120px; min-width: 0; padding: 10px 12px; font-size: 14px; }
  /* An empty answer list and an empty brief both still spent their margins. */
  .answered:empty { margin-top: 0; }
  .brief-card #briefContent p { margin-bottom: 4px; }
  .brief-actions { margin-top: 8px; }
  .brief-actions button { flex: 1 1 120px; min-width: 0; padding: 10px 12px; font-size: 14px; }
  /* Belongs to a stage this measurement never reaches, and to the same phone.
     A 108px answer box on a 640px screen is the next defect in this class. */
  #consultQuestion textarea { min-height: 88px; }
  .consult-nav { margin-top: 8px; }

  /* ------------------------------------------------------- COLLABORATE ----
     On top of the structural fix above, the collaborate chrome gives back what
     it can: this band is the pair of viewports that were 176 and 193 over. */
  .collab-grid > .card > .status-row { margin-bottom: 8px; }
  .collab-grid .mic-btn { width: 44px; height: 44px; }
  .collab-grid > .card > #transcript { margin: 6px 0 8px; min-height: 56px; }
  .collab-grid .board-actions input { height: 36px; }
  .collab-actions button { padding: 9px 12px; font-size: 14px; }
}
