/* The proof: a message waits on you in a team chat; on your Mac, otai lets you know and has the reply ready.
   Two places, told apart at a glance. The chat is someone else's app: the system's face, neutral greys, white.
   otai is otai: paper and its sky, plum ink, its three faces, the quote's line. Nothing of otai is ever drawn
   inside the chat, and nothing types: the chat's field stays empty. */

/* ---------- the section ---------- */
/* The notification waits 48px off its place before it plays; the section clips it so a phone never scrolls sideways. */
.proof {
  padding: 22vh var(--gutter) 20vh;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; row-gap: clamp(56px, 9vh, 96px); overflow-x: clip; }
/* The heading in two lines over the whole stage; the paragraph stands over otai's window, the place it tells about. */
.proof-copy { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; row-gap: 32px; }
.proof-copy h2 { grid-column: 1 / -1; }
.proof-copy h2 > span { display: inline-block; } /* each clause is a unit: two lines, broken at the comma; on a phone each wraps on its own */
.proof-copy .reading { grid-column: 7 / span 5; max-width: 40ch; }
.stagebox { grid-column: 1 / -1; display: grid; gap: 20px; }
.replay { justify-self: end; }

/* ---------- the stage: the chat on the left, otai on the right, the notification over otai's corner ---------- */
.demo {
  --sys: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, "Segoe UI", Roboto, sans-serif;
  --sys-ink: #1d1d1f; --sys-ink-3: #6b6b70; --sys-line: rgba(0, 0, 0, .08);
  --dot: #dad8dc;
  position: relative; margin: 0;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto auto; column-gap: 24px; align-items: start;
}
/* A Mac window's three buttons, quiet: neither window is the one in front. */
.demo .lights, .walk .lights {
  flex: none; width: 52px; height: 12px;
  background: radial-gradient(circle at 6px 6px, var(--dot) 5.5px, transparent 6px), radial-gradient(circle at 26px 6px, var(--dot) 5.5px, transparent 6px), radial-gradient(circle at 46px 6px, var(--dot) 5.5px, transparent 6px);
}

/* The chat: any team chat. */
.demo .chat {
  grid-column: 1 / span 5; grid-row: 1 / 3; display: flex; flex-direction: column; height: 392px;
  border-radius: 12px; background: #fff; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .07), 0 26px 60px -22px rgba(28, 22, 32, .3), 0 2px 6px rgba(28, 22, 32, .04);
  font: 400 14px/1.45 var(--sys); color: var(--sys-ink);
}
.demo .chat-bar { flex: none; display: flex; align-items: center; gap: 20px; height: 46px; padding: 0 18px; border-bottom: 1px solid var(--sys-line); background: #f6f6f7; }
.demo .chat-bar b { font-weight: 600; }
.demo .chat-bar b span { margin-right: 1px; color: var(--sys-ink-3); font-weight: 400; }
/* The latest messages sit on the field, as in every chat; older ones run up under the bar and fade. */
.demo .chat-log {
  flex: 1; min-height: 0; list-style: none; margin: 0; padding: 0 20px; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  -webkit-mask-image: linear-gradient(transparent, #000 64px); mask-image: linear-gradient(transparent, #000 64px);
}
.demo .chat-log > li { flex: none; } /* a message never shrinks to make room: the oldest go up under the bar */
.demo .msg { display: grid; grid-template-columns: 34px minmax(0, 1fr); column-gap: 12px; padding-top: 18px; }
/* The message that arrives carries its air inside its first row, so the whole of it can close to nothing. */
.demo .ask > .msg { padding-top: 0; }
.demo .ask :is(.face, .who) { margin-top: 18px; }
.demo .face { grid-row: 1 / 3; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: #ededf0; font: 600 13px/1 var(--sys); color: #55555b; }
.demo .who { font-size: 12px; line-height: 18px; color: var(--sys-ink-3); font-variant-numeric: tabular-nums; }
.demo .who b { margin-right: 6px; font-size: 14px; font-weight: 600; color: var(--sys-ink); }
.demo .said { margin-top: 1px; font-size: 14.5px; line-height: 1.45; text-wrap: pretty; }
.demo .at { padding: 0 3px; border-radius: 4px; background: rgba(0, 122, 255, .1); color: #0a5bc2; font-weight: 500; }
.demo .chat-field { flex: none; margin: 16px 16px 16px; padding: 10px 14px; border: 1px solid rgba(0, 0, 0, .13); border-radius: 9px; color: #737378; font-size: 14px; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The notification: macOS draws it, with otai's icon; it floats over everything, otai's window too. */
.demo .notif {
  grid-column: 7 / -1; grid-row: 1; justify-self: end; position: relative; z-index: 2; width: min(100%, 372px); margin-right: -14px;
  display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; column-gap: 11px; align-items: baseline;
  padding: 11px 14px 12px 11px; border-radius: 16px;
  background: rgba(246, 245, 247, .8); -webkit-backdrop-filter: blur(22px) saturate(1.8); backdrop-filter: blur(22px) saturate(1.8);
  box-shadow: 0 0 0 .5px rgba(0, 0, 0, .14), 0 14px 34px -12px rgba(28, 22, 32, .3), 0 2px 6px rgba(28, 22, 32, .06);
  font: 400 13px/1.36 var(--sys); color: var(--sys-ink);
}
.demo .notif-icon { grid-row: 1 / 3; align-self: start; width: 38px; height: 38px; padding: 4px; border-radius: 9px; background: var(--paper); box-shadow: 0 0 0 .5px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .07); }
.demo .notif-icon svg { display: block; width: 100%; height: 100%; }
.demo .notif-title { min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.demo .notif-time { font-size: 12px; color: var(--sys-ink-3); }
.demo .notif-body { grid-column: 2 / 4; margin-top: 1px; color: #3a3a3d; text-wrap: pretty; }

/* otai's window, as the app draws it: paper under its sky, the places centred in the bar. */
.demo .app {
  grid-column: 7 / -1; grid-row: 2; position: relative; margin-top: -8px; border-radius: 12px; overflow: hidden; color: var(--ink);
  background:
    radial-gradient(ellipse 78% 40% at 50% -6%, rgba(156, 175, 216, .26), transparent 72%),
    radial-gradient(ellipse 60% 34% at 50% 108%, rgba(251, 201, 185, .3), transparent 70%),
    var(--paper);
  box-shadow: 0 30px 80px rgba(58, 40, 61, .16), 0 0 0 1px rgba(58, 40, 61, .08);
}
.demo .app-bar { position: relative; display: flex; align-items: center; height: 46px; padding: 0 18px; }
.demo .places { position: absolute; left: 50%; translate: -50% 0; display: flex; gap: 44px; font: 400 13px/1 var(--sans); color: var(--ink-2); }
.demo .places .on { color: var(--ink); }
.demo .app-body { position: relative; padding: 20px 40px 36px; }
/* The app's centre column, at a demo's measure. */
.demo .req { max-width: 500px; margin: 0 auto; }

/* Before: Today with nothing in it, as the morning left it. */
.demo .calm { position: absolute; inset: 0 0 24px; display: grid; place-content: center; justify-items: center; gap: 12px; padding: 0 24px; text-align: center; opacity: 0; pointer-events: none; }
.demo .calm-title { font: 400 clamp(26px, 2.5vw, 36px)/1.1 var(--display); letter-spacing: -.012em; text-wrap: balance; }
.demo .calm p + p { font: 400 14px/1.45 var(--sans); color: var(--ink-2); }

/* After: who waits and what they ask, what memory holds and where it was read, then the reply, ready to copy. */
.demo .req-kick { font: 400 13px/1.45 var(--sans); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.demo .req-title { margin-top: 8px; font: 400 clamp(23px, 2vw, 28px)/1.2 var(--display); letter-spacing: -.008em; text-wrap: balance; }
.demo .mem { margin-top: 26px; display: grid; gap: 6px; }
.demo .mem-label { font: 400 13px/1.45 var(--sans); color: var(--ink-3); }
.demo .fact { position: relative; font: 400 15px/1.5 var(--sans); text-wrap: pretty; }
/* The fact's number hangs in the margin; the draft's mark says the same number. */
.demo .n { position: absolute; right: calc(100% + 9px); top: 3px; padding: 2px 4px; border-radius: 4px; font: 500 11px/1 var(--sans); color: var(--ink-3); }
.demo .quote { margin: 0; font: italic 400 17px/1.5 var(--text); color: var(--ink-2); text-wrap: pretty; }
.demo .quote mark { color: inherit; padding-bottom: 2px; background: linear-gradient(var(--quote-line), var(--quote-line)) 0 100% / 100% 1.5px no-repeat; }
.demo .prov { display: flex; align-items: flex-start; gap: 8px; margin-top: 2px; font: 400 13px/1.45 var(--sans); color: var(--ink-3); }
.demo .prov .cert { margin-top: 3.5px; } /* on the first line's middle, however the words wrap */
.demo .sheet { margin-top: 24px; display: grid; gap: 8px; padding: 18px 22px 14px; border-radius: 18px; background: var(--raised); box-shadow: 0 0 0 1px var(--line); }
.demo .sheet-to { font: 400 14px/1.4 var(--sans); color: var(--ink-2); }
.demo .sheet-text { font: 400 19px/1.55 var(--text); text-wrap: pretty; }
.demo .sheet-text sup { padding: 1px 2px; border-radius: 4px; font: 500 10px/1 var(--sans); color: var(--ink-3); vertical-align: 7px; }
.demo .sheet-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 16px; margin-top: 2px; font: 400 13px/1.4 var(--sans); color: var(--ink-3); }
.demo .copy { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-2); }

/* ---------- the play: about five seconds, timed here; demo.js only starts it ----------
   The message lands (.4s), otai's notification comes in from the edge (1.3s), Today lets its quiet go (2s),
   then the request fills in the order it is read: who asks, what memory holds, the quote's words marked as a
   pen would, where they were read, the reply (in by 4.8s); its mark and the fact's number then light once.
   Without script, or with reduced motion, the end is shown at once. */
@media (prefers-reduced-motion: no-preference) {
  .js .demo .ask { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .55s var(--settle) .4s; }
  .js .demo .ask > .msg { min-height: 0; overflow: hidden; transition: opacity .45s var(--settle) .55s, transform .6s var(--settle) .5s; }
  .js .demo:not(.play) .ask { grid-template-rows: 0fr; }
  .js .demo:not(.play) .ask > .msg { opacity: 0; transform: translateY(10px); }

  .js .demo .notif { transition: opacity .5s var(--settle) 1.3s, transform .75s var(--out) 1.3s; }
  .js .demo:not(.play) .notif { opacity: 0; transform: translateX(48px); }

  .js .demo:not(.play) .calm { opacity: 1; }
  .js .demo .calm { transition: opacity .35s var(--settle) 2s, transform .45s var(--settle) 2s, filter .35s var(--settle) 2s; }
  .js .demo.play .calm { transform: translateY(-12px); filter: blur(4px); }

  .js .demo :is(.req-kick, .req-title, .mem-label, .fact, .quote, .sheet) { transition: opacity .6s var(--settle) var(--at), transform .6s var(--settle) var(--at), filter .6s var(--settle) var(--at); }
  .js .demo:not(.play) :is(.req-kick, .req-title, .mem-label, .fact, .quote, .sheet) { opacity: 0; transform: translateY(12px); filter: blur(5px); }
  .js .demo .prov { transition: opacity .5s var(--settle) var(--at); }
  .js .demo:not(.play) .prov { opacity: 0; }
  .js .demo .quote mark { transition: background-size 1s var(--settle) 3.3s; }
  .js .demo:not(.play) .quote mark { background-size: 0 1.5px; }
  .demo .req-kick { --at: 2.2s; }
  .demo .req-title { --at: 2.3s; }
  .demo .mem-label { --at: 2.75s; }
  .demo .fact { --at: 2.85s; }
  .demo .quote { --at: 3.05s; }
  .demo .prov { --at: 3.8s; }
  .demo .sheet { --at: 4.15s; }
  /* The reply's mark and the fact's number light together once: this is where the words come from. */
  .js .demo.play :is(.n, .sheet-text sup) { animation: cite 1.3s var(--settle) 4.75s both; }

  /* Replay: back to the start in one frame, then again. */
  .js .demo.snap, .js .demo.snap * { transition: none !important; animation: none !important; }
}
@keyframes cite { 0%, 100% { background: transparent; color: var(--ink-3); } 30% { background: var(--highlight); color: var(--ink); } }

/* ---------- narrower: one place under the other, in the order things happen ---------- */
@media (max-width: 960px) {
  .proof-copy h2, .proof-copy .reading { grid-column: 1 / -1; }
  .proof-copy { row-gap: 24px; }
  .demo { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; row-gap: 14px; width: 100%; max-width: 620px; }
  .demo .chat, .demo .notif, .demo .app { grid-column: 1; grid-row: auto; margin: 0; }
  .demo .chat { height: 300px; }
  .demo .notif { justify-self: stretch; width: auto; margin: 4px 10px; }
  .replay { justify-self: start; }
}
@media (max-width: 760px) {
  .demo .chat { height: 276px; }
  .demo .chat-bar { padding: 0 14px; gap: 16px; }
  .demo .chat-log { padding: 0 14px; }
  .demo .msg { grid-template-columns: 30px minmax(0, 1fr); column-gap: 10px; padding-top: 14px; }
  .demo .ask :is(.face, .who) { margin-top: 14px; }
  .demo .face { width: 30px; height: 30px; font-size: 12px; }
  .demo .chat-field { margin: 12px; }
  .demo .notif { margin: 2px 6px; }
  .demo .app-bar { padding: 0 14px; }
  .demo .places { gap: 32px; }
  .demo .app-body { padding: 14px 22px 24px 30px; }
  .demo .req-title { font-size: 22px; }
  .demo .mem { margin-top: 22px; }
  .demo .quote { font-size: 16.5px; }
  .demo .sheet { margin: 22px -8px 0 -14px; padding: 16px 16px 12px; }
  .demo .sheet-text { font-size: 17.5px; }
}
@media (hover: none) {
  .replay .key { display: none; }
}
