/* The web shell freshness notice (web-shell-freshness.js) stays fixed and centred at the
   top over everything. Reload chips dock in the visible page header when one is available;
   this shared fixed surface is their body-level fallback. */
.web-shell-notice,
.web-shell-update-chip {
  position: fixed;
  top: calc(var(--safe-top) + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  margin: 0;
  padding: var(--control-pad-y) var(--control-pad-x);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface-raised);
  color: var(--ink);
}

.web-shell-notice:empty { display: none }

/* The "Update ready" chip: placed and surfaced by the shared rule above, plus what a button
   adds -- tapping it is the person's explicit choice to reload now. No display set, so
   [hidden] still hides it. */
.web-shell-update-chip {
  min-height: var(--touch-min);
  font: inherit;
  cursor: pointer;
}

.car-night-nudge {
  font: inherit;
  min-height: var(--touch-min);
  cursor: pointer;
  white-space: nowrap;
}

/* A docked Reload chip shares a page header action row before Settings, while the
   body-level rule above remains its fallback. */
.app-page-header > .web-shell-update-chip {
  position: static;
  transform: none;
  z-index: auto;
  flex: none;
  min-height: var(--control-min);
  margin-block: calc(-1 * var(--space-xs));
  padding: var(--control-pad-y) var(--control-pad-x);
  font-size: var(--text-support);
}

/* On Home, this places the docked Reload chip and the car night-mode chip below weather. */
.today-header > .web-shell-update-chip,
.today-header > .car-night-nudge {
  position: static;
  transform: none;
  z-index: auto;
  grid-column: 2;
  grid-row: 2;
  justify-self: end;
  min-height: 0;
  margin-block: 0;
  padding-block: var(--space-xs);
  font-size: var(--text-support);
}

/* With no weather occupying the first right-hand cell, let the chip rise into it. */
.today-header:has(> .today-weather-slot[hidden]) > .web-shell-update-chip,
.today-header:has(> .today-weather-slot[hidden]) > .car-night-nudge {
  grid-row: auto;
}

/* The "Couldn't load" notice (chat.js syncModuleFailureNotice): shown on a display whose
   script failed to start. Same placement vocabulary as the chip above, lower so it sits
   under the header rather than over it. No display set, so [hidden] still hides it. */
.module-failure-notice {
  position: fixed;
  top: 5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  margin: 0;
  padding: var(--control-pad-y) var(--control-pad-x);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface-raised);
  color: var(--ink);
}

.module-failure-notice button {
  min-height: var(--touch-min);
  padding: 0 var(--space-r2);
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.pair-page main {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  max-width: 28rem;
  margin: 0 auto;
  padding: max(var(--page-gutter), var(--safe-top)) max(var(--page-gutter), var(--safe-right)) max(1.5rem, var(--safe-bottom)) max(var(--page-gutter), var(--safe-left));
}

body:is(.pair-page, .restore-page) [hidden] { display: none; }

.pair-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-r2);
}

.pair-header h1 { margin: 0; }

.pair-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-r2);
  padding: var(--card-pad);
  background: var(--qr-ground);
  border-radius: var(--card-radius);
}

.pair-brand img {
  display: block;
  /* The PNG ground is opaque near-white (about 254), so a small brightness lift clamps it to the card's pure white instead of showing a faint box. */
  filter: brightness(1.02);
  width: min(60vmin, 100%);
  height: auto;
}

#pair-root[data-offer] .pair-brand {
  flex-direction: column;
  gap: var(--space-r3);
  margin-top: var(--space-r4);
}

.pair-page button,
.pair-page .app-primary-button,
.pair-page .app-quiet-button {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 56px;
  text-decoration: none;
}

.pair-page .app-quiet-button { border-style: none; }

/* Pairing choices remain quiet controls in both states; the shared selected treatment and the
   check mark make the radio-style choice legible without relying on colour alone. */
.pair-choice-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.pair-choice-groups[hidden] { display: none; }


.pair-choice-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

.pair-choice-option {
  position: relative;
  justify-content: flex-start;
  gap: var(--space-r2);
  text-align: start;
}

/* The page-wide quiet-button rule centers its contents; choice marks share one content-edge
   column instead. The mark itself is the app's shared ring primitive. */
.pair-page .app-quiet-button.pair-choice-option {
  justify-content: flex-start;
}

.pair-choice-option .app-check {
  cursor: inherit;
}

@media (orientation: landscape) and (min-width: 48rem) {
  .pair-page main {
    max-width: 60rem;
    gap: var(--space-r2);
    padding-block: var(--space-r2);
  }

  .pair-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-r2);
  }

  .pair-header h1 { font-size: var(--text-detail-title); }

  .pair-page .pair-surface {
    gap: var(--space-r2);
  }

  .pair-choice-groups {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: var(--space-r2);
  }

  .pair-choice-groups[hidden] {
    display: none;
  }


  .pair-page .pair-choice-option {
    min-height: 2.75rem;
  }
}

/* Settings -> AI usage: the month's total, two breakdown lists and a 30-day sparkline
   (ai-usage.js draws all of it). The sparkline stroke is in screen pixels
   (non-scaling-stroke), so its width is too, not viewBox units. */
.ai-usage-total {
  margin: 0;
  color: var(--ink);
  font-size: var(--text-page-title);
  font-variant-numeric: tabular-nums;
}

.ai-usage-heading {
  margin-block-start: var(--space-lg);
}

.ai-usage-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-xl);
  padding-block: var(--space-lg);
}

.ai-usage-row .settings-row-main {
  display: flex;
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  gap: var(--space-2xs);
  overflow-wrap: anywhere;
}

@media (max-width: 47.99rem) {
  /* Large text keeps the usage name flexible so the amount remains visible. */
  :root[data-text-size="large"] .ai-usage-row .settings-row-main {
    flex: 1 1 0;
  }
}

.ai-usage-amount {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.ai-usage-trend {
  display: block;
  width: 100%;
  height: 3rem;
}

.ai-usage-trend polyline {
  fill: none;
  stroke: var(--chart-ink);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* Settings -> Devices: rows, icons and dialogs (devices.js builds all of them). */
.devices-add-row {
  display: flex;
  margin-bottom: var(--space-r3);
}

.devices-row .settings-row-main {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: var(--space-2xs);
}

.devices-row .app-row-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.devices-name {
  min-width: 0;
}

.devices-row .app-row-meta {
  overflow-wrap: anywhere;
}

.devices-row {
  column-gap: var(--list-lead-gap);
}

.devices-icon {
  display: grid;
  flex: none;
  place-items: center;
  color: var(--muted);
}

.devices-icon svg {
  display: block;
  width: 22px;
  height: 22px;
}

.devices-dialog .app-dialog-body {
  overflow-y: auto;
  overflow-wrap: anywhere;
}

.devices-dialog .app-dialog-body > p:first-child {
  margin-top: 0;
}

.app-qr {
  box-sizing: border-box;
  width: min(16rem, 100%);
  padding: var(--space-xl);
  margin: var(--space-r3) auto;
  border-radius: var(--radius-nested);
  /* A QR needs a white quiet zone in every theme. */
  background: var(--qr-ground);
}

.app-qr:empty {
  display: none;
}

.app-qr svg {
  display: block;
  width: 100%;
  height: auto;
}

.app-code {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-page-title);
  letter-spacing: 0.12em;
  user-select: all;
  overflow-wrap: anywhere;
}

.app-code-pending {
  color: var(--muted);
}

.devices-pending-identity {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
  margin: 0 0 var(--space-r3);
}

.devices-pending-identity .settings-row-main {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.devices-pending-identity .app-row-title,
.devices-pending-identity .app-row-meta {
  overflow-wrap: anywhere;
}

.devices-code-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-r3);
}
.devices-code-form[hidden] { display: none; }

/* The shared person picker (person-choice.js): its radiogroup and the one-field add form that
   replaces the add row in place. */
.person-choice {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.person-choice .pair-choice-option {
  display: flex;
  align-items: center;
  width: 100%;
}

.person-choice-add {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.devices-offer-qr-label {
  margin: var(--space-r3) 0 0;
  text-align: center;
}

.devices-code-form .app-field {
  font-size: var(--text-page-title);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* The "My pages" viewer (pages-viewer.js): a full-height overlay above the app, a back bar over the page's sandboxed frame. */
.pages-viewer {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: flex;
  flex-direction: column;
  background: var(--page);
  /* The command bar stays on screen under the viewer. */
  padding-bottom: var(--command-bar-space);
}


/* The bar stays above the page overlay so chat can act on the open page. */
.pages-viewer-open .command-bar { z-index: 46; }

/* The gutter sits on the bar and status line only: the frame runs edge to edge because the
   kit's own body padding is the page's single gutter. */
.pages-viewer > .app-back-bar,
.pages-viewer > .app-status {
  padding-inline: var(--list-gutter);
}

/* Back and the page title share one line so the page frame starts higher. */
.pages-viewer > .app-back-bar { flex-wrap: nowrap; padding-bottom: 0; }
.pages-viewer > .app-back-bar > .app-toolbar-title { flex: 1 1 0; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.pages-viewer-share { display: inline-flex; align-items: center; gap: var(--space-r2); min-height: var(--touch-min); }
.pages-viewer-share[hidden] { display: none; }
.pages-viewer-settings-actions { flex-direction: column; align-items: stretch; }

.pages-viewer[hidden] {
  display: none;
}

/* A folded player chip floats over the frame's bottom-right corner; the frame ends above it. */
body.pages-viewer-open:has(.podcast-mini[data-folded="true"] .podcast-mini-chip:not([hidden])) .pages-viewer { padding-bottom: calc(var(--command-bar-space) + var(--touch-min) + var(--stack-gap)); }

.pages-viewer-frame {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  border: 0;
}

/* A hidden frame runs a page's action. */
.pages-action-frame { display: none; }

.pages-score {
  flex: 0 0 55%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--panel-subtle);
  border-bottom: 1px solid var(--line-strong);
}
.pages-score .app-quiet-button { min-height: var(--touch-min); min-width: var(--touch-min); }

.pages-score > .app-toolbar { flex-wrap: nowrap; gap: var(--space-sm); padding-inline: var(--list-gutter); }
.pages-score-page { flex: 1 1 auto; text-align: center; font-size: var(--text-detail-meta); }
.pages-score-pages { flex: 1 1 auto; min-height: 0; overflow: auto; touch-action: pan-x pan-y; padding: var(--space-sm); }
.pages-score-canvas { display: block; margin-inline: auto; border-radius: var(--card-radius); box-shadow: var(--shadow-card); }
.pages-viewer-score-open > .pages-viewer-frame { flex: 1 1 0; }

.update-control {
  position: relative;
}

/* The backup page stacks its sections, and the S3 form's label/field rows, on one gap. */
#backup-body {
  display: grid;
  gap: var(--space-md);
}

/* The backup notice sits a card-gap above the Backup card. */
#backup-setup-notice {
  margin-bottom: var(--space-md);
}

@media (max-width: 47.99rem) {
  :root[data-text-size="large"] #backup-body .app-actions {
    flex-direction: column;
    align-items: flex-start;
  }
}

.backup-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
}

.backup-form .app-field {
  width: 100%;
  min-width: 0;
}

/* The sheet's code is a long string: body size and tighter tracking keep it to two lines at the Large text size. */
.backup-sheet .app-code {
  font-size: var(--text-item);
  letter-spacing: 0.06em;
}

/* The recovery sheet is the only thing a print shows: a plain page in the system's paper colours. */
@media print {
  /* Print must beat every component rule. */
  body > *:not(.backup-sheet) {
    display: none !important;
  }

  .backup-sheet,
  .backup-sheet .app-dialog-frame {
    position: static;
    display: block;
    width: auto;
    max-width: none;
    height: auto;
    max-height: none;
    overflow: visible;
    border: 0;
    box-shadow: none;
    background: Canvas;
    color: CanvasText;
  }

  .backup-sheet .app-dialog-footer {
    display: none;
  }

  .backup-sheet .app-row-meta,
  .backup-sheet .app-code {
    color: CanvasText;
  }
}
