/* Component library, RTL-first (logical properties throughout — never left/right).
 *
 * Read the shape language before editing: surfaces are generously round and get
 * rounder the bigger they are (--r-xs → --r-xl), elevation is a hairline border
 * rather than a shadow, and an accent edge on the inline-start marks the one card
 * on a screen that matters most. Nothing is styled by colour alone: every state
 * that colour signals also carries an icon, a label, or a border change.
 *
 * The v1 class names (.card-rose, .list-item, .pill, .option-card, .dp-*, …) are
 * kept and re-pointed at the new palette — that is what lets the admin panel's
 * fourteen screens inherit this design without being rewritten.
 */

/* --- cards --------------------------------------------------------------------- */

.card {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s4);
}
.card + .card { margin-block-start: var(--s3); }
.card-xl { border-radius: var(--r-xl); }

/* The screen's principal card — «قرار بعدی», the throwback. One per screen. */
.card-lead { border-inline-start: 3px solid var(--accent); border-radius: var(--r-xl); }

/* An invitation rather than a record: a draft waiting, a first step to take. */
.card-accent {
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
}
.card-dashed { border-style: dashed; border-color: var(--accent-line); }
.card-inset { background: var(--bg-3); border-color: transparent; }
.card-danger { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 34%, transparent); }
.card-quiet { background: transparent; }

.card-press { cursor: pointer; transition: transform var(--dur-micro) var(--ease), border-color var(--dur-micro); }
.card-press:active { transform: scale(0.985); }
.card-press:hover { border-color: var(--line-2); }

/* v1 alias — the old "highlighted card". */
.card-rose { background: var(--accent-soft); border-color: var(--accent-line); }

/* A card built as a <button>: kill the UA chrome, keep the text flowing start-ward. */
.card-btn {
  inline-size: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

/* --- section headers ----------------------------------------------------------- */
/* A label, a hairline that fills the rest of the line, and an optional trailing
   count or action. Used everywhere instead of a bare heading, so a screen reads as
   a sequence of small rooms rather than one long document. */

.sec { margin-block-start: var(--s4); }
.sec-head {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding-inline: 3px;
  margin-block-end: var(--s2);
}
.sec-title { font-size: var(--fs-meta); font-weight: 600; color: var(--ink-2); }
.sec-rule { flex: 1; block-size: 1px; background: var(--line); }
.sec-meta { font-size: var(--fs-small); color: var(--ink-3); flex: none; }
.sec-action {
  flex: none;
  font-size: var(--fs-small);
  color: var(--accent);
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
}

/* --- rows ---------------------------------------------------------------------- */

.list { display: flex; flex-direction: column; gap: var(--s2); }

.row-card {
  display: flex;
  align-items: center;
  gap: var(--s3);
  inline-size: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s3) var(--s4);
  min-height: 52px;
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease), border-color var(--dur-micro);
}
.row-card:active { transform: scale(0.985); }
.row-card:hover { border-color: var(--line-2); }
.row-card.is-static { cursor: default; }
.row-card.is-static:active { transform: none; }

/* v1 alias. */
.list-item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s3) var(--s4);
  min-height: 52px;
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease), border-color var(--dur-micro);
  inline-size: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
}
.list-item:active { transform: scale(0.985); }

/* The leading icon tile on a row. --tile-bg/--tile-ink let a caller tint one
   (a person's colour, a muted past item) without a new class per case. */
.tile {
  flex: none;
  inline-size: 38px;
  block-size: 38px;
  border-radius: var(--r-sm);
  display: grid;
  place-items: center;
  background: var(--tile-bg, var(--bg-3));
  color: var(--tile-ink, var(--accent));
}
.tile-sm { inline-size: 30px; block-size: 30px; border-radius: var(--r-xs); }
.tile-lg { inline-size: 62px; block-size: 62px; border-radius: var(--r-btn); }
.tile-a { --tile-bg: var(--p-a-soft); --tile-ink: var(--p-a); }
.tile-b { --tile-bg: var(--p-b-soft); --tile-ink: var(--p-b); }

.caret { flex: none; color: var(--ink-3); }

/* --- person identity ----------------------------------------------------------- */
/* Side A is a filled dot, side B is a ring — the shape carries the identity so the
   two are still distinguishable in greyscale, and both always sit next to a name. */

.dot { flex: none; inline-size: 9px; block-size: 9px; border-radius: var(--r-pill); }
.dot-a { background: var(--p-a); }
.dot-b { border: 2.5px solid var(--p-b); }
.dot-none { background: var(--line-2); }
.dot-lg { inline-size: 11px; block-size: 11px; }

.who-a { color: var(--p-a); }
.who-b { color: var(--p-b); }

.avatar {
  flex: none;
  inline-size: 34px;
  block-size: 34px;
  border-radius: var(--r-xs);
  display: grid;
  place-items: center;
  font-size: var(--fs-body);
  font-weight: 700;
  color: var(--accent-ink);
}
.avatar-a { background: var(--p-a); }
.avatar-b { background: var(--p-b); }

/* --- buttons ------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 46px;
  padding: var(--s3) var(--s4);
  border: 1px solid transparent;
  border-radius: var(--r-btn);
  background: var(--bg-3);
  color: var(--ink);
  font-family: inherit;
  font-weight: 600;
  font-size: var(--fs-body);
  cursor: pointer;
  inline-size: 100%;
  transition: transform var(--dur-micro) var(--ease), opacity var(--dur-micro);
}
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.45; pointer-events: none; }

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
  font-weight: 700;
  border-radius: var(--r-md);
  min-height: 52px;
}
.btn-ghost { background: transparent; border-color: var(--line-2); color: var(--ink); }
.btn-soft { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.btn-danger { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-inline { inline-size: auto; }
.btn-sm { min-height: 38px; padding: var(--s1) var(--s3); font-size: var(--fs-meta); border-radius: var(--r-sm); }

/* An empty slot asking to be filled — «آزمون تازه», «عکس تازه». Reads as an
   invitation, not as a disabled control, which is why it is dashed and centred. */
.btn-dashed {
  background: transparent;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-card);
  color: var(--ink);
  min-height: 52px;
}
.btn-dashed:hover { border-color: var(--accent); color: var(--accent); }

/* The three-up action row on a date («ویرایش / عکس / رفتیم»). */
.act-row { display: flex; gap: var(--s2); }
.act {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s1);
  padding: var(--s3) var(--s2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease);
}
.act:active { transform: scale(0.97); }
.act .icon { color: var(--ink-2); }
/* Not-yet-available rather than forbidden: «رفتیم» before the date has passed. */
.act-waiting { border-style: dashed; color: var(--ink-3); }
.act-waiting .icon { color: var(--ink-3); }

/* --- chips, tags, pills -------------------------------------------------------- */

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: var(--s2) var(--s4);
  min-height: 42px;
  border-radius: var(--r-pill);
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-meta);
  font-weight: 500;
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease), background var(--dur-micro), color var(--dur-micro);
}
.chip:active { transform: scale(0.96); }
.chip-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.chip-quiet { background: transparent; min-height: 36px; font-size: var(--fs-small); }

/* Read-only metadata attached to a card: «۲ عکس», «یادآوری ۳ ساعت قبل». */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: 5px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
  color: var(--ink-2);
  font-size: var(--fs-small);
}
.tag-accent { background: var(--accent-soft); color: var(--accent); }
.tag-a { background: var(--p-a-soft); color: var(--p-a); }
.tag-b { background: var(--p-b-soft); color: var(--p-b); }
.tag-outline { background: transparent; border: 1px solid var(--line); color: var(--ink-3); }
.tag-dashed {
  background: transparent;
  border: 1px dashed var(--accent-line);
  color: var(--accent);
  cursor: pointer;
  font-family: inherit;
}

/* v1 status pills. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: var(--fs-small);
  font-weight: 600;
  background: var(--bg-3);
  color: var(--ink-3);
}
.pill-ok { background: var(--ok-soft); color: var(--ok); }
.pill-warn { background: var(--warn-soft); color: var(--warn); }
.pill-danger { background: var(--danger-soft); color: var(--danger); }
.pill-rose { background: var(--accent-soft); color: var(--accent); }

/* --- bottom tab bar ------------------------------------------------------------ */

#tabbar {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 40;
  display: flex;
  gap: 2px;
  padding: 7px var(--s2) calc(7px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg-2) 94%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-block-start: 1px solid var(--line);
}
#tabbar.hidden { display: none !important; }
.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s1);
  padding: var(--s2) 2px 5px;
  background: none;
  border: none;
  border-radius: var(--r-btn);
  color: var(--ink-3);
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur-micro), background var(--dur-micro);
}
/* The active tab gets a soft accent bed as well as the colour — the label is never
   the only thing distinguishing it. */
.tab.active { color: var(--accent); background: var(--accent-soft); }

/* --- sheets -------------------------------------------------------------------- */

.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--scrim);
  animation: fade-in var(--dur-micro) both;
}
.sheet {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 61;
  background: var(--bg-2);
  border-block-start: 1px solid var(--line-2);
  border-radius: var(--r-sheet);
  padding: var(--s4) var(--s4) calc(var(--s5) + env(safe-area-inset-bottom));
  max-height: 86vh;
  overflow-y: auto;
  animation: sheet-up var(--dur-std) var(--ease) both;
  max-width: 560px;
  margin-inline: auto;
}
.sheet-handle {
  inline-size: 40px;
  block-size: 4px;
  border-radius: 4px;
  background: var(--line-2);
  margin: 0 auto var(--s3);
}
.sheet h2 { font-size: var(--fs-title); font-weight: 700; }

/* --- toasts -------------------------------------------------------------------- */

#toasts {
  position: fixed;
  inset-inline: var(--s4);
  z-index: 80;
  inset-block-end: calc(var(--tabbar-h) + var(--s4) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  pointer-events: none;
}
.toast {
  background: var(--bg-4);
  border: 1px solid var(--line-2);
  color: var(--ink);
  border-radius: var(--r-btn);
  padding: var(--s3) var(--s4);
  font-size: var(--fs-meta);
  line-height: 1.75;
  text-align: center;
  animation: rise var(--dur-std) var(--ease) both;
  max-width: 560px;
  margin-inline: auto;
  inline-size: fit-content;
}
.toast-error { border-color: color-mix(in srgb, var(--danger) 50%, transparent); }
.toast-success { border-color: color-mix(in srgb, var(--ok) 50%, transparent); }

/* --- skeletons + photo tiles --------------------------------------------------- */

/* One shimmer for both: a photo that is still coming down from Telegram is the
   same "not here yet" state as a card that is still loading. */
.skeleton {
  background: linear-gradient(100deg, var(--bg-3) 30%, var(--bg-4) 50%, var(--bg-3) 70%);
  background-size: 220% 100%;
  animation: shimmer 1.5s linear infinite;
  border-radius: var(--r-btn);
}
.skeleton-line { block-size: 14px; }
.skeleton-card { block-size: 84px; border-radius: var(--r-card); }

/* Photo states. `ok` is a woven placeholder that stays behind a transparent PNG.
 *
 * The photo is positioned ABSOLUTELY, and that is load-bearing rather than tidy: as
 * a normal-flow grid/flex child, a tall portrait resolves `block-size: 100%` against
 * a content-sized track and grows past the tile — a 960×2078 photo rendered 54×117
 * inside a 54px tile and got clipped to a random middle band. Out of flow, the
 * image can never influence the box that crops it, so `aspect-ratio` and the column
 * width decide the square and `object-fit` decides the crop. The flex centring below
 * is for the failed/loading glyph, which IS in flow.
 */
.ph-tile {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: none;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(135deg, var(--bg-3) 0 7px, var(--bg-4) 7px 14px);
}
.ph-tile img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.ph-tile.is-loading {
  background: linear-gradient(100deg, var(--bg-3) 30%, var(--bg-4) 50%, var(--bg-3) 70%);
  background-size: 220% 100%;
  animation: shimmer 1.5s linear infinite;
}
.ph-tile.is-failed {
  background: var(--bg-3);
  border: 1px dashed var(--line-2);
  color: var(--ink-3);
  font-size: var(--fs-small);
}
/* The strip under a past date: a glance at what the day looked like. Scrolls in
   its own box so a long album can never make the page scroll sideways. */
.ph-strip { display: flex; gap: var(--s1); overflow-x: auto; }
.ph-strip .ph-tile, .ph-strip .photo-cell { flex: none; inline-size: 54px; }

/* v1 aliases. */
.photo-cell {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--bg-3);
  cursor: pointer;
  border: none;
  padding: 0;
}
.photo-cell img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.photo-x {
  position: absolute;
  inset-block-start: 4px;
  inset-inline-end: 4px;
  inline-size: 24px;
  block-size: 24px;
  border-radius: 50%;
  border: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: rgb(0 0 0 / 55%);
  color: #fff;
}

/* --- progress ------------------------------------------------------------------ */

.progress { block-size: 6px; border-radius: var(--r-pill); background: var(--bg-4); overflow: hidden; }
.progress > i {
  display: block;
  block-size: 100%;
  border-radius: var(--r-pill);
  background: var(--accent);
  transition: width var(--dur-entrance) var(--ease);
}
.progress-a > i { background: var(--p-a); }
.progress-b > i { background: var(--p-b); }

/* The take-flow's segmented progress: one cell per question, filled when answered,
   outlined where you are. Position and completion are separate signals. */
.prog-cells { display: flex; gap: var(--s1); }
.prog-cells > i {
  flex: 1;
  block-size: 5px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
}
.prog-cells > i.done { background: var(--accent); }
.prog-cells > i.here { background: var(--line-2); outline: 1px solid var(--accent); outline-offset: 2px; }
.prog-cells > i.done.here { background: var(--accent); }

/* Wizard dots: the current step stretches into a bar, so "where am I" survives
   greyscale and doesn't rely on the fill colour. */
.dots { display: flex; align-items: center; gap: var(--s2); }
.dots > i {
  inline-size: 7px;
  block-size: 7px;
  border-radius: var(--r-pill);
  background: var(--bg-4);
  transition: inline-size var(--dur-std) var(--ease), background var(--dur-micro);
}
.dots > i.on { background: var(--accent); }
.dots > i.now { inline-size: 22px; background: var(--accent); }

/* v1 alias. */
.progress-dots { display: flex; gap: 5px; justify-content: center; }
.progress-dots i { inline-size: 7px; block-size: 7px; border-radius: 50%; background: var(--bg-4); transition: all var(--dur-micro); }
.progress-dots i.on { background: var(--accent); }
.progress-dots i.now { background: var(--accent); transform: scale(1.45); }

/* --- empty states -------------------------------------------------------------- */
/* Not a rare screen here — for most features it is the *first* screen, so it gets a
   real headline, a warm sentence, and (where there is one) the first step to take. */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
  text-align: center;
  padding: var(--s5) var(--s4);
}
.empty-glyph {
  inline-size: 66px;
  block-size: 66px;
  border-radius: 24px;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  animation: bloom 600ms ease both;
}
.empty-glyph.tone-b { background: var(--p-b-soft); color: var(--p-b); }
.empty-title { font-size: var(--fs-h2); font-weight: 600; color: var(--ink); }
.empty-title.display { font-family: var(--font-display); font-size: var(--fs-display); font-weight: 400; }
.empty-text { font-size: var(--fs-meta); line-height: 1.95; color: var(--ink-2); max-inline-size: 264px; }

/* --- forms --------------------------------------------------------------------- */

.input, .textarea {
  inline-size: 100%;
  min-height: 46px;
  background: var(--bg-3);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  padding: var(--s2) var(--s3);
  transition: border-color var(--dur-micro);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.input:focus, .textarea:focus { outline: none; border-color: var(--accent); }
.textarea { min-height: 96px; resize: vertical; line-height: 1.9; }
.input-error { border-color: var(--danger) !important; }
.field-label { font-size: var(--fs-meta); color: var(--ink-3); margin-block-end: var(--s1); display: block; }

/* A tap-to-write box that looks like the answer it will hold, not like a form
   field — used for the daily question and the wizard's free-text escape hatch. */
.write-box {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3);
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  cursor: text;
}
.write-box .ph { flex: 1; font-size: var(--fs-meta); color: var(--ink-3); }
.write-send {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}

.switch { position: relative; inline-size: 48px; block-size: 28px; flex: none; cursor: pointer; }
.switch input { opacity: 0; inline-size: 100%; block-size: 100%; position: absolute; cursor: pointer; }
.switch i {
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background: var(--bg-4);
  transition: background var(--dur-std) var(--ease);
  pointer-events: none;
}
.switch i::after {
  content: "";
  position: absolute;
  inset-block-start: 3px;
  inset-inline-start: 3px;
  inline-size: 22px;
  block-size: 22px;
  border-radius: 50%;
  background: var(--bg-2);
  box-shadow: 0 1px 3px rgb(0 0 0 / 25%);
  transition: transform var(--dur-std) var(--ease);
}
.switch input:checked + i { background: var(--accent); }
/* RTL: the knob travels toward the inline-end, which is visually leftward. */
.switch input:checked + i::after { transform: translateX(-20px); }

/* --- quiz: options, review, compare -------------------------------------------- */

.option-card {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  inline-size: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s3) var(--s4);
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease), border-color var(--dur-micro), background var(--dur-micro);
}
.option-card:active { transform: scale(0.985); }
/* The box fills AND a check appears: selection is never colour-only. */
.option-card .opt-box {
  flex: none;
  inline-size: 23px;
  block-size: 23px;
  margin-block-start: 1px;
  /* An explicit 8px, not --r-xs: at 23px square the token's 11px reads as a circle,
     and a circle means "pick one" while these are multi-select. */
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1.5px solid var(--line-2);
  color: var(--accent-ink);
  transition: background var(--dur-micro), border-color var(--dur-micro);
}
.option-card.selected { background: var(--accent-soft); border-color: var(--accent-line); }
.option-card.selected .opt-box { background: var(--accent); border-color: var(--accent); animation: pop var(--dur-std) var(--ease); }
.option-card .opt-text { flex: 1; line-height: 1.65; }

/* v1 alias: the numbered circle. */
.option-card .opt-num {
  flex: none;
  inline-size: 28px;
  block-size: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--bg-3);
  font-weight: 700;
  font-size: var(--fs-meta);
  transition: all var(--dur-micro);
}
.option-card.selected .opt-num { background: var(--accent); color: var(--accent-ink); animation: pop var(--dur-std) var(--ease); }

/* The escape hatch under a multiple-choice question. */
.opt-own {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  inline-size: 100%;
  padding: var(--s3) var(--s4);
  border-radius: var(--r-md);
  border: 1px dashed var(--line-2);
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-meta);
  color: var(--ink-2);
  cursor: pointer;
}
.opt-own.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

/* Review row: question, answer, and an edit affordance while it is still editable. */
.rev { padding: var(--s3) var(--s4); background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-md); }
.rev-head { display: flex; align-items: baseline; gap: var(--s2); }
.rev-n { flex: none; font-size: var(--fs-small); font-weight: 600; color: var(--ink-3); }
.rev-q { flex: 1; font-size: var(--fs-meta); line-height: 1.75; color: var(--ink-2); }
.rev-a { margin-block-start: var(--s2); padding-inline-start: 19px; line-height: 1.85; }
.rev-a.is-none { color: var(--ink-3); }
.rev-edit {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--fs-small);
  color: var(--accent);
  cursor: pointer;
}

/* Compare: one card per question, a coloured rail per person. The rail, the dot,
   and the name all say who — three signals, so colour is never load-bearing. */
.cmp { padding: var(--s4); background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-card); }
.cmp-q { display: flex; align-items: baseline; gap: var(--s2); }
.cmp-sides { margin-block-start: var(--s3); display: flex; flex-direction: column; gap: var(--s3); }
.cmp-side { display: flex; gap: var(--s3); }
.cmp-rail { flex: none; inline-size: 3px; border-radius: var(--r-pill); }
.cmp-rail-a { background: var(--p-a); }
.cmp-rail-b { background: var(--p-b); }
.cmp-who { display: flex; align-items: center; gap: var(--s1); font-size: var(--fs-small); font-weight: 600; }
.cmp-a { margin-block-start: var(--s1); line-height: 1.85; }
.cmp-a.is-empty { color: var(--ink-3); }

/* v1 compare bubbles (kept: the bot-parity chat view is still reachable). */
.bubble { border-radius: var(--r-card); padding: var(--s3) var(--s4); max-inline-size: 88%; inline-size: fit-content; }
.bubble .who { font-size: var(--fs-meta); font-weight: 700; margin-block-end: 2px; }
.bubble-start { background: var(--accent-soft); margin-inline-end: auto; border-start-start-radius: 4px; }
.bubble-end { background: var(--bg-3); margin-inline-start: auto; border-start-end-radius: 4px; }
.bubble-empty { border: 1px dashed var(--line-2); background: transparent; color: var(--ink-3); }

/* Per-question thumbs, quiet by default so they don't compete with the answers. */
.vote-row { display: flex; align-items: center; gap: var(--s1); margin-block-start: var(--s3); }
.vote {
  inline-size: 34px;
  block-size: 30px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: background var(--dur-micro), color var(--dur-micro);
}
.vote.on { background: var(--accent-soft); color: var(--accent); }
.vote-lg { inline-size: 54px; block-size: 46px; border-radius: var(--r-btn); background: var(--bg-3); color: var(--ink-2); }
.vote-lg.on { background: var(--accent-soft); color: var(--accent); }

/* --- countdown ----------------------------------------------------------------- */

.countdown { display: flex; gap: var(--s2); margin-block-start: var(--s3); }
.cd-cell {
  flex: 1;
  text-align: center;
  padding: var(--s3) var(--s1) var(--s2);
  border-radius: var(--r-btn);
  background: var(--bg-3);
}
.cd-cell b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-num);
  font-weight: 400;
  line-height: 1.15;
  color: var(--ink);
}
.cd-cell span { font-size: var(--fs-small); color: var(--ink-3); }
.countdown.cd-over { opacity: 0.5; }

/* --- feed (what the other person did today) ------------------------------------ */

.feed { display: flex; flex-direction: column; gap: var(--s3); }
.feed-row { display: flex; align-items: center; gap: var(--s2); }
.feed-row .icon { flex: none; }
.feed-text { flex: 1; line-height: 1.7; }
.feed-when { flex: none; font-size: var(--fs-small); color: var(--ink-3); }

/* --- stat tiles + grids -------------------------------------------------------- */

.stat { text-align: center; padding: var(--s3); }
.stat .num { color: var(--accent); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }

/* --- upload -------------------------------------------------------------------- */

.drop-card {
  border: 1px dashed var(--accent-line);
  border-radius: var(--r-card);
  background: var(--accent-soft);
  padding: var(--s5);
  text-align: center;
  color: var(--accent);
  cursor: pointer;
  inline-size: 100%;
  font-family: inherit;
}

/* --- Jalali date picker -------------------------------------------------------- */

.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.dp-w { font-size: var(--fs-small); color: var(--ink-3); padding-block: var(--s1); font-weight: 700; }
.dp-d {
  aspect-ratio: 1;
  border: none;
  background: transparent;
  border-radius: 50%;
  font-family: inherit;
  font-size: var(--fs-body);
  color: var(--ink);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background var(--dur-micro) var(--ease), transform var(--dur-micro) var(--ease);
}
.dp-d:disabled { color: color-mix(in srgb, var(--ink-3) 55%, transparent); cursor: default; }
.dp-d.today { box-shadow: inset 0 0 0 1.5px var(--accent-line); }
.dp-d.sel { background: var(--accent); color: var(--accent-ink); font-weight: 700; animation: pop var(--dur-std) var(--ease); }
.dp-d:active:not(:disabled) { transform: scale(0.9); }

/* --- misc ---------------------------------------------------------------------- */

.divider { border: none; border-block-start: 1px solid var(--line); margin-block: var(--s4); }
.hair { block-size: 1px; background: var(--line); }
.badge {
  display: inline-grid;
  place-items: center;
  min-inline-size: 20px;
  block-size: 20px;
  padding-inline: 6px;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.7rem;
  font-weight: 700;
}

/* v1 app bar — still used by the admin panel's screens. */
.appbar { display: flex; align-items: center; gap: var(--s3); margin-block-end: var(--s4); }
.appbar h1 { flex: 1; min-width: 0; }

/* Full-screen gate (outside Telegram / 401 / a long AI job). */
.gate {
  min-height: calc(var(--vh) - var(--topbar-h) - var(--tabbar-h));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  text-align: center;
  padding: var(--s5);
}
.gate .emoji { font-size: 64px; animation: breathe 2.4s var(--ease) infinite; }

/* Pull-to-refresh indicator. */
#ptr {
  position: fixed;
  inset-inline: 0;
  inset-block-start: calc(var(--topbar-h) + 8px);
  z-index: 29;
  display: grid;
  place-items: center;
  pointer-events: none;
  font-size: 22px;
  opacity: 0;
  transition: opacity var(--dur-micro);
}

/* A primary button that is not ready yet. It stays tappable on purpose — tapping
   explains what is missing, which beats a dead control that ignores the tap. */
.btn-idle {
  background: var(--bg-3);
  color: var(--ink-3);
  border-color: transparent;
  border-radius: var(--r-md);
  min-height: 52px;
  font-weight: 700;
}

/* «+۳» — the overflow cell at the end of a photo strip. */
.ph-tile.is-more {
  background: var(--bg-3);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: var(--fs-meta);
  font-weight: 600;
  cursor: default;
}
