/* The graphics, part two: the phone and the app inside it, the completion
   notices and the pairing scan. Same rule as mockups.css: the app's chrome is
   the graphite palette and follows the theme; the terminal is Campbell in
   both. The phone itself is hardware, so its frame is graphite either way. */

/* ----------------------------------------------------------------- phone --- */

.mobile-device {
  /* One source of truth for how large a phone is drawn. Height follows from
     a 412:915 screen, so every phone on a page keeps the same proportion. */
  --mobile-device-w: clamp(228px, 56vw, 252px);
  position: relative;
  display: flex;
  flex-direction: column;
  width: var(--mobile-device-w);
  aspect-ratio: 412 / 915;
  padding: 7px;
  border-radius: 38px;
  background: linear-gradient(155deg, #3b3c40, #1c1d20 38%, #141517 62%, #2c2d31);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.12), var(--shadow-device);
  overflow: hidden;
}

/* The screen fills the frame as a flex item, not with height: 100%: Safari
   does not resolve a percentage against a height that comes from
   aspect-ratio. */
.mobile-device-screen {
  /* The status bar's share of the top of every screen (it was 18px). The
     headers, the notice and the scan below are all measured from it, so a
     change here moves them together. */
  --status-h: 14px;
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  border-radius: 31px;
  background: var(--base);
  font-size: 0.8125rem;
  letter-spacing: 0;
  overflow: hidden;
}

/* The session header: the page's own ground with a hairline edge (nothing
   frosted recomposites over a live terminal), the session, its project and
   its state. */
.app-head {
  position: relative;
  z-index: 1;
  display: grid;
  flex: none;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 4px;
  align-items: center;
  height: calc(var(--status-h) + 32px);
  padding: var(--status-h) 8px 0 3px;
  background: var(--base);
  box-shadow: 0 0.5px 0 var(--hairline);
}

.app-head-back {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  color: var(--tint);
}

.app-head-back svg {
  width: 12px;
  height: 12px;
}

.app-head-copy {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.app-head-copy b {
  overflow: hidden;
  color: var(--label);
  font-size: 10px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.app-head-copy small {
  overflow: hidden;
  color: var(--label-2);
  font-size: 7.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.app-head-actions {
  display: flex;
  gap: 2px;
}

.state-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 4px;
  color: var(--green-ink);
  font-size: 7.5px;
  font-weight: 510
}

.state-chip i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 3px currentColor
}

/* The word wears the ink; the dot and its glow are the status colour. */
.state-chip.is-running i {
  background: var(--green);
  box-shadow: 0 0 3px var(--green-glow)
}

/* Running and idle are two states of one control: the scene decides which. */
.state-chip.is-idle {
  display: none;
  color: var(--label-2)
}

[data-phase="idle"] .state-chip.is-running {
  display: none;
}

[data-phase="idle"] .state-chip.is-idle {
  display: inline-flex;
}

[data-phase="idle"] .state-chip.is-idle i {
  border: 1px solid currentColor;
  background: none;
  box-shadow: none
}

/* The terminal takes what the screen has left, so the key pad sits on the
   bottom edge. */
.mobile-device-term {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 6px 0 2px 7px;
  background: var(--term-bg);
  font-family: var(--mono);
  font-size: 7.2px;
  line-height: 1.5;
}

.mobile-device-term .line {
  min-height: 1.5em;
  color: var(--term-fg);
  white-space: pre;
  overflow: hidden;
}

/* The two-row utility pad: seven columns sharing one grid, so the arrows
   draw an inverted T. Keys are flat caps of fill on the page's ground. */
.keypad {
  display: grid;
  flex: none;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px 3px;
  padding: 5px 4px 10px;
  background: var(--base);
  box-shadow: inset 0 0.5px 0 var(--hairline)
}

.key {
  display: grid;
  place-items: center;
  height: 21px;
  padding: 0 1px;
  border-radius: 5px;
  background: var(--fill);
  color: var(--label);
  font-size: 6.4px;
  font-weight: 510
}

.key.is-arrow {
  background: var(--fill-2);
  color: var(--label);
  font-size: 8.5px
}

.key-mirror {
  transform: scaleX(-1);
}


/* ------------------------------------------------------------------ toast --- */

/* The completion notice: frosted, floating on layered shadows. */
.toast {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  max-width: 340px;
  padding: 10px 14px 10px 10px;
  border-radius: 14px;
  background: var(--material-thick);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
  box-shadow: var(--highlight), 0 0 0 0.5px var(--hairline), var(--shadow-float);
  font-size: 12.5px;
  opacity: 0;
  transform: translateY(10px) scale(0.96);
  transition: opacity 360ms var(--ease-out-soft), transform var(--spring-gentle-ms) var(--spring-gentle);
}

.toast[data-state="in"] {
  opacity: 1;
  transform: none;
}

.toast[data-state="out"] {
  opacity: 0;
  transform: translateY(-8px) scale(0.98);
}

.toast-icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: var(--green-fill);
  color: var(--green-ink);
}

.toast-icon svg {
  width: 15px;
  height: 15px;
}

.toast-copy {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.toast-copy b {
  color: var(--label);
  font-size: 12.5px;
  font-weight: 600;
}

.toast-copy small {
  overflow: hidden;
  color: var(--label-2);
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------------------------------------------------- the pushed notice --- */

/* A notification dropping in over the app, carrying the app's own icon. It
   slides in and out past the screen's top edge and never fades, so the icon
   on it is always whole. */
.push {
  position: absolute;
  top: calc(var(--status-h) + 6px);
  right: 8px;
  left: 8px;
  z-index: 9;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 14px;
  background: var(--material-thick);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
  box-shadow: var(--highlight), 0 0 0 0.5px var(--hairline), 0 10px 28px -8px rgba(0, 0, 0, 0.5);
  transform: translateY(-200%);
  transition: transform var(--spring-gentle-ms) var(--spring-gentle);
}

.push[data-state="in"] {
  transform: none;
}

.push-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
}

.push-copy {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.push-copy b {
  color: var(--label);
  font-size: 9.5px;
  font-weight: 600;
}

.push-copy small {
  overflow: hidden;
  color: var(--label-2);
  font-size: 8px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------------------------------------------------- the pairing scan --- */

/* The camera, looking at the desktop's code: dark in either theme, because
   it is a camera feed. The backdrop is a variable so a screen that also takes a
   theme surface (the tour's .tour-screen) can be pointed back at it. */
.scan {
  --scan-backdrop: radial-gradient(ellipse 90% 60% at 50% 45%, #1d1e22, #070708 75%);
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  flex: 1;
  min-height: 0;
  padding: calc(var(--status-h) + 8px) 12px 16px;
  background: var(--scan-backdrop);
}

.scan-head {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  color: #f5f5f7;
  font-size: 12px;
  font-weight: 600;
}

.scan-head svg {
  width: 14px;
  height: 14px;
  color: #2e9bff;
}

.scan-view {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
}

/* The reticle: four corners just outside the plate, an aim rather than a
   crop guide. */
.scan-corner {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 2.5px solid #2e9bff;
  transition: border-color 200ms var(--ease-out-soft);
}

.scan-corner.tl {
  top: 24%;
  left: 20%;
  border-right: 0;
  border-bottom: 0;
  border-radius: 7px 0 0 0;
}

.scan-corner.tr {
  top: 24%;
  right: 20%;
  border-bottom: 0;
  border-left: 0;
  border-radius: 0 7px 0 0;
}

.scan-corner.bl {
  bottom: 24%;
  left: 20%;
  border-top: 0;
  border-right: 0;
  border-radius: 0 0 0 7px;
}

.scan-corner.br {
  right: 20%;
  bottom: 24%;
  border-top: 0;
  border-left: 0;
  border-radius: 0 0 7px 0;
}

.scan-plate {
  width: 58%;
  padding: 8px;
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 10px 30px -6px rgba(0, 0, 0, 0.8);
}

.scan-plate img {
  display: block;
  width: 100%;
  height: auto;
}

/* The line the scanner sweeps: a 2px background on a track that spans the
   reticle, moved by background-position (a transform would move it by its
   own 2px height, not the distance it has to travel). */
.scan-line {
  position: absolute;
  inset: 25% 21%;
  background-image: linear-gradient(90deg, transparent, #2e9bff, transparent);
  background-repeat: no-repeat;
  background-size: 100% 2px;
  filter: drop-shadow(0 0 6px rgba(46, 155, 255, 0.7));
}

.scan-foot {
  padding-top: 10px;
  color: rgba(235, 235, 245, 0.62);
  font-size: 9px;
  line-height: 1.35;
  text-align: center;
}

/* The phone in a text column, narrowed a little so it does not dominate the
   split it sits beside. Two classes, so it wins over .mobile-device whatever
   the load order. */
.mobile-device.mobile-device-narrow {
  width: min(100%, calc(var(--mobile-device-w, 244px) * 0.94));
  margin-inline: auto;
}
