/* ===========================================================
   Riitti — the app behind the tap.
   Colours and typefaces come from ../tokens.css, shared with the
   landing page. Nothing here invents a new visual language.

   Written phone-first: this is only ever opened on a phone held
   up to an object, usually in the evening, usually in low light.
   =========================================================== */

/* Two typefaces, both inherited from the landing page and defined in
   tokens.css: Cormorant for voice, Jost for interface. Nothing else. */

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  min-height: 100vh;
  overflow-x: hidden;
}

/* Same film grain as the landing page — it's most of why the two feel related. */
body::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 100;
  opacity: var(--grain);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0   0 0 0 0 0   0 0 0 0 0   0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
}

::selection { background: var(--accent); color: var(--accent-ink); }
:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }
a { color: var(--accent); text-decoration: none; border-bottom: 1px solid transparent; }
a:hover { border-bottom-color: currentColor; }

/* ---------- The field ----------
   A painted sky that breathes. It appears only where you're being asked to
   say something — writing and the moment just after — and never on the
   reading screens, which want to be quiet.

   Everything animated here is a transform or an opacity, so it stays on the
   compositor and doesn't chew through a phone battery held up to a wall. */

.field {
  position: fixed; inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.6s ease;
}
body[data-mood="write"] .field { opacity: 1; }

/* Content sits above the field. */
.appbar, main, .appfoot { position: relative; z-index: 2; }

.field-sky {
  position: absolute; inset: -12%;
  background: url("../assets/prompt-bg.jpg") center / cover no-repeat;
  animation: sky-drift 96s ease-in-out infinite alternate;
  will-change: transform;
}

.blob {
  position: absolute;
  display: block;
  width: 92vmax; height: 92vmax;
  border-radius: 50%;
  filter: blur(64px);
  mix-blend-mode: screen;
  will-change: transform;
}
/* Kept low: these are a drift across the picture, not a second picture. */
.blob-1 {
  top: -34%; left: -26%;
  background: radial-gradient(circle at 50% 50%, rgba(194,133,140,.30), transparent 62%);
  animation: bloom-a 41s ease-in-out infinite alternate;
}
.blob-2 {
  bottom: -40%; right: -30%;
  background: radial-gradient(circle at 50% 50%, rgba(122,74,160,.30), transparent 64%);
  animation: bloom-b 57s ease-in-out infinite alternate;
}
.blob-3 {
  top: 16%; right: -24%;
  background: radial-gradient(circle at 50% 50%, rgba(224,132,66,.26), transparent 60%);
  animation: bloom-c 73s ease-in-out infinite alternate;
}

/* Just enough shade to hold the type — scrims at the top and bottom where the
   bar and footer sit, and a soft vignette. The middle is left alone: the
   picture is the point, and the legibility work is done by the text-shadow on
   the prompt rather than by drowning the colour. */
.field-veil {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(14,11,8,.52) 0%,
      rgba(14,11,8,0)  18%,
      rgba(14,11,8,0)  66%,
      rgba(14,11,8,.58) 100%),
    radial-gradient(135% 95% at 50% 45%, rgba(14,11,8,0) 40%, rgba(14,11,8,.42) 100%);
}

@keyframes sky-drift {
  from { transform: scale(1.04) translate3d(-1.5%, -1%, 0); }
  to   { transform: scale(1.16) translate3d(2.5%, 2%, 0); }
}
@keyframes bloom-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(14vw, 10vh, 0) scale(1.22); }
}
@keyframes bloom-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-12vw, -13vh, 0) scale(0.94); }
}
@keyframes bloom-c {
  from { transform: translate3d(0, 0, 0) scale(0.96); }
  to   { transform: translate3d(-9vw, 12vh, 0) scale(1.16); }
}

/* Stillness for anyone who's asked for it. The sky stays; it stops moving.
   The ASCII blooms on the notes are static anyway, so they're unaffected. */
@media (prefers-reduced-motion: reduce) {
  .field-sky, .blob { animation: none; }
  .field { transition: none; }
}

/* ---------- App bar ---------- */
.appbar {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 50;
}
.appbar-mark { border: none; line-height: 0; flex: 0 0 auto; }
.appbar-mark img { height: 18px; width: auto; display: block; opacity: .9; }
.appbar-obj {
  font-size: 10px; letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--ink-mute); flex: 1 1 auto;
}
.appbar-nav { display: flex; gap: 18px; flex: 0 0 auto; }
.appbar-nav a {
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-soft); border: none;
}
.appbar-nav a:hover, .appbar-nav a.active { color: var(--accent); }

/* ---------- Screens ---------- */
main { display: block; }
.screen {
  max-width: 620px;
  margin: 0 auto;
  padding: 48px 22px 96px;
}
.screen--center {
  min-height: 70vh;
  display: flex; flex-direction: column; justify-content: center;
}
@media (min-width: 720px) {
  .screen { padding: 88px 32px 120px; }
}

.section-label {
  font-size: 10px;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 22px;
  display: inline-flex; align-items: center; gap: 12px;
}
.section-label::before {
  content: ""; display: block; width: 18px; height: 1px; background: var(--accent);
}

.h-app {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(34px, 9vw, 54px);
  line-height: 1.06;
  letter-spacing: -0.01em;
  margin: 0 0 26px;
  color: var(--ink);
}

/* The prompt is the one piece of type that should feel spoken rather than set. */
.prompt {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(28px, 7.5vw, 42px);
  line-height: 1.22;
  margin: 0 0 36px;
  color: var(--ink);
  max-width: 20ch;
}

.lede { font-size: 16px; line-height: 1.7; color: var(--ink-soft); margin: 0 0 28px; }
.whisper { color: var(--ink-mute); font-size: 13px; letter-spacing: 0.24em; text-transform: uppercase; }
.footnote { margin-top: 36px; font-size: 13px; color: var(--ink-mute); }
.footnote a { color: var(--ink-soft); }
.note { font-size: 13px; line-height: 1.65; color: var(--ink-mute); margin: 0 0 18px; }

.plainlist { list-style: none; margin: 0 0 34px; padding: 0; }
.plainlist li {
  font-size: 15px; line-height: 1.65; color: var(--ink-soft);
  padding: 0 0 18px 20px; position: relative;
}
.plainlist li::before {
  content: ""; position: absolute; left: 0; top: 11px;
  width: 6px; height: 1px; background: var(--accent);
}
.plainlist strong { color: var(--ink); font-weight: 500; }

/* ---------- Forms ---------- */
.form-stack { display: flex; flex-direction: column; gap: 26px; align-items: stretch; }
.form-row { display: flex; flex-direction: column; gap: 10px; }
.form-row label { font-size: 10px; letter-spacing: 0.32em; text-transform: uppercase; color: var(--ink-mute); }
.form-row input, .form-row textarea {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;              /* under 16px makes iOS Safari zoom on focus */
  line-height: 1.6;
  padding: 10px 0 14px;
  outline: none;
  border-radius: 0;
  transition: border-color .25s;
  width: 100%;
}
.form-row textarea {
  resize: vertical;
  min-height: 130px;
  font-family: var(--serif);
  font-size: 20px;
  line-height: 1.55;
}
.form-row input:focus, .form-row textarea:focus { border-color: var(--accent); }
.form-row input::placeholder, .form-row textarea::placeholder { color: var(--ink-mute); }

/* Bigger and plainer than the landing page's buttons on purpose. This is read
   on a phone, often in low light, sometimes by someone in their seventies —
   so: 14px not 12px, tighter letter-spacing so the words read as words, and a
   56px minimum so it's a comfortable target for an unsteady thumb. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 14px;
  min-height: 58px;
  padding: 18px 36px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: none;
  align-self: flex-start;
  transition: background .25s ease, color .25s ease, border-color .25s ease, opacity .25s ease;
}
.btn:hover:not(:disabled) { background: var(--ink); color: var(--bg); }
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-primary:hover:not(:disabled) { background: transparent; color: var(--accent); }
.btn:disabled { opacity: .32; cursor: not-allowed; }
.btn .arrow { width: 14px; height: 1px; background: currentColor; position: relative; }
.btn .arrow::after {
  content: ""; position: absolute; right: 0; top: -3px; width: 7px; height: 7px;
  border-right: 1px solid currentColor; border-top: 1px solid currentColor; transform: rotate(45deg);
}
@media (max-width: 520px) { .btn { align-self: stretch; } }

/* Every screen ends in something to press, never in a faint underlined word. */
.cta-stack {
  display: flex; flex-direction: column; gap: 14px;
  align-items: stretch;
  margin-top: 36px;
}
@media (min-width: 560px) {
  .cta-stack { flex-direction: row; gap: 16px; }
  .cta-stack .btn { align-self: auto; }
}
#screen-write .cta-stack, #screen-saved .cta-stack { justify-content: center; }

/* An outline button over the field needs something to sit on. */
body[data-mood="write"] .btn:not(.btn-primary) {
  border-color: rgba(255,255,255,.72);
  color: #fff;
  background: rgba(20,10,4,.26);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
}
body[data-mood="write"] .btn:not(.btn-primary):hover {
  background: rgba(255,255,255,.92); color: var(--accent-ink);
}

.form-error {
  font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--accent); margin: 0;
}

.success {
  font-family: var(--serif); font-style: italic; font-size: 26px;
  color: var(--accent); line-height: 1.4; margin: 0;
}
.success::before { content: "✦"; display: inline-block; margin-right: 14px; }

/* ---------- Consent checkbox ----------
   Deliberately ordinary and deliberately large. No pre-tick, no dark pattern,
   nothing clever — the point is that it's obvious what's being agreed to. */
.checkrow {
  display: flex; align-items: flex-start; gap: 14px;
  margin: 0 0 32px;
  font-size: 15px; line-height: 1.6; color: var(--ink-soft);
  cursor: pointer;
}
.checkrow input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto;
  width: 22px; height: 22px; margin: 1px 0 0;
  border: 1px solid var(--ink-soft);
  background: transparent;
  border-radius: 0;
  cursor: pointer;
  position: relative;
  transition: border-color .2s, background .2s;
}
.checkrow input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
.checkrow input[type="checkbox"]:checked::after {
  content: ""; position: absolute; left: 7px; top: 3px;
  width: 6px; height: 11px;
  border-right: 1.5px solid var(--accent-ink); border-bottom: 1.5px solid var(--accent-ink);
  transform: rotate(45deg);
}

/* ---------- The writing moment ----------
   Centred, quiet, and floating on the field rather than sitting in a form.
   Everything here is scoped to the write and saved screens; the reading
   screens stay left-aligned and plain, because reading wants a margin to
   start from and writing wants a centre to arrive at. */

#screen-write, #screen-saved {
  text-align: center;
  /* Fill what's left between the bar and the footer so the composition sits
     in the middle of the screen rather than floating near the top of it.
     svh keeps it honest while mobile browser chrome slides in and out. */
  min-height: calc(100svh - 190px);
  padding-top: 24px;
  padding-bottom: 32px;
}
@supports not (height: 100svh) {
  #screen-write, #screen-saved { min-height: calc(100vh - 190px); }
}
#screen-write .section-label { justify-content: center; }
#screen-write .prompt {
  margin-left: auto; margin-right: auto;
  max-width: 17ch;
  font-size: clamp(30px, 8vw, 50px);
  text-wrap: balance;
}
#screen-write .form-row label { text-align: center; }
#screen-write .form-stack { gap: 34px; }
#screen-write .btn, #screen-saved .btn { align-self: center; }

#screen-write .form-row textarea {
  min-height: 54px;
  overflow: hidden;              /* it grows to fit instead of scrolling */
  text-align: center;
  font-size: 22px;
}

/* The top bar shouldn't cut a hard band across the sky. */
body[data-mood="write"] .appbar {
  background: linear-gradient(to bottom, rgba(14,11,8,.55), transparent);
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* A soft shadow does the legibility work instead of a heavy veil, so the
   picture stays as saturated as it was painted. */
body[data-mood="write"] .prompt {
  color: #fff;
  text-shadow: 0 2px 34px rgba(20,10,4,.62), 0 1px 4px rgba(20,10,4,.34);
}
body[data-mood="write"] .success { text-shadow: 0 2px 30px rgba(20,10,4,.6); }
body[data-mood="write"] .section-label,
body[data-mood="write"] .form-row label,
body[data-mood="write"] .footnote { text-shadow: 0 1px 12px rgba(20,10,4,.6); }
body[data-mood="write"] .form-row textarea { color: #fff; text-shadow: 0 1px 16px rgba(20,10,4,.5); }

/* Muted greys read as dirt over colour, so lift everything on the field. */
body[data-mood="write"] .section-label { color: rgba(255,255,255,.78); }
body[data-mood="write"] .appbar-obj { color: rgba(238,225,224,.55); }
body[data-mood="write"] .footnote { color: rgba(238,225,224,.66); }
body[data-mood="write"] .footnote a { color: rgba(238,225,224,.92); }
body[data-mood="write"] .form-row label { color: rgba(238,225,224,.7); }
body[data-mood="write"] .form-row textarea { border-bottom-color: rgba(238,225,224,.34); }
body[data-mood="write"] .form-row textarea::placeholder { color: rgba(238,225,224,.42); }
body[data-mood="write"] .form-row textarea:focus { border-bottom-color: rgba(238,225,224,.8); }
body[data-mood="write"] .success { color: var(--ink); }
body[data-mood="write"] .appfoot { border-top-color: rgba(238,225,224,.14); }
body[data-mood="write"] .appfoot a { color: rgba(238,225,224,.5); }

/* ---------- Entries ----------
   Not a feed — a stack of digital notes. Each one carries a piece of the same
   sky the writing screen sits on, seen through a different window, with an
   ASCII bloom drawn from a hash of what's actually written on it. Two notes
   are never the same, and the pattern is the same every time you come back to
   it: the object's own handwriting, in a sense. */

.entries { display: flex; flex-direction: column; gap: 18px; margin-bottom: 8px; }

.entry {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: 24px 24px 22px;
  border-radius: 22px;
  border: 1px solid rgba(238,225,224,.14);
  box-shadow: 0 22px 44px -26px rgba(0,0,0,.95);
}

/* The window onto the sky. Position and scale vary per note, set in app.js. */
.entry-sky {
  position: absolute; inset: 0;
  background-image: url("../assets/prompt-bg.jpg");
  background-size: 260% auto;
  z-index: 0;
}
/* Enough shade to read against, without losing the colour underneath. */
.entry-sky::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(105deg, rgba(14,11,8,.74) 0%, rgba(14,11,8,.42) 62%, rgba(14,11,8,.30) 100%);
}

.entry-meta {
  position: relative; z-index: 2;
  font-family: var(--sans);
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(238,225,224,.5);
  margin-bottom: 14px;
  display: flex; flex-direction: column; gap: 7px; align-items: flex-start;
}
.entry-prompt {
  font-family: var(--serif);
  font-style: italic;
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 14px;
  color: rgba(238,225,224,.58);
}

.entry-body {
  position: relative; z-index: 2;
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 400;
  line-height: 1.42;
  color: #fff;
  text-shadow: 0 1px 18px rgba(14,11,8,.7);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  margin: 0;
}

.entry-delete {
  position: relative; z-index: 2;
  display: inline-flex; align-items: center;
  margin-top: 18px; padding: 9px 18px;
  min-height: 38px;
  background: rgba(14,11,8,.3);
  border: 1px solid rgba(238,225,224,.28);
  border-radius: 999px;
  font-family: var(--sans); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(238,225,224,.7); cursor: pointer;
  transition: background .2s, color .2s, border-color .2s;
}
.entry-delete:hover {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
}

.entries-empty {
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  color: var(--ink-soft);
  padding: 24px 0 8px;
  margin: 0;
}

/* ---------- Help / prose ---------- */
.qa { border-top: 1px solid var(--rule); padding: 22px 0; }
.qa h3 { font-family: var(--sans); font-size: 13px; letter-spacing: 0.1em; font-weight: 500; margin: 0 0 8px; color: var(--ink); }
.qa p { margin: 0; font-size: 15px; line-height: 1.7; color: var(--ink-soft); }

.prose h2 {
  font-family: var(--serif); font-weight: 300; font-size: 30px;
  margin: 56px 0 4px; color: var(--ink);
  border-top: 1px solid var(--rule); padding-top: 34px;
}
/* The page now opens straight on "Terms of service" — no rule above the first
   one, or the screen starts with a stray line. */
.prose h2:first-child { border-top: none; padding-top: 0; margin-top: 0; }
.prose h3 { font-family: var(--sans); font-size: 12px; letter-spacing: 0.24em; text-transform: uppercase; color: var(--ink-mute); margin: 30px 0 8px; font-weight: 500; }
.prose p { font-size: 15px; line-height: 1.75; color: var(--ink-soft); margin: 0 0 14px; }
.prose .meta { font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-mute); }

.datatable { width: 100%; border-collapse: collapse; margin: 16px 0 24px; font-size: 13px; }
.datatable th, .datatable td {
  text-align: left; vertical-align: top;
  padding: 12px 12px 12px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-soft); line-height: 1.55;
}
.datatable th { color: var(--ink-mute); font-weight: 400; font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase; }

/* On a phone, three columns of this is unreadable — each row becomes a small
   labelled block instead, at a size someone can actually read. */
@media (max-width: 620px) {
  .datatable, .datatable tbody, .datatable tr, .datatable td { display: block; width: 100%; }
  .datatable thead { display: none; }
  .datatable tr {
    border-bottom: 1px solid var(--rule);
    padding: 20px 0;
  }
  .datatable tr:first-child { border-top: 1px solid var(--rule); }
  .datatable td { border: none; padding: 0 0 14px; font-size: 15px; line-height: 1.6; }
  .datatable td:last-child { padding-bottom: 0; }
  .datatable td::before {
    content: attr(data-label);
    display: block;
    font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: 5px;
  }
}

/* ---------- Admin ---------- */
.specs { margin: 0 0 40px; padding: 0; }
.specs .row {
  display: flex; justify-content: space-between; gap: 20px;
  border-bottom: 1px solid var(--rule); padding: 14px 0;
}
/* The first panel below draws its own top rule; without this the two stack
   into what looks like an empty row. */
.specs .row:last-child { border-bottom: none; }
.specs dt { font-size: 10px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--ink-mute); margin: 0; }
.specs dd { margin: 0; font-size: 15px; color: var(--ink); }

.panel { border-top: 1px solid var(--rule); padding: 30px 0; }
.panel h3 { font-family: var(--serif); font-weight: 400; font-size: 24px; margin: 0 0 10px; color: var(--ink); }
.panel--danger h3 { color: var(--accent); }
.panel--danger .btn { border-color: var(--accent); color: var(--accent); }
.panel--danger .btn:hover:not(:disabled) { background: var(--accent); color: var(--accent-ink); }
.panel .checkrow { margin-bottom: 0; }

/* ---------- Footer ---------- */
.appfoot {
  border-top: 1px solid var(--rule);
  padding: 22px 22px 30px;
  display: flex; flex-wrap: wrap; justify-content: center;
  column-gap: 18px; row-gap: 8px;
}
.appfoot a {
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-mute); border: none; white-space: nowrap;
}
.appfoot a:hover { color: var(--accent); }
