/* The front page only. Loaded by index.html, nowhere else.
 *
 * The device mockups are sized in `em` throughout, with the frame's own
 * font-size derived from its container width — so 1em is 10px at full size
 * and every measurement inside is the app's real one divided by ten. The rail
 * is 7.6em because theme.RAIL_WIDTH is 76. A frame therefore scales smoothly
 * from a 1200px column to a phone without a single breakpoint, and a real
 * screenshot dropped in later lands at exactly the same size.
 */

/* The reading pages are 62rem for line length. A product page is not being
   read that way: it needs the width, and every device frame scales to fill
   whatever column it is handed. */
.stage, .clients, .feature, .closing { --wrap: 76rem; }

/* --- reveal on scroll ---------------------------------------------------- */

/* Hidden only once the script has confirmed it can reveal them again. With no
 * JavaScript, or with reduced motion asked for, everything is simply visible. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity .7s cubic-bezier(.22, .61, .36, 1),
              transform .7s cubic-bezier(.22, .61, .36, 1);
}
.js [data-reveal].seen { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* --- the hero ------------------------------------------------------------ */

.stage {
  position: relative;
  padding: clamp(3rem, 7vw, 6rem) 0 0;
  text-align: center;
  overflow: hidden;
  background:
    radial-gradient(56rem 34rem at 50% -12%,
      color-mix(in srgb, var(--accent-lift) 26%, transparent), transparent 68%),
    radial-gradient(40rem 26rem at 88% 8%,
      color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%);
}

.chip-version {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .3rem .35rem .3rem .8rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); text-decoration: none; font-size: .85rem;
  color: var(--muted); margin-bottom: 1.6rem;
}
.chip-version b {
  background: var(--accent); color: var(--accent-ink);
  border-radius: 999px; padding: .1rem .6rem; font-size: .8rem;
}
.chip-version:hover { border-color: var(--accent); color: var(--ink); }

.stage h1 {
  font-size: clamp(2.4rem, 6.4vw, 4.6rem);
  line-height: 1.03;
  letter-spacing: -0.035em;
  margin: 0 auto .9rem;
  max-width: 16ch;
  text-wrap: balance;
}
.stage-sub {
  font-size: clamp(1.05rem, 1.9vw, 1.4rem);
  color: var(--muted);
  max-width: 46ch; margin: 0 auto 1.8rem;
  text-wrap: pretty;
}
.stage-actions { display: flex; gap: .8rem; justify-content: center; flex-wrap: wrap; margin: 0 0 1rem; }
.stage-note { color: var(--muted); font-size: .88rem; margin: 0 0 2.5rem; }

/* Desktop window with the phone standing in front of its lower right corner.
 * The phone is absolutely placed so it can overlap; below 60rem it drops out
 * of the overlap and sits beside the window instead. */
.stage-devices {
  position: relative;
  max-width: 68rem; margin: 0 auto;
  padding: 0 1.25rem 4rem;
}
.stage-desktop { container-type: inline-size; width: 86%; }
.stage-phone {
  position: absolute; right: .25rem; bottom: 0; width: 15%;
  min-width: 132px;
}

/* Side by side, two 170px-wide devices are two illegible smudges. Keep the
   window at full width and let the phone go on overlapping it. */
@media (max-width: 60rem) {
  /* The phone is taller than the window and hangs above it, so the note
     above needs the clearance or the two collide. */
  .stage-note { margin-bottom: 5rem; }
  .stage-devices { padding-bottom: 5rem; }
  .stage-desktop { width: 100%; }
  .stage-phone { right: 1.25rem; bottom: .5rem; width: 29%; }
}

/* Narrower than this, three panes cannot be read at any scale — so the
   mockup drops the details pane, exactly as the app itself would if it were
   this size. A picture of a cramped app helps nobody. */
@media (max-width: 48rem) {
  .pane-details { display: none; }
  .rep-table th:nth-child(n+3), .rep-table td:nth-child(n+3) { display: none; }
  .pane-list { width: 15em; flex-basis: 15em; }
  .feature-visual.d-both .dev-desktop { width: 82%; }
  .feature-visual.d-both .dev-phone { width: 24%; }
}

/* --- the two clients ----------------------------------------------------- */

.clients { border-top: 1px solid var(--line); background: var(--panel); }
.clients-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem;
  padding: 3rem 1.25rem;
}
.clients-grid h2 { font-size: 1.25rem; margin: 0 0 .5rem; letter-spacing: -.01em; }
.clients-grid p { margin: 0 0 .5rem; color: var(--muted); max-width: 40ch; }
.clients-grid code { background: var(--bg); padding: .05rem .35rem; border-radius: 5px; }
@media (max-width: 46rem) { .clients-grid { grid-template-columns: 1fr; gap: 1.8rem; } }

/* --- feature sections ---------------------------------------------------- */

.feature { padding: clamp(3rem, 7vw, 6rem) 0; border-bottom: 1px solid var(--line); }
.feature.flip { background: var(--panel); }   /* alternating, keyed to the flip */
.feature-grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
.feature.flip .feature-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.feature.flip .feature-copy { order: 2; }
.feature.flip .feature-visual { order: 1; }
@media (max-width: 56rem) {
  .feature-grid, .feature.flip .feature-grid { grid-template-columns: 1fr; gap: 2rem; }
  .feature.flip .feature-copy, .feature.flip .feature-visual { order: initial; }
}

.feature-copy .kicker {
  text-transform: uppercase; letter-spacing: .11em; font-size: .76rem;
  font-weight: 650; color: var(--accent); margin: 0 0 .7rem;
}
.feature-copy h2 {
  font-size: clamp(1.7rem, 3.4vw, 2.5rem); line-height: 1.1;
  letter-spacing: -0.028em; margin: 0 0 .9rem; text-wrap: balance;
}
.feature-copy p { color: var(--muted); font-size: 1.02rem; max-width: 46ch; }
.feature-copy strong { color: var(--ink); }
.feature-copy code { background: var(--bg); border: 1px solid var(--line); padding: .05rem .3rem; border-radius: 5px; font-size: .9em; }

.ticks { list-style: none; padding: 0; margin: 1.4rem 0 0; display: grid; gap: .6rem; }
.ticks li { display: grid; grid-template-columns: 1.15rem 1fr; gap: .65rem; align-items: start; font-size: .95rem; }
.ticks svg { width: 1.15rem; height: 1.15rem; color: var(--accent); margin-top: .15rem; }

.feature-visual { container-type: inline-size; }
.feature-visual.d-both { position: relative; padding-bottom: 2.5rem; }
.feature-visual.d-both .dev-desktop { width: 85%; }
.feature-visual.d-both .dev-phone {
  position: absolute; right: 0; bottom: 0; width: 20%; min-width: 96px;
}
.feature-visual.d-phone { display: flex; justify-content: center; }
.feature-visual.d-phone .dev-phone { width: clamp(180px, 36%, 248px); }

/* --- closing ------------------------------------------------------------- */

.closing { padding: clamp(3.5rem, 8vw, 6.5rem) 0; text-align: center; }
.closing h2 {
  font-size: clamp(1.9rem, 4.6vw, 3.2rem); letter-spacing: -.03em;
  margin: 0 auto .7rem; max-width: 18ch; line-height: 1.08; text-wrap: balance;
}
.closing p { color: var(--muted); margin: 0 auto 1.6rem; max-width: 44ch; }

/* ==========================================================================
   The app's own palettes.

   Straight out of `meshcore/ui/theme.py` (LIGHT and DARK) and
   `android/qml/Theme.qml`. The toggle by the hero sets `data-app-theme` on
   the document; with nothing set, the mockups follow the reader's system
   scheme like the rest of the page does.
   ========================================================================== */

:root {
  --a-window: #F0F0F4;  --a-rail: #EBEBF0;      --a-surface: #FFFFFF;
  --a-alt:    #F4F4F8;  --a-border: #E0E0E6;    --a-text: #1B1B1F;
  --a-muted:  #5E5E68;  --a-faint: #8A8A94;     --a-accent: #5B5FC7;
  --a-soft:   #E8EAFA;  --a-on-accent: #FFFFFF; --a-success: #12A150;
  --a-warning:#C77A00;  --a-danger: #C4314B;

  --p-bg: #F7F8FA;      --p-surface: #FFFFFF;   --p-alt: #EEF0F4;
  --p-border: #DDE1E7;  --p-text: #1A1C1F;      --p-muted: #6B7280;
  --p-accent: #4655C8;  --p-accent-text: #FFFFFF; --p-warning: #C77A00;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-app-theme="light"]) {
    --a-window: #17171A;  --a-rail: #1F1F23;      --a-surface: #242429;
    --a-alt:    #2D2D33;  --a-border: #35353D;    --a-text: #F2F2F5;
    --a-muted:  #A8A8B3;  --a-faint: #7A7A85;     --a-accent: #8B8FE8;
    --a-soft:   #33334D;  --a-on-accent: #15151A; --a-success: #3FD07A;
    --a-warning:#E8A33D;  --a-danger: #E8697F;

    --p-bg: #121316;      --p-surface: #1B1D21;   --p-alt: #24272C;
    --p-border: #33373E;  --p-text: #E8EAED;      --p-muted: #9AA0A8;
    --p-accent: #7B8CFF;  --p-accent-text: #FFFFFF; --p-warning: #E8A33D;
  }
}

:root[data-app-theme="dark"] {
  --a-window: #17171A;  --a-rail: #1F1F23;      --a-surface: #242429;
  --a-alt:    #2D2D33;  --a-border: #35353D;    --a-text: #F2F2F5;
  --a-muted:  #A8A8B3;  --a-faint: #7A7A85;     --a-accent: #8B8FE8;
  --a-soft:   #33334D;  --a-on-accent: #15151A; --a-success: #3FD07A;
  --a-warning:#E8A33D;  --a-danger: #E8697F;

  --p-bg: #121316;      --p-surface: #1B1D21;   --p-alt: #24272C;
  --p-border: #33373E;  --p-text: #E8EAED;      --p-muted: #9AA0A8;
  --p-accent: #7B8CFF;  --p-accent-text: #FFFFFF; --p-warning: #E8A33D;
}

/* `theme.AVATAR_COLOURS`, in order. Same ten in both themes — they were
   picked to hold white text in either. */
.avatar.c1 { background: #C4314B; } .avatar.c2 { background: #B146C2; }
.avatar.c3 { background: #5B5FC7; } .avatar.c4 { background: #0C7A8C; }
.avatar.c5 { background: #107C41; } .avatar.c6 { background: #986F0B; }
.avatar.c7 { background: #C36A2D; } .avatar.c8 { background: #4F6BED; }
.avatar.c9 { background: #8764B8; } .avatar.c10 { background: #00838F; }

/* --- the theme switch ---------------------------------------------------- */

.appswitch {
  display: inline-flex; align-items: center; gap: .5rem;
  border: 1px solid var(--line); border-radius: 999px;
  padding: .25rem; background: var(--bg); font-size: .82rem;
}
.appswitch span { color: var(--muted); padding-left: .6rem; }
.appswitch button {
  font: inherit; font-weight: 600; cursor: pointer; color: var(--muted);
  background: none; border: 0; border-radius: 999px; padding: .3rem .85rem;
}
.appswitch button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.switch-holder { display: flex; justify-content: center; margin: 0 0 1.6rem; }
/* No script, no switch: it would be a control that does nothing. The class
   is its own, not the reveal script's — someone who asked for reduced motion
   still gets the switch. */
html:not(.app-ready) .switch-holder { display: none; }

/* ==========================================================================
   The device frames. 1em = 10px at full size.
   ========================================================================== */

.dev-desktop {
  font-size: clamp(4.4px, 1.02cqi, 10px);
  width: 100%;
  border-radius: 1.2em;
  border: 0.1em solid var(--a-border);
  background: var(--a-window);
  overflow: hidden;
  box-shadow: 0 2.4em 5em -1.6em rgba(28, 30, 60, .38),
              0 .3em 1em -.4em rgba(28, 30, 60, .2);
  color: var(--a-text);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  text-align: left;
}

/* A window on a Linux desktop: a title bar the window manager draws, with
   its controls on the right. Not three coloured dots — this app has never
   run on a Mac. */
.dev-bar {
  height: 3.6em; display: flex; align-items: center; justify-content: space-between;
  padding: 0 1.2em; background: var(--a-rail);
  border-bottom: 0.1em solid var(--a-border);
}
.dev-title { font-size: 1.2em; font-weight: 600; color: var(--a-text); }
.dev-wm { display: flex; gap: .7em; }
.dev-wm i {
  width: 1.9em; height: 1.9em; border-radius: 50%; background: var(--a-alt);
  position: relative;
}
.dev-wm i::before {
  content: ""; position: absolute; inset: 0; margin: auto;
  background: var(--a-muted);
}
.dev-wm .min::before { width: .7em; height: .12em; }
.dev-wm .max::before { width: .65em; height: .65em; border: .12em solid var(--a-muted); background: none; }
.dev-wm .cls::before {
  width: .75em; height: .12em; transform: rotate(45deg);
  box-shadow: 0 0 0 0 transparent;
}
.dev-wm .cls::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: .75em; height: .12em; background: var(--a-muted); transform: rotate(-45deg);
}
.dev-body { display: flex; height: 46em; overflow: hidden; }
.dev-shot { display: block; width: 100%; height: auto; }

.dev-status {
  height: 2.6em; display: flex; align-items: center; justify-content: space-between;
  padding: 0 1.2em; border-top: 0.1em solid var(--a-border);
  background: var(--a-window); color: var(--a-muted); font-size: 1.05em;
}

.dev-rail {
  width: 7.6em; flex: 0 0 7.6em; background: var(--a-rail);
  border-right: 0.1em solid var(--a-border); padding: .6em 0;
  display: flex; flex-direction: column;
}
.dev-dest {
  position: relative; height: 7em; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .35em; color: var(--a-muted);
  text-align: center;
}
.dev-dest svg { width: 2.3em; height: 2.3em; }
.dev-dest em { font-style: normal; font-size: 1em; line-height: 1.15; }
.dev-dest.on { background: var(--a-surface); color: var(--a-accent); }
.dev-dest.on::before {
  content: ""; position: absolute; left: 0; top: .9em; bottom: .9em;
  width: .3em; border-radius: 0 .3em .3em 0; background: var(--a-accent);
}
.dev-content { flex: 1 1 auto; min-width: 0; background: var(--a-surface); }

/* --- chat --------------------------------------------------------------- */

.dev-panes { display: flex; height: 100%; min-height: 0; }
.dev-panes > * { overflow: hidden; }
.pane-list {
  width: 23em; flex: 0 0 23em; border-right: 0.1em solid var(--a-border);
  background: var(--a-surface);
}
.list-search {
  margin: .9em 1em; padding: .55em .8em; border-radius: .8em;
  background: var(--a-alt); color: var(--a-faint); font-size: 1.1em;
}
.list-section {
  display: flex; align-items: center; gap: .5em; padding: .5em 1em .3em;
  font-size: .95em; font-weight: 600; color: var(--a-muted);
  text-transform: uppercase; letter-spacing: .05em;
}
.list-section b { font-weight: 400; color: var(--a-faint); }
.list-section .caret { font-size: .9em; }

.conv { position: relative; display: flex; gap: .9em; align-items: center; padding: .75em 1em; }
.conv.on { background: var(--a-soft); }
.avatar {
  width: 3.2em; height: 3.2em; flex: 0 0 3.2em; border-radius: 50%;
  display: grid; place-items: center; color: #fff; font-size: 1em; font-weight: 600;
}
.avatar.square { border-radius: 1em; }
.conv-text { display: grid; gap: .3em; min-width: 0; flex: 1 1 auto; }
.conv-top, .conv-bot { display: flex; align-items: baseline; justify-content: space-between; gap: .6em; }
.conv-top b { font-size: 1.15em; font-weight: 400; color: var(--a-text); }
.conv-top b.unread { font-weight: 600; }
.when { font-style: normal; font-size: .95em; color: var(--a-faint); flex: 0 0 auto; }
.conv-bot i {
  font-style: normal; font-size: 1.05em; color: var(--a-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.badge {
  font-style: normal; font-size: .9em; background: var(--a-accent);
  color: var(--a-on-accent); border-radius: 1em; padding: .05em .55em; flex: 0 0 auto;
}
.star { position: absolute; left: 3.3em; bottom: .8em; font-size: 1.1em; color: var(--a-accent); }

.pane-chat { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.chat-head {
  display: flex; align-items: center; gap: 1.2em; padding: 1em 1.6em;
  border-bottom: 0.1em solid var(--a-border);
}
.chat-heading { display: grid; gap: .1em; flex: 1 1 auto; min-width: 0; }
.chat-heading b { font-size: 1.35em; font-weight: 600; }
.chat-heading i { font-style: normal; font-size: .95em; color: var(--a-muted); }
.chat-tool { color: var(--a-muted); }
.chat-tool svg { width: 2em; height: 2em; }

.bubbles { flex: 1 1 auto; min-height: 0; overflow: hidden; padding: 1.2em 1.6em; display: flex; flex-direction: column; gap: .5em; }
.day {
  align-self: center; font-size: .95em; color: var(--a-faint);
  background: var(--a-alt); border-radius: 1em; padding: .25em .9em; margin-bottom: .4em;
}
.bubble {
  max-width: 68%; padding: 1.2em; border-radius: 1.2em; font-size: 1.15em;
  line-height: 1.35; display: grid; gap: .45em;
}
.bubble.in { background: var(--a-alt); align-self: flex-start; border-bottom-left-radius: .3em; }
.bubble.own { background: var(--a-soft); align-self: flex-end; border-bottom-right-radius: .3em; }
.bubble .meta { font-size: .8em; color: var(--a-faint); text-align: right; }
.bubble .meta u { color: var(--a-accent); text-decoration: none; border-bottom: .08em solid currentColor; }
.path {
  align-self: flex-start; display: flex; gap: .5em; align-items: center;
  font-size: 1em; color: var(--a-accent); background: var(--a-soft);
  border-radius: 1em; padding: .5em .9em;
}
.path b { color: var(--a-faint); font-weight: 400; }
.composer {
  border-top: 0.1em solid var(--a-border); display: flex; align-items: center;
  gap: 1em; padding: .9em 1.6em;
}
.composer-box {
  flex: 1 1 auto; background: var(--a-alt); border-radius: .8em;
  padding: .6em .9em; color: var(--a-faint); font-size: 1.15em;
}
.composer em { font-style: normal; font-size: 1em; color: var(--a-faint); }

.pane-details {
  width: 19em; flex: 0 0 19em; border-left: 0.1em solid var(--a-border);
  background: var(--a-surface);
}
.det-head {
  display: flex; align-items: center; gap: .9em; padding: 1em 1.2em .5em;
  font-size: 1.15em;
}
.det-head b { font-weight: 600; }
.kv { display: grid; gap: .05em; padding: .36em 1.2em; font-size: 1em; }
.kv span { color: var(--a-faint); }
.kv b { font-weight: 500; color: var(--a-text); word-break: break-word; }
.det-section {
  padding: .7em 1.2em .3em; font-size: .95em; font-weight: 600;
  color: var(--a-muted); text-transform: uppercase; letter-spacing: .05em;
}
.spark { padding: 0 1.2em; color: var(--a-accent); }
.spark svg { width: 100%; height: 3.4em; }

/* --- map ---------------------------------------------------------------- */

.dev-map { position: relative; height: 100%; }
.dev-map svg { width: 100%; height: 100%; display: block; }
.map-chip {
  position: absolute; left: 1.2em; bottom: 1.2em; background: var(--a-surface);
  border: 0.1em solid var(--a-border); border-radius: .8em; padding: .5em .9em;
  font-size: 1.05em; color: var(--a-muted);
}

/* --- repeaters ---------------------------------------------------------- */

.dev-repeater { height: 100%; padding: 1.2em 1.4em; display: flex; flex-direction: column; gap: .9em; }
.rep-top { display: flex; gap: .7em; align-items: center; }
.rep-search {
  flex: 1 1 auto; background: var(--a-alt); border-radius: .8em;
  padding: .55em .9em; color: var(--a-faint); font-size: 1.1em;
}
.rep-btn {
  background: var(--a-alt); border: 0.1em solid var(--a-border); border-radius: .8em;
  padding: .55em .9em; font-size: 1.05em; color: var(--a-text);
}
.rep-summary { font-size: 1.1em; color: var(--a-muted); }
.rep-summary b { color: var(--a-warning); font-weight: 600; }
.rep-table { width: 100%; border-collapse: collapse; font-size: 1.1em; }
.rep-table th {
  text-align: left; font-weight: 600; color: var(--a-muted); font-size: .92em;
  padding: .5em .6em; border-bottom: 0.1em solid var(--a-border);
}
.rep-table td { padding: .6em; border-bottom: 0.1em solid var(--a-alt); color: var(--a-text); }
.rep-table tr.stale td { color: var(--a-warning); }
.cli {
  margin-top: auto; padding: 1em; border-radius: .8em; background: #15151A;
  color: #E8EAFA; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05em; display: grid; gap: .35em;
}
.cli .ans { color: #8B8FE8; }

/* --- sync --------------------------------------------------------------- */

.dev-sync { height: 100%; padding: 1.4em; display: flex; flex-direction: column; gap: 1.2em; }
.sync-head { font-size: 1.35em; font-weight: 600; }
.sync-row { display: flex; align-items: center; gap: 1.4em; }
.sync-card {
  flex: 1 1 0; display: grid; gap: .45em; padding: 1.2em;
  border: 0.1em solid var(--a-border); border-radius: 1em; background: var(--a-window);
}
.sync-card b { font-size: 1.25em; }
.sync-card i { font-style: normal; font-size: 1.05em; color: var(--a-faint); }
.sync-card .sync-bar { display: block; height: .6em; border-radius: .3em; background: var(--a-alt); overflow: hidden; }
.sync-card .sync-bar em { display: block; height: 100%; background: var(--a-success); }
.sync-note { font-size: 1em; color: var(--a-success); }
.sync-flow { display: grid; gap: .4em; justify-items: center; flex: 0 0 9.6em; color: var(--a-accent); }
.sync-flow svg { width: 9.6em; }
.sync-flow em { font-style: normal; font-size: 1em; color: var(--a-muted); }
.sync-profiles { display: grid; gap: .7em; }
.sync-prof {
  display: flex; justify-content: space-between; align-items: baseline;
  border: 0.1em solid var(--a-border); border-radius: .8em; padding: .8em 1em;
  background: var(--a-window);
}
.sync-prof b { font-size: 1.15em; font-weight: 500; }
.sync-prof i { font-style: normal; font-size: 1.05em; color: var(--a-faint); }

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

.dev-phone { container-type: inline-size; width: 100%; }
.phone-screen {
  font-size: calc(100cqi / 39);          /* 39em wide = a 390px screen */
  aspect-ratio: 390 / 844;
  border-radius: 4.4em;
  border: .9em solid #23242B;            /* the hardware, not the theme */
  background: var(--p-bg);
  overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: 0 2em 4em -1.2em rgba(28, 30, 60, .45);
  color: var(--p-text);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  text-align: left;
}
.phone-head {
  padding: 3.2em 1.6em 1em; font-size: 1.5em; font-weight: 650;
  background: var(--p-surface); border-bottom: .08em solid var(--p-border);
}
.phone-body { flex: 1 1 auto; padding: 1.2em; display: flex; flex-direction: column; gap: .9em; overflow: hidden; }
.ph-search {
  background: var(--p-alt); border-radius: 1.8em; padding: 1em 1.3em;
  color: var(--p-muted); font-size: 1.35em;
}
.ph-conv { position: relative; display: flex; gap: 1.1em; align-items: center; padding: .55em .2em; }
.ph-conv .avatar { width: 4.6em; height: 4.6em; flex-basis: 4.6em; font-size: 1.2em; }
.ph-conv .conv-top b { font-size: 1.45em; color: var(--p-text); }
.ph-conv .when { font-size: 1.2em; color: var(--p-muted); }
.ph-conv .conv-bot i { font-size: 1.3em; color: var(--p-muted); }
.ph-conv .badge { background: var(--p-accent); color: var(--p-accent-text); font-size: 1.15em; }
.ph-conv .star { left: 4.4em; bottom: .2em; font-size: 1.4em; color: var(--p-warning); }

.ph-card, .ph-item {
  background: var(--p-surface); border: .08em solid var(--p-border);
  border-radius: 1.2em; padding: 1.1em; display: grid; gap: .25em;
}
.ph-card b { font-size: 1.45em; font-weight: 620; }
.ph-card i, .ph-item i { font-style: normal; font-size: 1.25em; color: var(--p-muted); }
.ph-item b { font-size: 1.2em; font-weight: 600; }
.ph-progress { height: 1em; border-radius: .5em; background: var(--p-border); overflow: hidden; }
.ph-progress em { display: block; height: 100%; background: var(--p-accent); }
.ph-note { font-size: 1.25em; color: var(--p-muted); }
.ph-section {
  font-size: 1.15em; color: var(--p-muted); margin-top: .4em;
  text-transform: uppercase; letter-spacing: .08em;
}

.phone-nav {
  height: 6.4em; flex: 0 0 6.4em; background: var(--p-surface);
  border-top: .08em solid var(--p-border); display: grid;
  grid-template-columns: repeat(4, 1fr);
}
.phone-nav span {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .3em; color: var(--p-muted);
}
.phone-nav svg { width: 2.4em; height: 2.4em; }
.phone-nav em { font-style: normal; font-size: 1.1em; }
.phone-nav .on { color: var(--p-accent); }

.phone-body .dev-map { flex: 1 1 auto; border-radius: 1em; overflow: hidden; }

/* Deeper shadow on a dark page; the frames themselves already switched. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .dev-desktop {
    box-shadow: 0 2.4em 5em -1.6em rgba(0, 0, 0, .6);
  }
}

/* Whatever is written on the front page row in the admin, kept out of the
   way of the feature sections. Empty by default. */
.extra { border-top: 1px solid var(--line); }
.extra .prose { padding-top: 3rem; }
