/*
 * app-ui.css — the LittleStep app, rendered on the web at 1:1.
 *
 * This is NOT a mockup. Every number below is copied from the app's own source
 * and is checkable against it:
 *
 *   colours, radii, spacing, type scale  → apps/mobile/src/theme/tokens.ts
 *   home screen                          → apps/mobile/app/(tabs)/home.tsx
 *   tab bar                              → apps/mobile/app/(tabs)/_layout.tsx
 *   story detail                         → apps/mobile/app/story/[id]/index.tsx
 *   reader                               → apps/mobile/app/story/[id]/reader.tsx
 *   mark / avatar / chip / trust badge   → apps/mobile/src/ui/*
 *   cover art geometry                   → apps/mobile/src/ui/CoverArt.tsx
 *   copy                                 → apps/mobile/src/i18n/messages/{en,th}.ts
 *   story + moment content               → apps/mobile/src/data/sample.ts
 *
 * React Native's `dp` and the CSS pixel are the same unit, so the screen is
 * laid out in the app's own numbers — 393 × 852, an iPhone 15/16 — and the
 * whole device is then scaled with a single `transform`. Nothing is re-typed at
 * a "web size", which is the only way a phone on a landing page keeps the real
 * proportions instead of looking like a drawing of an app.
 *
 * If a value here and a value in the app disagree, the app is right.
 */

/* ── Device ─────────────────────────────────────────────────────────────
 * The frame is iPhone geometry: a 393 × 852 display with a 55pt corner
 * radius, inside a 12pt case. `--s` scales the lot; the outer box is sized
 * from the same numbers so the layout around it never has to guess.
 */

.device {
  --dw: 393; /* display width, logical px  */
  --dh: 852; /* display height             */
  --bezel: 12;
  --s: 1;
  --frame-w: calc((var(--dw) + var(--bezel) * 2) * 1px);
  --frame-h: calc((var(--dh) + var(--bezel) * 2) * 1px);

  width: calc(var(--frame-w) * var(--s));
  height: calc(var(--frame-h) * var(--s));
  flex: none;
  position: relative;
}

.device__frame {
  width: var(--frame-w);
  height: var(--frame-h);
  transform: scale(var(--s));
  transform-origin: 0 0;
  padding: calc(var(--bezel) * 1px);
  border-radius: 67px;
  /* Titanium case. Cocoa-tinted rather than grey: there is no black here
   * either, and the phone has to sit on cream without punching a hole in it. */
  background: linear-gradient(150deg, #6f5a4c 0%, #3f2617 38%, #59463a 68%, #2e1b10 100%);
  box-shadow:
    0 2px 3px rgba(63, 38, 23, 0.16),
    0 40px 80px -40px rgba(63, 38, 23, 0.55),
    0 14px 30px -18px rgba(63, 38, 23, 0.4);
}

.device__screen {
  position: relative;
  width: calc(var(--dw) * 1px);
  height: calc(var(--dh) * 1px);
  border-radius: 55px;
  overflow: hidden;
  background: #faf7f1; /* colors.cream */
  isolation: isolate;
}

/* ── iOS chrome ─────────────────────────────────────────────────────────
 * Status bar, Dynamic Island and home indicator are the system's, not the
 * app's — so they take the system face, at the sizes iOS actually uses.
 */

.ios-status {
  position: absolute;
  inset: 0 0 auto 0;
  height: 59px; /* the top safe-area inset the app reads from insets.top */
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 30px 0 32px;
  padding-top: 12px;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
  color: #3f2617;
  pointer-events: none;
}

.ios-status__time {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.1px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.ios-status__icons {
  display: flex;
  align-items: center;
  gap: 6px;
}

.ios-status__icons svg {
  display: block;
  fill: currentColor;
}

.ios-island {
  position: absolute;
  top: 11px;
  left: 50%;
  transform: translateX(-50%);
  width: 125px;
  height: 37px;
  border-radius: 999px;
  background: #1b1210;
  z-index: 4;
}

.ios-home {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 139px;
  height: 5px;
  border-radius: 999px;
  background: rgba(63, 38, 23, 0.32);
  z-index: 4;
}

.ios-home--onPaper {
  background: rgba(63, 38, 23, 0.28);
}

/* ── One app screen ─────────────────────────────────────────────────────
 * Screens stack and cross-fade. The inactive ones stay in the DOM (and stay
 * measured) so switching never reflows anything.
 */

.app {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: #faf7f1; /* colors.cream — Screen's default background */
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
  transform: scale(1.012);
}

.app[data-active] {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* The reader runs on paper, not cream — `background={colors.paper}`. */
.app--paper {
  background: #fffdfa;
}

/*
 * `Screen`: contentPad = insets.top + 8 (59 + 8), screenX 24, padBottom 32.
 * The scroll indicator is hidden in the app, so it is hidden here too.
 */
.app__scroll {
  flex: 1;
  min-height: 0;
  padding: 67px 24px 32px;
  overflow: hidden;
  /* A flex column, because React Native's box model has no margin collapsing.
   * Laying it out any other way makes the vertical rhythm drift from the app's
   * by a few px per block, which is exactly the kind of drift that turns a
   * real screen back into a drawing of one. */
  display: flex;
  flex-direction: column;
}

/* Story detail and the reader both take `padX={0}` and place their own
 * horizontal padding per row. */
.app__scroll--edge {
  padding-left: 0;
  padding-right: 0;
}

/* ── Type — theme/tokens.ts `type` ─────────────────────────────────────── */

.app,
.app button,
.app p,
.app h1,
.app h2,
.app h3,
.app h4,
.app span {
  font-family: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.app p,
.app h1,
.app h2,
.app h3,
.app h4 {
  margin: 0;
  font-weight: 400;
}

.ls-display {
  font-weight: 600;
  font-size: 30px;
  line-height: 36px;
  letter-spacing: -0.8px;
  color: #3f2617;
  max-width: 300px;
}

.ls-title {
  font-weight: 600;
  font-size: 28px;
  line-height: 34px;
  letter-spacing: -0.6px;
  color: #3f2617;
}

.ls-body {
  font-size: 16px;
  line-height: 25px;
  color: #7a6355;
}

.ls-bodySmall {
  font-size: 14px;
  line-height: 20px;
  color: #7a6355;
}

.ls-caption {
  font-size: 13px;
  line-height: 18px;
  color: #7a6355;
}

/* `overline` is the one place the app leaves Figtree: it is set in the mono
 * face, which is what gives the label its technical, quiet register. */
.ls-overline {
  display: block;
  font-family: ui-monospace, Menlo, Monaco, 'SF Mono', 'Roboto Mono', monospace;
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #7c6a5a;
}

/* ── The mark ──────────────────────────────────────────────────────────── */

.ls-mark {
  display: block;
  flex: none;
}

/* ── Avatar — ui/Avatar.tsx, size 42 ───────────────────────────────────── */

.ls-avatar {
  width: 42px;
  height: 42px;
  border-radius: 21px;
  background: #f0e3d3; /* beige */
  border: 1px solid rgba(201, 128, 106, 0.35);
  display: grid;
  place-items: center;
  flex: none;
  font-weight: 600;
  font-size: 17.64px; /* size * 0.42 */
  line-height: 21.84px; /* size * 0.52 */
  color: #c6431a; /* clay */
}

/* ── Home — app/(tabs)/home.tsx ────────────────────────────────────────── */

.ls-topRow {
  padding-top: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ls-head {
  padding-top: 36px;
  padding-left: 2px;
  padding-right: 2px;
}

.ls-head .ls-overline {
  margin-bottom: 16px;
}

.ls-focusRow {
  margin-top: 26px;
  border-top: 1px solid rgba(63, 38, 23, 0.11);
  padding-top: 18px;
  display: flex;
  align-items: center;
  gap: 13px;
}

.ls-dot {
  border-radius: 50%;
  background: #ff6a2b;
  flex: none;
}

.ls-dot--12 {
  width: 12px;
  height: 12px;
}

.ls-dot--8 {
  width: 8px;
  height: 8px;
}

.ls-focusCol {
  flex: 1;
  min-width: 0;
}

.ls-focusCol .ls-overline {
  font-size: 10px;
  line-height: 13px;
  letter-spacing: 1.5px;
  margin-bottom: 2px;
}

.ls-focusTitle {
  font-weight: 600;
  font-size: 15px;
  line-height: 20px;
  color: #3f2617;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ls-cards {
  padding-top: 26px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ls-card {
  background: #fffdfa; /* paper */
  border: 1px solid rgba(63, 38, 23, 0.11);
  border-radius: 26px; /* radii.cardLarge */
  padding: 22px; /* spacing.lg */
}

.ls-cardRow {
  display: flex;
  align-items: center;
  gap: 18px;
}

.ls-glyph {
  width: 56px;
  height: 56px;
  border-radius: 28px;
  display: grid;
  place-items: center;
  flex: none;
}

.ls-glyph--beige {
  background: #f0e3d3;
}

.ls-glyph--tangerineSoft {
  background: rgba(255, 106, 43, 0.14);
}

.ls-cardText {
  flex: 1;
  min-width: 0;
}

.ls-cardTitle {
  font-weight: 600;
  font-size: 19px;
  line-height: 24px;
  letter-spacing: -0.2px;
  color: #3f2617;
}

.ls-cardSub {
  font-size: 14px;
  line-height: 19px;
  margin-top: 2px;
  color: #7a6355;
}

.ls-reason {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
}

.ls-reason p {
  font-weight: 600;
  font-size: 11px;
  line-height: 15px;
  letter-spacing: 0.5px;
  color: #7a6355;
}

/* ── Tab bar — app/(tabs)/_layout.tsx ──────────────────────────────────── */

.ls-tabbar {
  flex: none;
  background: #faf7f1;
  border-top: 1px solid rgba(63, 38, 23, 0.11);
  height: 83px; /* 49 bar + 34 bottom inset */
  padding-bottom: 34px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.ls-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding-top: 6px;
}

.ls-tab span {
  font-weight: 600;
  font-size: 11px;
  line-height: 13px;
  color: #7c6a5a;
}

.ls-tab[data-focused] span {
  color: #3f2617;
}

/* ── Story detail — app/story/[id]/index.tsx ───────────────────────────── */

.ls-detailTop {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22px 16px;
}

/* ui/CircleButton.tsx, size 38 */
.ls-circleBtn {
  width: 38px;
  height: 38px;
  border-radius: 19px;
  background: #fffdfa;
  border: 1px solid rgba(63, 38, 23, 0.11);
  display: grid;
  place-items: center;
  font-size: 18px;
  line-height: 22px;
  color: #3f2617;
  flex: none;
}

/* ui/LanguageMenu.tsx trigger */
.ls-langPill {
  height: 38px;
  min-width: 46px;
  padding: 0 12px;
  border-radius: 19px;
  background: #fffdfa;
  border: 1px solid rgba(63, 38, 23, 0.11);
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 13px;
  line-height: 18px;
  color: #3f2617;
}

.ls-detailBody {
  flex: 1;
  min-height: 0;
  padding: 0 24px 24px;
  overflow: hidden;
}

.ls-cover {
  display: block;
  border-radius: 24px;
  overflow: hidden;
}

.ls-detailTitle {
  font-weight: 600;
  font-size: 26px;
  line-height: 31px;
  letter-spacing: -0.6px;
  color: #3f2617;
  margin-bottom: 14px;
}

.ls-chipRow {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-bottom: 16px;
}

/* ui/Chip.tsx, size="sm" */
.ls-chip {
  border-radius: 999px;
  padding: 7px 13px;
  background: #fffdfa;
  border: 1px solid rgba(63, 38, 23, 0.11);
  font-weight: 500;
  font-size: 13px;
  line-height: 18px;
  color: #3f2617;
}

/* ui/TrustBadge.tsx */
.ls-trust {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: #f7efe6;
  border-radius: 999px;
  padding: 8px 14px;
}

.ls-trust__star {
  font-size: 13px;
  line-height: 16px;
  color: #ff6a2b;
}

.ls-trust__text {
  font-weight: 600;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.2px;
  color: #3f2617;
}

.ls-why {
  background: #f7efe6;
  border-radius: 18px;
  padding: 16px 18px;
  margin-top: 18px;
}

.ls-why__overline {
  font-weight: 600;
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #c6431a;
  margin-bottom: 8px;
}

.ls-why p:last-child {
  font-size: 14px;
  line-height: 22px;
  color: #7a6355;
}

.ls-detailFooter {
  flex: none;
  padding: 14px 22px 0;
  background: #faf7f1;
}

/* ui/Button.tsx */
.ls-btn {
  border-radius: 999px;
  padding: 18px 24px;
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
}

.ls-btn--primary {
  background: #3f2617;
  color: #faf7f1;
}

.ls-btn--ghost {
  background: transparent;
  color: #7a6355;
}

/* ── Reader — app/story/[id]/reader.tsx ────────────────────────────────── */

.ls-readerTop {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 24px;
}

.ls-readerClose {
  font-size: 22px;
  line-height: 26px;
  color: #7a6355;
}

.ls-pageCount {
  font-family: ui-monospace, Menlo, Monaco, 'SF Mono', 'Roboto Mono', monospace;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 1px;
  color: #7c6a5a;
}

.ls-readerActions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ls-readerPage {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.ls-readerCopy {
  padding: 30px 30px 0;
}

/* type.reading — 23 / 36, the app's calmest setting */
.ls-reading {
  font-size: 23px;
  line-height: 36px;
  letter-spacing: -0.2px;
  color: #3f2617;
}

/* Quoted dialogue drops to inkSoft, per ReadingText */
.ls-reading q,
.ls-reading .said {
  color: #7a6355;
  quotes: none;
}

.ls-parentLayer {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: flex-start;
}

.ls-parentPill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: #f7efe6;
  border-radius: 999px;
  padding: 8px 14px;
}

.ls-parentPill .ls-caption {
  color: #3f2617;
}

.ls-pager {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 24px 4px;
}

.ls-pager__arrow {
  font-size: 18px;
  line-height: 22px;
  color: #3f2617;
}

.ls-dots {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ls-pagerDot {
  width: 7px;
  height: 7px;
  border-radius: 4px;
  background: #7c6a5a;
  opacity: 0.55;
  flex: none;
}

.ls-pagerDot--active {
  width: 20px;
  border-radius: 999px;
  background: #ff6a2b;
  opacity: 1;
}

/* ── Day complete — home.tsx, the `dayDone` branch ─────────────────────── */

.ls-doneHeader {
  padding-top: 8px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.ls-doneGreeting {
  font-size: 15px;
  line-height: 20px;
  color: #7a6355;
}

.ls-doneName {
  font-weight: 600;
  font-size: 22px;
  line-height: 27px;
  letter-spacing: -0.4px;
  margin-top: 2px;
  color: #3f2617;
}

.ls-doneCenter {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 16px;
  text-align: center;
}

.ls-doneTitle {
  font-weight: 600;
  font-size: 25px;
  line-height: 30px;
  letter-spacing: -0.5px;
  margin: 28px 0 14px;
  color: #3f2617;
}

.ls-doneSummary {
  font-size: 16px;
  line-height: 26px;
  max-width: 280px;
  color: #7a6355;
}

.ls-doneBrowse {
  margin-top: 28px;
  font-weight: 600;
  font-size: 15px;
  line-height: 20px;
  color: #c6431a;
}

/* ── Thai ───────────────────────────────────────────────────────────────
 * The same two rules the app follows. Figtree has no Thai glyphs, so Thai
 * takes the platform face (theme/script-font.ts), and every line height is
 * raised to clear the consonant → vowel → tone-mark stack: THAI_LINE_HEIGHT
 * is 1.65, and a line box measured for Latin shears the top mark off, which
 * turns the word into a different word.
 */

:lang(th) .app,
:lang(th) .app p,
:lang(th) .app h1,
:lang(th) .app h2,
:lang(th) .app h3,
:lang(th) .app h4,
:lang(th) .app span {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, 'Noto Sans Thai', 'Sarabun',
    sans-serif;
  letter-spacing: 0;
}

:lang(th) .ls-display {
  line-height: 49.5px; /* 30 × 1.65 */
  max-width: none;
}

:lang(th) .ls-detailTitle {
  line-height: 42.9px; /* 26 × 1.65 */
}

:lang(th) .ls-doneTitle {
  line-height: 41.25px; /* 25 × 1.65 */
}

:lang(th) .ls-cardTitle {
  line-height: 31.35px; /* 19 × 1.65 */
}

:lang(th) .ls-cardSub,
:lang(th) .ls-bodySmall {
  line-height: 23.1px; /* 14 × 1.65 */
}

:lang(th) .ls-reading {
  line-height: 42px;
}

:lang(th) .ls-focusTitle,
:lang(th) .ls-doneBrowse {
  line-height: 24.75px; /* 15 × 1.65 */
}

:lang(th) .ls-body,
:lang(th) .ls-doneSummary {
  line-height: 26.4px; /* 16 × 1.65 */
}

:lang(th) .ls-caption {
  line-height: 21.45px; /* 13 × 1.65 */
}

/* The mono overline is a Latin device: Thai has no case for `uppercase` to
 * act on, and 2px of tracking pulls tone marks off their consonants. Thai
 * keeps the label's role and drops the mechanics — the same rule as the rest
 * of the site. */
:lang(th) .ls-overline {
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
  line-height: 19.8px;
}

:lang(th) .ls-focusCol .ls-overline {
  font-size: 11px;
  line-height: 18.15px;
}

:lang(th) .ls-why__overline,
:lang(th) .ls-reason p,
:lang(th) .ls-trust__text {
  letter-spacing: 0;
  line-height: 1.65;
}

:lang(th) .ls-why__overline {
  text-transform: none;
}

/* Latin still sets the numbers and the two store-facing words. */
.ls-latin {
  font-family: 'Figtree', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
