/* ============================================================================
   Drdesh — drdesh.app
   Static site styles. No build step, no framework, no third-party requests.
   Tokens follow docs/design/design-system.md v2 (§2 color, §3 type, §4 shape).
   Web-specific deviations from the app tokens are noted inline.

   This one stylesheet also dresses /privacy.html, /terms.html and /u.html —
   those pages are frozen, so the shared classes they use (.wrap, .policy,
   .profile, .btn-row, .e2e-note …) are kept alive at the bottom of the file.
   ========================================================================= */

/* ── Archivo (bundled, OFL — /fonts/OFL.txt) ─────────────────────────────── */
@font-face {
  font-family: "Archivo";
  src: url("/fonts/Archivo-400.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("/fonts/Archivo-600.ttf") format("truetype");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("/fonts/Archivo-800.ttf") format("truetype");
  font-weight: 800; font-style: normal; font-display: swap;
}

/* ── Tokens ──────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light dark;

  /* Semantic surfaces (§2.2) */
  --bg:            #efeae4;
  --surface:       #e4ddd5;
  --paper:         #faf7f3;   /* bubbleIn, doubles as the raised card fill   */
  --ink:           #241f1b;
  /* muted is darkened vs the app's 55% — 55% on #EFEAE4 is only 3.5:1, and
     web body copy must clear 4.5:1. 72% measures ~5.5:1.                    */
  --muted:         rgba(36, 31, 27, 0.72);
  --faint:         rgba(36, 31, 27, 0.66);   /* quiet secondary text (>=4.8:1) */
  --rule:          rgba(36, 31, 27, 0.12);
  /* DEVIATION (§2.2 puts ruleStrong at ink 40% / 45%): the web page uses it on
     large flat areas — diagram strokes, hairline dividers, the status pill —
     where 40% reads as a heavy box. 30% / 34% is the web value.              */
  --rule-strong:   rgba(36, 31, 27, 0.30);
  /* The visual boundary of a CONTROL is held to 3:1 (WCAG 1.4.11), which
     neither the web 30% nor the app's own 40% reaches on #EFEAE4 (1.86:1 and
     2.37:1). Outlined buttons use this token instead — 50% measures 3.08:1.  */
  --ctl-border:    rgba(36, 31, 27, 0.50);

  --accent:        #ec3013;   /* fills, rules, glyphs                        */
  --accent-text:   #a81800;   /* accentDeep — small accent text, 6.3:1 on bg */
  --accent-2:      #e15b47;
  --on-accent:     #ffffff;
  /* Filled buttons step one stop down the accent ramp: white on #EC3013 is
     4.2:1, which is short of AA for 15px button text. #DD2B0F clears it.     */
  --btn-bg:        #dd2b0f;
  --btn-bg-hover:  #ae1800;

  --bubble-out:    #332c26;
  --bubble-out-ink:#faf7f3;
  --bubble-in:     #faf7f3;
  --tick:          #ff8a70;   /* read ticks inside the mock (decorative)     */
  --bezel:         #241f1b;
  --screen:        #efeae4;

  /* selection: accent-300 ground, ink text — reads as accent, clears AA      */
  --sel-bg:        #ffc4b8;
  --sel-ink:       #241f1b;

  --header-bg:     rgba(239, 234, 228, 0.88);
  /* the diagram's server block: a tint in light, a recessed well in dark    */
  --dg-server:     var(--surface);
  --shadow-sm:     0 1px 2px rgba(45, 30, 20, 0.14);
  --shadow-md:     0 3px 14px rgba(45, 30, 20, 0.10);
  --shadow-lg:     0 18px 44px rgba(45, 30, 20, 0.13);

  /* Shape (§4) */
  --r-pill: 999px;
  --r-lg: 16px;
  --r-md: 12px;

  /* Type scale (web reading distance; the app scale in §3 is the reference) */
  --fs-hero:  clamp(2.6rem, 1.15rem + 5.6vw, 5.25rem);
  --fs-h2:    clamp(1.875rem, 1.1rem + 2.6vw, 3rem);
  --fs-h3:    clamp(1.0625rem, 1rem + 0.28vw, 1.25rem);
  --fs-lede:  clamp(1.0625rem, 0.97rem + 0.6vw, 1.4375rem);
  --fs-body:  clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem);
  --fs-small: 0.8125rem;
  --fs-kicker:0.6875rem;

  /* Rhythm */
  --pad-y:   clamp(4.25rem, 8.5vw, 8.5rem);
  --gutter:  clamp(1.25rem, 5vw, 4rem);
  --shell:   74rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:            #1c1a19;
    --surface:       #282625;
    --paper:         #2f2c2a;
    --ink:           #f1efed;
    --muted:         rgba(241, 239, 237, 0.68);
    --faint:         rgba(241, 239, 237, 0.58);
    --rule:          rgba(241, 239, 237, 0.14);
    --rule-strong:   rgba(241, 239, 237, 0.34);
    --ctl-border:    rgba(241, 239, 237, 0.40);   /* 3.55:1 on #1C1A19 */

    --accent:        #ff563c;   /* §2.3 — base accent fails on #1C1A19       */
    --accent-text:   #ff8a70;
    --accent-2:      #ff9783;
    --on-accent:     #1c1a19;
    --btn-bg:        #ff563c;
    --btn-bg-hover:  #ff9783;

    --bubble-out:    #413d3a;
    --bubble-out-ink:#f5f2f0;
    --bubble-in:     #2f2c2a;
    --tick:          #ff8a70;
    --bezel:         #0d0c0c;
    --screen:        #201e1d;

    --sel-bg:        #ff563c;
    --sel-ink:       #1c1a19;

    --header-bg:     rgba(28, 26, 25, 0.88);
    --dg-server:     var(--bg);
    --shadow-sm:     0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md:     0 3px 14px rgba(0, 0, 0, 0.38);
    --shadow-lg:     0 18px 44px rgba(0, 0, 0, 0.46);
  }
}

/* ── The always-dark band ────────────────────────────────────────────────
   Every component on this page reads the same semantic token names, so
   re-declaring the whole block on one section inverts the section and all
   of its children with no component changes — mirroring the app's immersive
   always-dark call screens (design-system.md §2.2).
   In LIGHT theme it is the DS's true call-screen ground, #181615.
   In DARK theme that would be four units off the page and would vanish, so
   the band shifts LIGHTER than #1C1A19 and keeps its hairline brackets: the
   compositional beat survives in both themes.                              */
.band-dark {
  --bg:            #181615;
  --surface:       #242120;
  --paper:         #242120;
  --ink:           #f6f4f3;
  --muted:         rgba(246, 244, 243, 0.74);
  --faint:         rgba(246, 244, 243, 0.62);
  --rule:          rgba(246, 244, 243, 0.16);
  --rule-strong:   rgba(246, 244, 243, 0.38);
  --ctl-border:    rgba(246, 244, 243, 0.42);
  --accent:        #ff563c;
  --accent-text:   #ffc4b8;
  --accent-2:      #ff9783;
  --on-accent:     #181615;
  --btn-bg:        #ff563c;
  --btn-bg-hover:  #ff9783;
  --shadow-md:     0 3px 14px rgba(0, 0, 0, 0.5);
  --shadow-lg:     0 18px 44px rgba(0, 0, 0, 0.6);
  background: var(--bg);
  color: var(--ink);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
@media (prefers-color-scheme: dark) {
  .band-dark {
    --bg:        #262322;
    --surface:   #2f2c2a;
    --paper:     #2f2c2a;
    --on-accent: #262322;
  }
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, p, ul, ol, li, figure, figcaption, dl, dt, dd, blockquote {
  margin: 0; padding: 0;
}
ul, ol { list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 7.5rem;
  -webkit-text-size-adjust: 100%;
}
@media (min-width: 64rem) { html { scroll-padding-top: 5.5rem; } }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Archivo", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

::selection { background: var(--sel-bg); color: var(--sel-ink); }

:focus-visible {
  /* no border-radius here: it would square off the element being focused */
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}
.inline-link:focus-visible,
.footer-links a:focus-visible { outline-offset: 4px; }
/* .site-nav is overflow-x:auto, which computes overflow-y to auto as well, so
   it clips at its padding box and eats the bottom (and, at scrollLeft 0, the
   left) of an outset ring. Draw this one inside the 44px link box instead —
   fully visible at both ends of the scroller, and it costs no header height. */
.site-nav a:focus-visible { outline-offset: -3px; }

/* #main carries tabindex="-1" purely so the skip link can move focus there:
   WebKit does not implement the sequential-focus-navigation starting point, so
   without it "Skip to content" scrolls but the next Tab returns to the nav. */
#main:focus { outline: none; }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 50;
  background: var(--ink);
  color: var(--bg);
  font-weight: 800;
  font-size: var(--fs-small);
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 var(--r-md) 0;
}
.skip:focus { left: 0; }

/* ── Layout ──────────────────────────────────────────────────────────────── */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--pad-y); }
.section + .section { border-top: 1px solid var(--rule); }
.band-dark + .section { border-top: 0; }

.sec-head {
  display: grid;
  gap: 1.15rem;
  max-width: 44rem;
  margin-bottom: clamp(2.75rem, 5.5vw, 4.5rem);
}
.sec-head--flush { margin-bottom: 0; }
.gap-t { margin-top: 1.6rem; }
.measure { max-width: 36rem; }

/* ── Type ────────────────────────────────────────────────────────────────── */
/* Hanging indent, not flex: the accent rule occupies the indent, so a kicker
   that wraps keeps its second line aligned under the first word instead of
   stranding the dash on line one.                                          */
.kicker {
  display: block;
  padding-left: 32px;
  text-indent: -32px;
  font-weight: 800;
  font-size: var(--fs-kicker);
  line-height: 1.35;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--accent-text);
}
.kicker::before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  width: 20px;
  height: 2px;
  margin-right: 12px;
  background: var(--accent);
  transform: translateY(-0.1em);
}
.kicker--plain { padding-left: 0; text-indent: 0; }
.kicker--plain::before { display: none; }

h1 {
  font-weight: 800;
  font-size: var(--fs-hero);
  line-height: 0.98;
  letter-spacing: -0.04em;
  text-wrap: balance;
}
h2 {
  font-weight: 800;
  font-size: var(--fs-h2);
  line-height: 1.06;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
h3 {
  font-weight: 800;
  font-size: var(--fs-h3);
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.lede {
  font-size: var(--fs-lede);
  line-height: 1.45;
  color: var(--muted);
  max-width: 34ch;
}
.sec-head .lede { max-width: 48ch; }

p.body { color: var(--muted); }
p.body + p.body { margin-top: 1.1rem; }

strong { font-weight: 600; color: var(--ink); }

.micro {
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--muted);
}
.mono {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.92em;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.inline-link {
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: 1px;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.inline-link:hover { color: var(--ink); }

/* ── Header ──────────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--header-bg);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--rule);
}
.site-header__in {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.85rem;
  min-height: 3.5rem;
  padding-block: 0.4rem;
}

.brand {
  order: 1;
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
}
.mark {
  width: 30px; height: 30px;
  flex: none;
  border-radius: 9px;
  background: var(--accent);
  display: grid;
  place-items: center;
}
.mark svg { width: 18px; height: 18px; }
.mark--lg { width: 40px; height: 40px; border-radius: 11px; }
.mark--lg svg { width: 23px; height: 23px; }

/* status pill, beside the wordmark — it reads as product status, not a link */
.pill {
  order: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--rule-strong);
  padding: 0.26rem 0.6rem;
  font-weight: 800;
  font-size: 0.625rem;         /* §3 Kicker floor is 10px; 9px was below it */
  letter-spacing: 0.13em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.pill .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}
.header-cta { order: 3; }

.site-nav {
  order: 4;
  flex: 1 0 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 1.15rem;
  border-top: 1px solid var(--rule);
  padding-top: 0.45rem;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.site-nav::-webkit-scrollbar { display: none; }
/* The scrollbar is suppressed, so the fade is the only thing telling a touch
   or mouse user that the strip continues. Only the wrapped mobile row can
   overflow; above 64rem the nav is inline and needs no cue. */
@media (max-width: 63.99rem) {
  .site-nav {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  }
}
.site-nav a {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;            /* §10 touch floor */
  white-space: nowrap;
  font-weight: 600;
  font-size: var(--fs-small);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.18s ease;
}
.site-nav a:hover { color: var(--ink); }

@media (min-width: 64rem) {
  .site-header__in { min-height: 4.25rem; padding-block: 0; gap: 1rem; }
  .site-nav {
    order: 2;
    flex: 0 1 auto;
    border-top: 0;
    padding-top: 0;
    gap: 1.6rem;
    overflow: visible;
    margin-right: 0.5rem;
  }
  .pill { order: 3; }
  .header-cta { order: 4; }
}
/* The pill is a nicety; below ~416px the header row needs the space more, and
   the beta status is restated one line under the hero CTA anyway. 24rem was a
   pixel short: brand + pill + CTA overflows from 385px up, which orphans the
   CTA onto a third row across the whole iPhone 12/13/14 width (390px). 26rem
   matches the breakpoint .cta-row and .mock__chip already switch at.        */
@media (max-width: 26rem) {
  .pill { display: none; }
}

/* ── Buttons (§7 primary button; ghost variant) ──────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 48px;            /* explicit touch-target floor (§10) */
  font-family: inherit;
  font-weight: 800;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  border-radius: var(--r-md);
  padding: 0.75rem 1.35rem;
  border: 1.5px solid transparent;
  transition: transform 0.16s ease, background-color 0.18s ease,
              border-color 0.18s ease, color 0.18s ease;
}
.btn svg { width: 15px; height: 15px; flex: none; }
.btn-sm { min-height: 44px; padding: 0.5rem 0.95rem; font-size: 0.8125rem; }
.btn-primary { background: var(--btn-bg); color: var(--on-accent); }
.btn-primary:hover { background: var(--btn-bg-hover); }
.btn-ghost { border-color: var(--ctl-border); color: var(--ink); }
.btn-ghost:hover { border-color: var(--ink); background: var(--paper); }
@media (prefers-reduced-motion: no-preference) {
  .btn:hover { transform: translateY(-1px); }
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.35rem;
}
/* at phone width the two hero CTAs share one width instead of looking ragged */
@media (max-width: 26rem) {
  .cta-row { display: grid; grid-template-columns: minmax(0, 1fr); }
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero { padding-block: clamp(3rem, 7vw, 6.5rem) clamp(3.5rem, 7vw, 6rem); }
.hero-grid {
  display: grid;
  gap: clamp(3rem, 6vw, 5rem);
  align-items: center;
}
@media (min-width: 60rem) {
  .hero-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
}

.hero-copy { display: grid; gap: 1.5rem; justify-items: start; }
.hero-copy h1 { margin-top: 0.3rem; }

.cta-note {
  margin-top: -0.95rem;
  color: var(--faint);
  font-size: var(--fs-small);
  line-height: 1.5;
}
.cta-note strong { color: var(--ink); font-weight: 800; }

.ticks {
  display: grid;
  gap: 0.55rem;
  width: 100%;
  max-width: 34rem;
  margin-top: 0.15rem;
}
.ticks li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.65rem;
  align-items: start;
  color: var(--muted);
  font-size: var(--fs-small);
  line-height: 1.45;
}
.ticks .tick { color: var(--accent); }
.ticks .tick svg { width: 15px; height: 15px; transform: translateY(2px); }

.hero-art { display: grid; justify-items: center; min-width: 0; }

/* ── Phone illustration ──────────────────────────────────────────────────
   Pure CSS/SVG. Every dimension inside the screen is in `em`, derived from
   the single font-size on .mock__screen, so the whole device rescales in
   proportion from 320px up without a breakpoint anywhere.                  */
.mock {
  position: relative;
  width: min(336px, 76vw);
  flex: none;
}
.mock__bezel {
  background: var(--bezel);
  border-radius: clamp(30px, 8vw, 42px);
  padding: clamp(7px, 1.8vw, 10px);
  box-shadow: var(--shadow-lg), 0 0 0 1px var(--rule);
}
.mock__screen {
  background: var(--screen);
  color: var(--ink);
  border-radius: clamp(24px, 6.4vw, 33px);
  overflow: hidden;
  /* The unit everything below uses. The floor is what .m-meta (0.72em) and
     .m-sys (0.74em) are derived from, so 10.5px put those at ~7.6px. */
  font-size: clamp(11.5px, 3.2vw, 13px);
  line-height: 1.42;
  display: flex;
  flex-direction: column;
  min-height: 38em;
}

.m-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9em 1.5em 0.3em;
  font-size: 0.8em;
  font-weight: 800;
}
.m-status__dots { display: inline-flex; gap: 0.35em; }
.m-status__dots i {
  width: 0.42em; height: 0.42em;
  border-radius: 50%;
  background: var(--ink);
  opacity: 0.5;
}

.m-nav {
  display: flex;
  align-items: center;
  gap: 0.65em;
  padding: 0.55em 1.1em 0.75em;
  border-bottom: 1px solid var(--rule);
}
.m-nav svg, .m-sys svg, .m-field__ico, .m-send svg {
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.m-nav__back { color: var(--ink); opacity: 0.75; }
.m-nav__back svg { width: 1.25em; height: 1.25em; }
.m-nav__avatar {
  width: 2.5em; height: 2.5em;
  flex: none;
  border-radius: 50%;
  /* the token that exists because white on base accent is only 4.2:1 */
  background: var(--btn-bg);
  color: var(--on-accent);
  font-weight: 800;
  font-size: 0.95em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.m-nav__who { display: flex; flex-direction: column; line-height: 1.25; flex: 1; min-width: 0; }
.m-nav__who b { font-weight: 800; font-size: 1.05em; letter-spacing: -0.01em; }
.m-nav__who i {
  font-style: normal;
  font-weight: 600;
  font-size: 0.76em;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
}
.m-nav__call { color: var(--ink); opacity: 0.7; }
.m-nav__call svg { width: 1.5em; height: 1.5em; }
.m-lock { width: 0.95em; height: 0.95em; flex: none; }

.m-thread {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.55em;
  padding: 1em 0.85em 0.8em;
}
.m-sys {
  text-align: center;
  font-size: 0.74em;
  font-weight: 600;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  margin-bottom: 0.5em;
}
.m-sys svg { stroke-width: 2.2; }

.m-row { display: flex; }
.m-row--in  { justify-content: flex-start; }
.m-row--out { justify-content: flex-end; }

.m-bubble {
  max-width: 78%;
  padding: 0.62em 0.8em 0.5em;
  font-size: 1em;
  border-radius: 1.25em;
  position: relative;
}
.m-row--in .m-bubble {
  background: var(--bubble-in);
  color: var(--ink);
  border-top-left-radius: 0.46em;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
.m-row--out .m-bubble {
  background: var(--bubble-out);
  color: var(--bubble-out-ink);
  border-top-right-radius: 0.46em;
}
.m-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  float: right;
  margin: 0.45em 0 -0.15em 0.8em;
  font-size: 0.72em;
  font-weight: 600;
  opacity: 0.62;
}
.m-row--out .m-meta { opacity: 0.75; }
.m-ticks {
  width: 1.7em; height: 0.9em;
  fill: none;
  stroke: var(--tick);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.m-bubble--typing {
  display: inline-flex;
  gap: 0.3em;
  padding: 0.85em 0.9em;
}
.m-bubble--typing i {
  width: 0.42em; height: 0.42em;
  border-radius: 50%;
  background: var(--ink);
  opacity: 0.38;
  /* SC 2.2.2: bounded, not infinite — it settles into three resting dots. */
  animation: mtype 1.3s ease-in-out 4;
}
.m-bubble--typing i:nth-child(2) { animation-delay: 0.16s; }
.m-bubble--typing i:nth-child(3) { animation-delay: 0.32s; }
@keyframes mtype {
  0%, 60%, 100% { opacity: 0.28; transform: translateY(0); }
  30%           { opacity: 0.7;  transform: translateY(-0.18em); }
}

.m-composer {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.7em 0.85em 1.4em;
}
.m-field {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.55em;
  background: var(--paper);
  border-radius: var(--r-pill);
  padding: 0.72em 0.9em;
  color: var(--muted);
}
.m-field__text { flex: 1; font-size: 0.95em; font-weight: 400; }
.m-field__ico {
  width: 1.25em; height: 1.25em;
  flex: none;
  stroke-width: 1.9;
  opacity: 0.8;
}
.m-send {
  width: 3em; height: 3em;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
}
.m-send svg { width: 1.35em; height: 1.35em; stroke-width: 2.4; }

.mock__chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  padding: 8px 13px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: -0.005em;
  white-space: nowrap;
  box-shadow: var(--shadow-md);
}
.mock__chip svg {
  width: 14px; height: 14px;
  fill: none;
  stroke: var(--accent-text);
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mock__chip--a { top: -15px; left: -14px; }
.mock__chip--b { bottom: 15%; right: -12px; }
@media (max-width: 26rem) {
  .mock__chip { font-size: 0.65rem; padding: 6px 10px; }
  .mock__chip--a { top: -12px; left: -6px; }
  .mock__chip--b { bottom: 13%; right: -6px; }
}
@media (min-width: 60rem) {
  .mock__chip--a { top: -18px; left: -32px; }
  .mock__chip--b { right: -28px; }
}

.fig-note {
  color: var(--faint);
  font-size: 0.75rem;
  line-height: 1.5;
  margin-top: 1rem;
  max-width: 26rem;
}
.hero-art .fig-note { text-align: center; }

/* ── The diagram ─────────────────────────────────────────────────────────── */
.proof-figure { margin: 0; }

.diagram-wide { display: none; }
@media (min-width: 64rem) {
  .diagram-wide {
    display: block;
    width: 100%;
    height: auto;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 24px;
    padding: clamp(1rem, 2vw, 2rem) clamp(0.5rem, 1.5vw, 1.5rem);
    box-shadow: var(--shadow-md);
  }
}

/* shared diagram ink */
.dg-device { fill: var(--paper); stroke: var(--rule-strong); stroke-width: 2; }
.dg-box    { fill: var(--dg-server); stroke: var(--rule-strong); stroke-width: 1.5; }
.dg-inner  { fill: var(--bg); stroke: var(--rule); stroke-width: 1.5; }
.dg-line   { fill: none; stroke: var(--rule-strong); stroke-width: 2; stroke-linecap: round; }
.dg-arrow  { fill: var(--rule-strong); }
.dg-hair   { stroke: var(--rule); stroke-width: 1.5; }
.dg-notch  { fill: var(--ink); opacity: 0.18; }
.dg-in     { fill: var(--bubble-in); stroke: var(--rule); stroke-width: 1.5; }
.dg-out    { fill: var(--bubble-out); }
.dg-bar-in { fill: var(--ink); opacity: 0.3; }
.dg-bar-out{ fill: var(--bubble-out-ink); opacity: 0.42; }
.dg-packet { fill: var(--bg); stroke: var(--accent); stroke-width: 2; }
.dg-cipher { fill: var(--accent); opacity: 0.62; }
.dg-fade   { opacity: 0.3; }
.dg-gone   { fill: none; stroke: var(--accent); stroke-width: 2;
             stroke-dasharray: 5 6; opacity: 0.42; }
.dg-spark  { fill: var(--accent-2); opacity: 0.55; }  /* the copy dispersing */
.dg-label  { fill: var(--ink); font-weight: 800; font-size: 15px; letter-spacing: 1.7px; }
.dg-micro  { fill: var(--muted); font-weight: 800; font-size: 13.5px; letter-spacing: 1.5px; }
.dg-sub    { fill: var(--muted); font-weight: 400; font-size: 16px; letter-spacing: 0; }

@media (prefers-reduced-motion: no-preference) {
  .dg-gone { animation: breathe 5.5s ease-in-out 1; }   /* SC 2.2.2: bounded */
  @keyframes breathe {
    0%, 100% { opacity: 0.46; }
    55%      { opacity: 0.12; }
  }
}

/* Steps — the textual equivalent of the diagram; a vertical timeline on
   narrow screens, a three-column legend under the diagram on wide ones. */
.steps { display: grid; gap: 2.25rem; }
.steps li { display: grid; gap: 0.7rem; }
.step-fig {
  width: 100%;
  max-width: 172px;
  height: auto;
  margin-bottom: 0.35rem;
}
.step-n {
  font-weight: 800;
  font-size: var(--fs-kicker);
  letter-spacing: 0.17em;
  color: var(--accent-text);
  text-transform: uppercase;
}
.steps p:not(.step-n) { color: var(--muted); font-size: var(--fs-small); line-height: 1.6; }

@media (min-width: 48rem) {
  .steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.75rem, 3.5vw, 3rem);
    margin-top: clamp(2.5rem, 4vw, 3.5rem);
  }
  .steps li { border-top: 1.5px solid var(--rule-strong); padding-top: 1.25rem; }
}
@media (min-width: 64rem) {
  /* the wide diagram takes over; the per-step figures would only repeat it */
  .step-fig { display: none; }
  .steps li { padding-top: 1.1rem; }
}

/* ── The redaction card ──────────────────────────────────────────────────
   Deliberately blank, and placed one paragraph away from the sentence that
   explains why: beside the OUR SERVER block, the blankness reads as
   redaction rather than as content that failed to load.                    */
.redaction {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
  margin-top: clamp(3rem, 5vw, 4.5rem);
}
@media (min-width: 58rem) {
  .redaction { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }
}
.redaction__art { display: grid; justify-items: center; min-width: 0; }
.redaction__copy { display: grid; gap: 0.85rem; }
.redaction__copy h3 { font-size: clamp(1.15rem, 1rem + 0.7vw, 1.5rem); max-width: 24ch; }
.redaction__copy p { color: var(--muted); font-size: var(--fs-small); max-width: 46ch; }
.redaction__copy .fig-note { color: var(--faint); max-width: 46ch; margin-top: 0.2rem; }

.redact-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 24px;
  box-shadow: var(--shadow-md);
  padding: 1.15rem 1.15rem 1rem;
  max-width: 23rem;
  width: 100%;
}
.rc-head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--rule);
}
.rc-avatar {
  width: 34px; height: 34px;
  border-radius: 50%;
  flex: none;
  background: var(--bg);
  border: 1px solid var(--rule);
}
.rc-head-lines { display: grid; gap: 6px; flex: 1 1 auto; }
.rc-head-lines i { display: block; height: 7px; border-radius: 4px; background: var(--ink); opacity: 0.34; }
.rc-head-lines i:first-child { width: 42%; opacity: 0.5; }
.rc-head-lines i:last-child  { width: 26%; opacity: 0.2; }
.rc-lock { color: var(--faint); flex: none; }
.rc-lock svg { width: 14px; height: 14px; }

.rc-body { display: grid; gap: 0.6rem; padding: 1rem 0 0.9rem; }
.bub {
  --bub-ink: var(--ink);
  padding: 0.7rem 0.85rem;
  display: grid;
  gap: 7px;
  /* an explicit width: the bars inside are percentage-sized, so the bubble
     itself must not be shrink-to-fit */
  max-width: 88%;
  position: relative;
}
.bub i { display: block; height: 8px; border-radius: 4px; background: var(--bub-ink); opacity: 0.30; }
.bub.in {
  background: var(--bubble-in);
  border: 1px solid var(--rule);
  border-radius: 6px 16px 16px 16px;
  justify-self: start;
}
.bub.out {
  --bub-ink: var(--bubble-out-ink);
  background: var(--bubble-out);
  /* a hairline keeps the outgoing bubble legible against the dark-theme
     card ground, where #413D3A and #2F2C2A are close neighbours */
  box-shadow: inset 0 0 0 1px var(--rule);
  border-radius: 16px 6px 16px 16px;
  justify-self: end;
}
.bub.out i { opacity: 0.42; }
.bub--w56 { width: 56%; }
.bub--w64 { width: 64%; }
.bub--w82 { width: 82%; }
.bub--w88 { width: 88%; }
.bub i.w54 { width: 54%; }
.bub i.w66 { width: 66%; }
.bub i.w82 { width: 82%; }
.bub i.w84 { width: 84%; }
.bub i.w88 { width: 88%; }
.bub i.w92 { width: 92%; }
.rc-ticks { position: absolute; right: 9px; bottom: 5px; color: var(--bubble-out-ink); opacity: 0.55; }
.rc-ticks svg { width: 13px; height: 8px; }

.rc-foot {
  text-align: center;
  color: var(--faint);
  font-weight: 800;
  font-size: 0.625rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  border-top: 1px solid var(--rule);
  padding-top: 0.85rem;
}

.caveat {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  border-left: 2.5px solid var(--accent);
  background: var(--surface);
  border-radius: 5px var(--r-lg) var(--r-lg) 5px;
  padding: 1.15rem 1.35rem;
  max-width: 46rem;
  color: var(--muted);
  font-size: var(--fs-small);
  line-height: 1.6;
}
.caveat b { color: var(--ink); font-weight: 800; }

/* ── Encryption band ─────────────────────────────────────────────────────── */
.two {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 58rem) {
  .two { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.enc-list-label { margin-bottom: 1.25rem; }
.enc-list { display: grid; gap: 0; }
.enc-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.9rem;
  align-items: baseline;
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--rule);
}
.enc-list li:first-child { border-top: 1px solid var(--rule); }
.enc-list .tick { color: var(--accent); }
.enc-list .tick svg { width: 15px; height: 15px; transform: translateY(3px); }
.enc-list .txt { display: block; }
.enc-list b {
  display: block;
  font-weight: 800;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.enc-list .txt span {
  display: block;
  color: var(--muted);
  font-size: var(--fs-small);
  line-height: 1.45;
  margin-top: 0.1rem;
}

.note-card {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  display: grid;
  gap: 0.85rem;
  margin-top: 2rem;
}
.note-card .glyph {
  width: 42px; height: 42px;
  border-radius: 50%;
  background: var(--bg);
  display: grid;
  place-items: center;
  color: var(--accent);
}
.note-card .glyph svg { width: 20px; height: 20px; }
.note-card p { color: var(--muted); font-size: var(--fs-small); }

/* ── The argument: field swap, reasons, pull quote ───────────────────────── */
.swap {
  margin: 0 0 clamp(2.75rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  max-width: 46rem;
  box-shadow: var(--shadow-md);
}
@media (min-width: 38rem) {
  .swap { grid-template-columns: 1fr 1fr; }
}
.swap__col {
  background: var(--paper);
  padding: clamp(1.1rem, 2.2vw, 1.6rem);
  display: grid;
  gap: 0.65rem;
  align-content: start;
}
.swap__col--yes { background: var(--surface); }
.swap__col .micro {
  font-weight: 800;
  font-size: var(--fs-kicker);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}
.swap__cap {
  grid-column: 1 / -1;
  background: var(--paper);
  padding: 0.85rem clamp(1.1rem, 2.2vw, 1.6rem);
  border-top: 1px solid var(--rule);
}

.field {
  border: 1.5px solid var(--rule-strong);
  border-radius: var(--r-md);
  padding: 0.7rem 0.85rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--muted);
  background: transparent;
  overflow-wrap: anywhere;
}
.field--dead { border-style: dashed; border-color: var(--rule); }
.field__strike { text-decoration: line-through; text-decoration-thickness: 2px; }
.field--live {
  border-color: var(--accent);
  color: var(--accent-text);
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 2px;
}
.caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  background: var(--accent);
  animation: blink 1.15s step-end infinite;
}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

.reasons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
}
.reasons li { min-width: 0; border-top: 1.5px solid var(--rule-strong); padding-top: 1.15rem; }
.reasons h3 { margin: 0.6rem 0 0.4rem; }
.reasons p { color: var(--muted); font-size: var(--fs-small); max-width: 46ch; }

.idx {
  display: block;
  font-weight: 800;
  font-size: clamp(1.9rem, 1.2rem + 1.9vw, 2.8rem);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--rule-strong);
}
@supports (-webkit-text-stroke: 1px currentColor) {
  .idx {
    color: transparent;
    -webkit-text-stroke: 1.5px var(--accent);
    opacity: 0.85;
  }
}

.pull {
  margin-top: clamp(2.75rem, 5vw, 4.5rem);
  border-left: 3px solid var(--accent);
  padding-left: clamp(1.1rem, 2.4vw, 2rem);
  font-weight: 800;
  font-size: clamp(1.3rem, 0.95rem + 1.4vw, 2.1rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
  max-width: 26ch;
  text-wrap: balance;
}
.pull__hl { color: var(--accent-text); }

/* ── Getting started: steps + QR card ────────────────────────────────────── */
.start-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 60rem) {
  .start-grid { grid-template-columns: minmax(0, 1fr) minmax(280px, 23rem); }
}
.how-steps { display: grid; gap: clamp(1.6rem, 3vw, 2.25rem); }
.how-steps li { border-top: 1px solid var(--rule); padding-top: 1.15rem; min-width: 0; }
.how-steps h3 { margin: 0.5rem 0 0.4rem; }
.how-steps p { color: var(--muted); font-size: var(--fs-small); max-width: 52ch; }

.qr-card {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: clamp(1.1rem, 2vw, 1.5rem);
  box-shadow: var(--shadow-lg);
  display: grid;
  gap: 1rem;
  width: 100%;
  max-width: 23rem;
  margin-inline: auto;
}
.qr-card__head { display: flex; align-items: center; gap: 0.75rem; }
.qr-card__name { display: block; font-weight: 800; font-size: 1.0625rem; letter-spacing: -0.01em; }
.qr-card__head .micro { display: block; }

.qr-frame {
  position: relative;
  padding: clamp(0.9rem, 2vw, 1.25rem);
  border-radius: var(--r-md);
  background: var(--bg);
  overflow: hidden;
}
.qr { width: 100%; height: auto; color: var(--ink); }
.qr__hub { fill: var(--accent); }
.qr__bubble { fill: #fff; }

.qr-frame__c {
  position: absolute;
  width: 20px; height: 20px;
  border: 2.5px solid var(--accent);
}
.qr-frame__c--tl { top: 8px; left: 8px; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.qr-frame__c--tr { top: 8px; right: 8px; border-left: 0; border-bottom: 0; border-radius: 0 6px 0 0; }
.qr-frame__c--bl { bottom: 8px; left: 8px; border-right: 0; border-top: 0; border-radius: 0 0 0 6px; }
.qr-frame__c--br { bottom: 8px; right: 8px; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }

/* echoes the app's own QR scanline (design-system.md §8) */
.qr-frame::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px;
  height: 2px;
  background: var(--accent);
  /* SC 2.2.2: the scanline is not an endless loop. `both` holds the 0%/100%
     keyframe (invisible) before and after, and the play-state hook below
     starts it when the card is actually revealed — so it still greets you on
     arrival, sweeps twice, then rests. */
  opacity: 0;
  animation: scan 3.4s ease-in-out 2 both;
}
.js-reveal .qr-card .qr-frame::after { animation-play-state: paused; }
.js-reveal .qr-card.is-in .qr-frame::after { animation-play-state: running; }
@keyframes scan {
  0%, 100% { top: 10%; opacity: 0; }
  10%      { opacity: 0.75; }
  50%      { top: 88%; opacity: 0.75; }
  60%      { opacity: 0; }
}

.point-list {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.25rem);
  margin-top: clamp(2.75rem, 5vw, 4rem);
}
@media (min-width: 58rem) {
  .point-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.point-list > div { border-top: 1.5px solid var(--rule-strong); padding-top: 1.15rem; min-width: 0; }
.point-list h3 { margin-bottom: 0.45rem; }
.point-list p { color: var(--muted); font-size: var(--fs-small); }

/* ── Trade-offs ──────────────────────────────────────────────────────────
   Term-and-definition pairs, so a <dl>. Hairlines live on the cells with a
   -1px offset, clipped by the container: a partly filled last row can never
   strand a block of rule colour, and nothing here is a filled card.        */
.honest {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.honest > div {
  min-width: 0;
  padding: clamp(1.35rem, 2.4vw, 1.9rem);
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
  margin: -1px 0 0 -1px;
}
.honest dt {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  font-weight: 800;
  font-size: var(--fs-h3);
  line-height: 1.25;
  letter-spacing: -0.015em;
  margin-bottom: 0.45rem;
}
.honest dt::before {
  content: "";
  flex: none;
  width: 9px; height: 9px;
  border-radius: 2px;
  background: var(--accent);
  transform: translateY(-1px);
}
.honest dd { color: var(--muted); font-size: var(--fs-small); }

/* ── Beta ────────────────────────────────────────────────────────────────── */
.beta-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: 2rem;
}
.beta-card {
  min-width: 0;
  padding: clamp(1.35rem, 2.5vw, 1.9rem);
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
  margin: -1px 0 0 -1px;
  display: grid;
  gap: 0.5rem;
  align-content: start;
}
.beta-card .plat {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 800;
  font-size: var(--fs-kicker);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
}
.beta-card .plat svg { width: 15px; height: 15px; color: var(--accent); }
.beta-card p { color: var(--muted); font-size: var(--fs-small); }
.beta-card .how { font-weight: 800; font-size: 1.25rem; letter-spacing: -0.02em; color: var(--ink); }

.status-line {
  margin-top: 2rem;
  padding-top: 1.15rem;
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-size: var(--fs-small);
  max-width: 58ch;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--rule);
  padding-block: clamp(2.5rem, 5vw, 4rem) 2.5rem;
}
.footer-grid {
  display: grid;
  gap: 2rem;
  align-items: start;
}
@media (min-width: 48rem) {
  .footer-grid { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.75rem;
  align-content: start;
}
@media (min-width: 48rem) {
  .footer-links { justify-content: flex-end; }
}
.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;            /* §10 touch floor */
  font-weight: 600;
  font-size: var(--fs-small);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.18s ease;
}
.footer-links a:hover { color: var(--ink); }
.footer-note {
  color: var(--faint);
  font-size: 0.75rem;
  line-height: 1.6;
  max-width: 44ch;
  margin-top: 0.9rem;
}
.footer-base {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  display: grid;
  gap: 0.4rem;
  color: var(--faint);
  font-size: 0.75rem;
  line-height: 1.55;
  max-width: 78ch;
}

/* ── Scroll reveal (progressive enhancement; JS adds .js-reveal) ─────────── */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
  }
  .js-reveal [data-reveal].is-in {
    opacity: 1;
    transform: none;
    transition: opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
                transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
}

/* ── Reduced motion ──────────────────────────────────────────────────────
   A global backstop first, so anything added later is covered by default,
   then the named cases that need more than a shortened duration.          */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .qr-frame::after { display: none; }
  .caret { animation: none; opacity: 1; }
  .dg-gone { animation: none; opacity: 0.46; }
  .m-bubble--typing i { animation: none; }
  .js-reveal [data-reveal] { opacity: 1; transform: none; }
}

/* ── Very narrow screens ─────────────────────────────────────────────────── */
@media (max-width: 23.75rem) {
  :root { --fs-hero: clamp(2.3rem, 1rem + 5.6vw, 5.25rem); }
  .swap__col { padding: 1rem; }
}

@media print {
  /* Two things break a print/PDF render that setting `color` alone cannot fix.
     (1) The reveal class is added by the head script, but the observer that
     removes it never runs for a print — so every [data-reveal] block prints at
     opacity 0. (2) Everything on this page reads semantic tokens, so a section
     (or a dark-theme page in Safari, which does not force light for print)
     keeps light-on-dark values against white paper. Reset the tokens. */
  :root, .band-dark {
    --bg:            #fff;
    --surface:       #fff;
    --paper:         #fff;
    --screen:        #fff;
    --ink:           #000;
    --muted:         #222;
    --faint:         #333;
    --rule:          rgba(0, 0, 0, 0.25);
    --rule-strong:   rgba(0, 0, 0, 0.45);
    --ctl-border:    rgba(0, 0, 0, 0.50);
    --accent:        #a81800;
    --accent-text:   #a81800;
    --accent-2:      #a81800;
    --on-accent:     #fff;
    --btn-bg:        #a81800;
    --bubble-out:    #241f1b;
    --bubble-out-ink:#fff;
    --bubble-in:     #fff;
    --bezel:         #241f1b;
    --dg-server:     #fff;
    --header-bg:     #fff;
    --shadow-sm: none; --shadow-md: none; --shadow-lg: none;
    background: #fff;
    color: #000;
  }
  .site-header, .cta-row, .qr-frame::after { display: none; }
  body { background: #fff; color: #000; }
  .js-reveal [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SHARED SITE STYLES
   /privacy.html, /terms.html and /u.html are frozen pages that load this same
   stylesheet. Everything below keeps their markup dressed correctly; the
   landing page above does not use any of it.
   ══════════════════════════════════════════════════════════════════════════ */

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px var(--gutter) 40px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.wrap main { flex: 1; }

.wrap footer {
  border-top: 1px solid var(--rule);
  margin-top: 40px;
  padding-top: 16px;
  display: flex;
  gap: 8px 20px;
  flex-wrap: wrap;
  align-items: center;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 600;
}
.wrap footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--muted);
  text-decoration: none;
}
.wrap footer a:hover { color: var(--ink); }

/* Logo tile (§1) — /u/ fallback page */
.logo-tile {
  width: 72px; height: 72px;
  border-radius: var(--r-lg);
  background: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
}
.logo-tile svg { width: 40px; height: 40px; }
.logo-tile--sm { width: 48px; height: 48px; border-radius: 12px; }
.logo-tile--sm svg { width: 27px; height: 27px; }

.profile {
  padding: 40px 0 24px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
.profile h1 { font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem); }
.handle { color: var(--accent-text); overflow-wrap: anywhere; }
.qr-card .handle, .codecard .handle { color: inherit; }

.btn-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
  padding: 8px 0 16px;
}
.btn[aria-disabled="true"] { opacity: 0.55; cursor: default; }

.e2e-note {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 16px 0;
}

/* Policy pages */
.backlink {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  color: var(--ink);
  font-weight: 800;
  font-size: 0.875rem;
  text-decoration: none;
  margin-bottom: 12px;
}
.policy h1 { font-size: clamp(2rem, 1.4rem + 2vw, 2.75rem); line-height: 1.04; }
.policy h2 {
  font-size: clamp(1.0625rem, 1rem + 0.45vw, 1.3125rem);
  margin: 2.25rem 0 0.5rem;
}
.policy p { color: var(--muted); margin: 0.5rem 0; max-width: 62ch; }
.policy ul {
  color: var(--muted);
  list-style: disc;
  margin: 0.5rem 0 0.75rem;
  padding-left: 22px;
  max-width: 62ch;
}
.policy li { margin: 0.375rem 0; }
.policy strong { color: var(--ink); font-weight: 600; }
.policy a { color: var(--accent-text); }
.policy-meta {
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 24px;
}
