/* Snail web app — design tokens, dark mode, components */

:root {
  --bg: #fafaf9;
  --surface: #ffffff;
  --fg: #1c1917;
  --muted: #78716c;
  --border: #e7e5e4;
  --accent: #d97706;
  --accent-hover: #b45309;
  --danger: #dc2626;
  --radius: 8px;
  --font: system-ui, -apple-system, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1c1917;
    --surface: #292524;
    --fg: #e7e5e4;
    --muted: #a8a29e;
    --border: #44403c;
    --accent: #f59e0b;
    --accent-hover: #d97706;
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--fg);
  line-height: 1.6;
  min-height: 100vh;
}

#app {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* Extra top padding for the notch when launched full-screen from the home
     screen (apple-mobile-web-app-capable + viewport-fit=cover). */
  padding: calc(0.75rem + env(safe-area-inset-top)) 1rem 0.75rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

header h1 { font-size: 1.25rem; font-weight: 700; display: flex; align-items: center; gap: 0.5rem; }
.brand-logo { height: 1.8rem; width: auto; display: block; }

nav { display: flex; gap: 0.5rem; align-items: center; }
nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.85rem;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius);
  white-space: nowrap;
}
nav a:hover { color: var(--fg); }
nav a.active { color: var(--accent); font-weight: 600; }

#layout {
  display: flex;
  flex: 1;
  overflow: hidden;
}

#sidebar {
  width: 240px;
  flex-shrink: 0;
  border-right: 1px solid var(--border);
  padding: 1rem;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

#sidebar .sidebar-header {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

#sidebar .group-list { list-style: none; }
#sidebar .group-card {
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius);
  margin-bottom: 0.25rem;
  cursor: pointer;
  transition: background 0.1s;
  font-size: 0.9rem;
}
#sidebar .group-card:hover { background: var(--surface); }
/* The group currently open in the feed — make it unmistakable at a glance. */
#sidebar .group-card.active {
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  font-weight: 600;
  color: var(--accent);
}
#sidebar .group-card.active:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
#sidebar .group-card .meta {
  font-size: 0.7rem;
  color: var(--muted);
  margin-top: 0.1rem;
}

/* Quiet "start a new correspondence" link tucked under the group list. */
#sidebar .new-corr {
  display: block;
  padding: 0.5rem 0.75rem;
  margin-top: 0.25rem;
  border-radius: var(--radius);
  font-size: 0.85rem;
  color: var(--muted);
  text-decoration: none;
}
#sidebar .new-corr:hover { background: var(--surface); color: var(--fg); }
#sidebar .new-corr.active { color: var(--accent); font-weight: 600; }

/* It's your turn to write in this group — bold name, plus the turn-pill in the meta line. */
#sidebar .group-card.your-turn .name { font-weight: 600; }
.turn-pill {
  color: var(--accent);
  font-weight: 600;
  white-space: nowrap;
}

/* Groups disclosure: a static open list on desktop; the summary's active-group
   line is hidden there (the header label carries it). On mobile it collapses to
   a tap-to-expand dropdown. */
.groups-disclosure > summary {
  list-style: none;
  cursor: default;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.groups-disclosure > summary::-webkit-details-marker { display: none; }
.groups-summary-active { display: none; }
/* Desktop renders the <details> with [open] (set in JS by viewport), so the
   list shows natively as a static sidebar; mobile renders it closed → dropdown. */

@media (max-width: 640px) {
  #layout { flex-direction: column; overflow: visible; }
  #sidebar {
    width: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 0.5rem 1rem;
    overflow: visible;
  }
  /* Collapsed by default on mobile (the [open] attr is overridden visually by
     hiding the list unless the user expands). */
  .groups-disclosure > summary { cursor: pointer; }
  .groups-disclosure > summary::after {
    content: "▾";
    color: var(--muted);
    margin-left: auto;
  }
  .groups-disclosure:not([open]) .group-list { display: none; }
  .groups-summary-active { display: inline; color: var(--fg); font-size: 0.9rem; }
}

main {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem 2rem;
}

.auth-screen { max-width: 360px; margin: 4rem auto; text-align: center; }
.auth-screen h2 { margin-bottom: 1.5rem; }

.form-group { margin-bottom: 1rem; text-align: left; }
.form-group label { display: block; font-size: 0.875rem; color: var(--muted); margin-bottom: 0.25rem; }
/* :not([type=checkbox]): a checkbox stretched to width:100% shoves its label
   text out of the box (contacts picker names were invisible). */
.form-group input:not([type="checkbox"]), .form-group select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--fg);
  font-size: 1rem;
}

.btn {
  display: inline-block;
  padding: 0.5rem 1.25rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  font-size: 1rem;
  cursor: pointer;
  font-weight: 600;
}
.btn:hover { background: var(--accent-hover); }
.btn:disabled { opacity: 0.4; cursor: default; }

.group-list { list-style: none; }
.group-card {
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 0.75rem;
  cursor: pointer;
  transition: background 0.15s;
}
.group-card:hover { background: var(--surface); }
.group-card h3 { font-size: 1.1rem; margin-bottom: 0.25rem; }
.group-card .meta { font-size: 0.8rem; color: var(--muted); }

.feed {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 1rem;
}
.feed-meta { margin-bottom: 1.5rem; font-size: .875rem; color: var(--muted); }

/* Group settings, after the letters and before the draft area — where the
   reader already is once they've caught up, rather than back up in the header. */
.feed-settings-link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  margin: 1.5rem auto;
  padding: .7rem 1rem;
  border: 1px solid var(--border);
  border-radius: .5rem;
  color: var(--muted);
  font-size: .875rem;
  text-decoration: none;
  /* Comfortable tap target on mobile without dominating the page. */
  min-height: 44px;
  max-width: 22rem;
}
.feed-settings-link:hover { color: var(--fg); border-color: var(--muted); }
/* The gear carries the affordance, so it reads larger than the label. */
.feed-settings-gear { font-size: 1.35rem; line-height: 1; }
.feed-rotation { margin-top: .25rem; font-size: .8rem; }
.feed-loading { color: var(--muted); text-align: center; padding: 2rem 0; }
.feed-empty { color: var(--muted); text-align: center; padding: 2rem 0; }

/* Author-grouped letter blocks */
.letter-group {
  margin-bottom: 1.75rem;
  border-left: 4px solid var(--border);
  padding: 0.75rem 1rem;
  border-radius: 0 8px 8px 0;
}
/* snail's own notices (cadence/schedule change, member left, reorder). Sits
   between letters as a quiet record of what changed — deliberately NOT styled
   as a letter: no avatar, no author colour, no left border. */
.feed-notice {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 1.75rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.feed-notice-icon { flex: none; }
.feed-notice-text { flex: 1; }
.feed-notice-date { flex: none; font-size: 0.75rem; }
.letter-group-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
.author-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.author-name {
  font-weight: 700;
  font-size: 0.9rem;
}
.letter-date {
  color: var(--muted);
  font-size: 0.75rem;
  margin-left: auto;
}
.letter-body {
  margin-top: 0.25rem;
}
.letter-para {
  margin-bottom: 0.6rem;
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.7;
}

/* Compose section embedded below feed */
.compose-section {
  border-top: 2px solid var(--border);
  padding-top: 1rem;
  margin-top: 0.5rem;
}
.compose-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}
.compose-label { font-size: 0.85rem; font-weight: 600; color: var(--accent); }
.compose-banner {
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
}
.muted-banner {
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border);
}
/* Your-turn call to action — a warm, affirmative banner (vs. the muted draft-
   ahead / paused banners). */
.turn-banner {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  font-weight: 500;
}
.compose-editor {
  width: 100%;
  min-height: 240px;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--fg);
  font-family: var(--font);
  font-size: 0.95rem;
  line-height: 1.7;
  resize: vertical;
}
.compose-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0.5rem;
}
.compose-hint { font-size: 0.75rem; color: var(--muted); }
.compose-hint.over-limit { color: var(--danger); }

.error-banner {
  background: #fef2f2;
  color: var(--danger);
  border: 1px solid #fecaca;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
  font-size: 0.9rem;
}

.notice-banner {
  background: #fffbeb;
  color: #92400e;
  border: 1px solid #fde68a;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
  font-size: 0.9rem;
}

.about { max-width: 560px; margin: 1rem auto; }
.about h2 { margin-bottom: 1rem; }
.about p { margin-bottom: 1rem; }
.about ol { margin: 0 0 1rem 1.25rem; }
.about li { margin-bottom: 0.5rem; }

.landing { max-width: 560px; margin: 2rem auto; }
.landing section { margin-bottom: 2rem; }
.landing-hero h2 { font-size: 2rem; margin-bottom: 0.25rem; }
.hero-logo { height: 7rem; width: auto; display: block; margin-bottom: 0.5rem; }
.h2-logo { height: 1.4em; width: auto; vertical-align: -0.3em; }
.landing-tagline { color: var(--muted); font-size: 1.05rem; margin-bottom: 1rem; }
.landing p { margin-bottom: 1rem; line-height: 1.5; }
.landing h3 { margin-bottom: 0.75rem; }
.landing ol { margin: 0 0 1rem 1.25rem; }
.landing li { margin-bottom: 0.5rem; }
.landing-signin { border-top: 1px solid var(--border, #e3ded8); padding-top: 1.5rem; }
.landing-signin-note { color: var(--muted); font-size: 0.9rem; }

.toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translate(-50%, 1rem);
  background: var(--accent);
  color: #fff;
  padding: 0.6rem 1rem;
  border-radius: 8px;
  font-size: 0.9rem;
  opacity: 0;
  transition: opacity 0.3s, transform 0.3s;
  pointer-events: none;
  z-index: 50;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* Media display in feed */
.media-placeholder {
  display: flex; align-items: center; justify-content: center;
  height: 120px; background: var(--surface); border-radius: 6px;
  color: var(--muted); font-size: 0.85rem;
}
.media-placeholder.loading { opacity: 0.6; }
.media-placeholder.failed { cursor: pointer; color: var(--danger); opacity: 0.85; }
.letter-media {
  max-width: 100%; max-height: 400px; border-radius: 6px;
  margin: 0.5rem 0; display: block; cursor: zoom-in;
}
/* Videos carry width/height attributes so a src-less <video> still has an
   aspect ratio; height:auto keeps those attributes from forcing literal pixel
   dimensions, letting max-width/max-height scale it down to fit. */
video.letter-media { height: auto; background: #000; }
/* Fallback for a video whose dimensions Telegram didn't provide: without this
   it collapses to the 300x150 CSS default. */
video.letter-media:not([width]) { width: 100%; aspect-ratio: 16 / 9; }
.letter-media.doc-link {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.5rem 0.75rem; background: var(--surface);
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--fg); text-decoration: none; font-size: 0.85rem; cursor: pointer;
}

/* Compose attachments */
.compose-attach { margin-bottom: 0.5rem; }
.compose-attach-label {
  cursor: pointer; color: var(--accent); font-size: 0.85rem;
  padding: 0.25rem 0; display: inline-block;
}
.compose-attach-label:hover { text-decoration: underline; }
.attachment-row {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.6rem; background: var(--surface);
  border: 1px solid var(--border); border-radius: 6px;
  margin-bottom: 0.25rem; font-size: 0.8rem;
}
.attachment-row .att-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attachment-row .att-size { color: var(--muted); white-space: nowrap; }

/* Editable letter blocks (one per Telegram message). */
.compose-block {
  position: relative;
  padding: 0.6rem 2rem 0.6rem 2rem;
  border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 0.6rem; background: var(--surface);
}
.compose-block.changed-in-telegram { border-color: var(--accent); }
.compose-block-media { font-size: 0.85rem; color: var(--muted); margin-bottom: 0.35rem; }
.compose-block-img { max-width: 220px; max-height: 220px; border-radius: 6px; display: block; }
.compose-block-media.clickable, .compose-block-img.clickable { cursor: pointer; }
.compose-block.upload-failed { border-color: #c0392b; opacity: 0.7; }
.compose-block-edit {
  width: 100%; min-height: 8rem; resize: vertical;
  padding: 0.75rem 1rem; font-family: var(--font);
  font-size: 0.95rem; line-height: 1.7;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--fg);
}
.compose-block-actions {
  display: flex; align-items: center; gap: 0.5rem; margin-top: 0.4rem;
}
.compose-block-actions .btn { padding: 0.25rem 0.8rem; font-size: 0.8rem; }
.btn-cancel { background: none; color: var(--muted); border: 1px solid var(--border); }
.btn-cancel:hover { background: var(--surface); }
.compose-block-status { font-size: 0.75rem; color: var(--muted); }
.compose-block-date { margin-left: auto; font-size: 0.75rem; color: var(--muted); }
.compose-block-remove {
  position: absolute; top: 0.4rem; right: 0.6rem;
  cursor: pointer; color: var(--muted); font-size: 0.9rem;
}
.compose-block-remove:hover { color: var(--accent); }
.compose-block-drag {
  position: absolute; left: 0.5rem; top: 50%;
  transform: translateY(-50%);
  cursor: grab; color: var(--muted); font-size: 1rem;
  user-select: none; line-height: 1;
  touch-action: none;
}
.compose-block-drag:active { cursor: grabbing; }
.compose-block.dragging { opacity: 0.4; }
.attachment-row .att-remove { cursor: pointer; color: var(--danger); font-weight: 700; padding: 0 0.2rem; }

/* Setup wizard */
.wizard-steps { display: flex; gap: 1rem; margin: 0.75rem 0 1.5rem; font-size: 0.875rem; color: var(--muted); }
.wizard-step.active { color: var(--accent); font-weight: 600; }
.wizard-step.done { color: var(--muted); text-decoration: line-through; }
