/* app.css — dark shell so the white ink render carries the screen.
 * Sized for a phone held at arm's length in a loud, bright exhibition hall:
 * large hit targets, high contrast, nothing that needs precision.
 *
 * Responsive strategy: one fluid column by default, widening to a two-column
 * hero once there is room. Breakpoints are placed where the *content* starts
 * to look wrong rather than at device sizes. */

@font-face {
  font-family: 'Vazirmatn';
  src: url('../assets/fonts/Vazirmatn-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Vazirmatn';
  src: url('../assets/fonts/Vazirmatn-Bold.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  --teal: #1CAF8E;
  --teal-dim: #148f74;
  --bg: #0B0F14;
  --bg-2: #131A22;
  --line: rgba(255, 255, 255, 0.10);
  --fg: #F2F5F7;
  --fg-dim: #96A2AE;
  --warn: #F5A524;
  --radius: 14px;
  --pad: clamp(14px, 4vw, 28px);
  --shell: 720px;
}

* { box-sizing: border-box; }

/* The UA rule for the hidden attribute is [hidden]{display:none} — same
 * specificity as any class, and it loses to an author stylesheet. So a class
 * that sets `display` (.spinner: grid, .btn: inline-flex) silently defeats
 * el.hidden = true. That left the loading overlay permanently on top of the
 * result: nothing was loading, but every re-render happened underneath a dark
 * scrim, so changing style or background looked like it did nothing at all.
 * Never drop this rule. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: Vazirmatn, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

.app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  max-width: var(--shell);
  margin: 0 auto;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ── top bar ─────────────────────────────────────────── */
.topbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px var(--pad);
  border-bottom: 1px solid var(--line);
}
.brand-logo {
  height: clamp(20px, 5.2vw, 28px);
  width: auto;
  /* The wordmark ships as teal-on-transparent; on the dark shell it needs
     lifting rather than recolouring, so brightness beats a filter chain. */
  filter: brightness(1.25);
}
.topbar-right { display: flex; align-items: center; gap: 8px; }
.badge {
  font-size: clamp(9.5px, 2.6vw, 11px);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--teal);
  border: 1px solid rgba(28, 175, 142, 0.45);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}
.lang-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--fg-dim);
  border-radius: 999px;
  padding: 5px 11px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  min-height: 32px;
}
.lang-btn:active { background: var(--bg-2); }

/* ── screens ─────────────────────────────────────────── */
.screen {
  display: none;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
}
.screen.is-active { display: flex; }

/* ── intro ───────────────────────────────────────────── */
.hero {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: clamp(12px, 3.5vh, 22px);
  padding: var(--pad);
  /* Short viewports (landscape phones, small laptops) scroll rather than
     clipping the call to action off the bottom. */
  overflow-y: auto;
}
.hero-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(10px, 2vh, 16px);
  width: 100%;
}
.hero h1 {
  margin: 0;
  font-size: clamp(22px, 6.4vw, 36px);
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}
.sub {
  margin: 0;
  color: var(--fg-dim);
  font-size: clamp(13.5px, 3.7vw, 16.5px);
  max-width: 34ch;
  line-height: 1.6;
  text-wrap: pretty;
}

.hero-art { width: 100%; display: flex; justify-content: center; }
.sample {
  display: flex;
  width: min(100%, 360px);
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg-2);
}
/* Decorative "photo → outline" swatch. Head plus shoulders rather than a bare
   circle, so it reads as a portrait at desktop size. */
.sample-half { flex: 1; position: relative; }
.sample-photo {
  background:
    radial-gradient(ellipse 42% 26% at 50% 104%, #6b5a4c 0 72%, transparent 73%),
    radial-gradient(circle at 50% 40%, #7d6a59 0 19%, transparent 20%),
    linear-gradient(160deg, #3a3a42, #23262c);
}
.sample-ink {
  background:
    radial-gradient(ellipse 42% 26% at 50% 104%, #14181d 0 72%, transparent 73%),
    radial-gradient(circle at 50% 40%, #14181d 0 19%, transparent 20%),
    #fff;
}
/* a couple of stroke marks so the right half reads as line work */
.sample-ink::after {
  content: '';
  position: absolute;
  left: 41%;
  top: 36%;
  width: 18%;
  height: 9%;
  border-top: 2px solid rgba(255, 255, 255, 0.85);
  border-bottom: 2px solid rgba(255, 255, 255, 0.55);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  width: 100%;
}
.privacy {
  margin: 0;
  color: var(--fg-dim);
  font-size: clamp(11.5px, 3vw, 13px);
  max-width: 40ch;
  line-height: 1.6;
  opacity: 0.85;
}

/* ── buttons ─────────────────────────────────────────── */
.btn {
  appearance: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 14px clamp(16px, 5vw, 24px);
  font: inherit;
  font-size: clamp(14px, 3.8vw, 15.5px);
  font-weight: 700;
  cursor: pointer;
  min-height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform .06s ease, background .15s ease;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  flex: 1 1 auto;
  max-width: 260px;
}
.btn:active { transform: scale(0.975); }
.btn-primary { background: var(--teal); color: #05221B; }
.btn-primary:hover { background: var(--teal-dim); }
.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--fg);
}
.btn-ghost:hover { background: var(--bg-2); }
.btn:disabled { opacity: .5; pointer-events: none; }

.btn-icon {
  width: 52px;
  min-height: 52px;
  max-width: 52px;
  flex: 0 0 auto;
  padding: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--fg);
  font-size: 20px;
}

/* ── camera ──────────────────────────────────────────── */
.stage {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  overflow: hidden;
}
.video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.video.is-mirrored { transform: scaleX(-1); }

.guide {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 34% 30% at 50% 42%,
      transparent 0 98%, rgba(0, 0, 0, 0.42) 100%);
}
.guide::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 42%;
  width: min(62%, 42vh);
  aspect-ratio: 3 / 4;
  transform: translate(-50%, -50%);
  border: 2px dashed rgba(28, 175, 142, 0.55);
  border-radius: 50% 50% 46% 46%;
}
.tip, .lighthint {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: 8px 15px;
  border-radius: 999px;
  font-size: clamp(11.5px, 3.2vw, 13px);
  line-height: 1.35;
  text-align: center;
  max-width: min(92%, 420px);
}
.tip {
  bottom: 14px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
}
/* Lighting guidance sits at the top so it never fights the shutter button,
   and is coloured because it is an instruction, not decoration. */
.lighthint {
  top: 14px;
  background: rgba(20, 14, 0, 0.82);
  border: 1px solid rgba(245, 165, 36, 0.55);
  color: var(--warn);
  font-weight: 700;
}
.lighthint.is-ok {
  background: rgba(3, 26, 21, 0.82);
  border-color: rgba(28, 175, 142, 0.5);
  color: var(--teal);
}

.controls {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-around;
  gap: 16px;
  padding: 14px var(--pad) calc(14px + env(safe-area-inset-bottom));
  background: var(--bg);
}
.shutter {
  width: clamp(62px, 18vw, 76px);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, 0.85);
  background: var(--teal);
  cursor: pointer;
  box-shadow: 0 0 0 4px rgba(28, 175, 142, 0.22);
  -webkit-tap-highlight-color: transparent;
  transition: transform .06s ease;
  flex: 0 0 auto;
}
.shutter:active { transform: scale(0.93); }

/* ── result ──────────────────────────────────────────── */
.result-stage { background: var(--bg-2); padding: 12px; }
.preview {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
  background: #fff;
}

.spinner {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 12px;
  background: rgba(11, 15, 20, 0.68);
  padding: var(--pad);
  text-align: center;
}
.spinner-ring {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--teal);
  animation: spin .8s linear infinite;
}
.spinner-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(78%, 260px);
}
.spinner-track {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
.spinner-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--teal);
  transition: width .18s linear;
}
.spinner-pct {
  font-size: 12px;
  font-weight: 700;
  color: var(--teal);
  font-variant-numeric: tabular-nums;
  min-width: 4ch;
  text-align: end;
}
.spinner-note {
  font-style: normal;
  font-size: 13px;
  color: var(--fg-dim);
  max-width: 30ch;
  line-height: 1.5;
  white-space: pre-line;   /* the note is two lines: action + size hint */
}
@keyframes spin { to { transform: rotate(360deg); } }

.panel {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 13px;
  padding: 14px var(--pad) calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}
/* Two columns even on a phone: four stacked groups pushed the Download row
   below the fold. The three-button groups span the full width; the two-button
   ones (background, file type) pair up on a single row. */
.opt-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px 10px;
}
.opt-wide { grid-column: 1 / -1; }
.opt-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.opt-label {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.segmented {
  display: flex;
  flex-wrap: wrap;      /* five style buttons will not fit one row on a phone */
  gap: 6px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 5px;
}
.seg {
  flex: 1 1 auto;
  min-width: 3.6rem;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--fg-dim);
  font: inherit;
  font-size: clamp(12.5px, 3.4vw, 14px);
  font-weight: 700;
  padding: 11px 4px;
  border-radius: 8px;
  cursor: pointer;
  min-height: 44px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-tap-highlight-color: transparent;
}
.seg.is-on { background: var(--teal); color: #05221B; }
.seg.is-busy { opacity: .55; }
/* Looks disabled but still receives clicks, so tapping it explains itself. */
.seg.is-unavailable { opacity: .4; text-decoration: line-through; }

/* ── toast + footer ──────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(22px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 50;
  max-width: min(92vw, 460px);
  padding: 12px 18px;
  border-radius: 12px;
  background: #22272E;
  border: 1px solid var(--line);
  color: var(--fg);
  font-size: 14px;
  line-height: 1.5;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  text-align: center;
}
.toast.is-error { border-color: rgba(255, 107, 107, 0.5); }

.footbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px var(--pad) calc(8px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  font-size: clamp(10px, 2.8vw, 11.5px);
  color: var(--fg-dim);
}
.engine-tag { opacity: .6; font-variant-numeric: tabular-nums; }
.foot-name { opacity: .8; text-align: end; }

/* ── short screens ───────────────────────────────────── */
/* On a 568px-tall phone the preview and a four-group panel cannot both have
   what they want. The controls win: a visitor who cannot reach Download has
   no way to finish, whereas a smaller preview is merely a smaller preview. */
@media (max-height: 660px) {
  /* max-height in vh, not flex-basis in %: the ancestors only carry
     min-height, so a percentage basis has nothing definite to resolve
     against and the stage never actually shrinks. */
  .result-stage { max-height: 42vh; padding: 8px; }
  .panel { gap: 9px; padding-block: 10px; }
  .opt-group { gap: 5px; }
  .seg { padding-block: 9px; min-height: 42px; }
}

/* ── narrow phones (iPhone SE and below) ─────────────── */
@media (max-width: 360px) {
  .hero-art { display: none; }          /* the CTA matters more than decoration */
  .foot-name { display: none; }
  .btn { padding-inline: 14px; }
}

/* ── two columns once the shell has room ─────────────── */
@media (min-width: 700px) {
  :root { --shell: 960px; }
  .hero {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: clamp(24px, 5vw, 56px);
  }
  .hero-copy { align-items: flex-start; text-align: start; flex: 1 1 46%; }
  .hero .cta-row { justify-content: flex-start; }
  .hero-art { flex: 1 1 54%; }
  .sample { width: 100%; max-width: 380px; aspect-ratio: 4 / 3; }
  .opt-wide { grid-column: auto; }
  .panel .cta-row { justify-content: flex-end; }
  .result-stage { padding: 20px; }
}

/* RTL: the hero columns should read right-to-left too. */
[dir="rtl"] .foot-name { text-align: start; }

/* ── landscape phones ────────────────────────────────── */
/* The camera stage would otherwise be crushed between bar and controls. */
@media (max-height: 520px) and (orientation: landscape) {
  .topbar, .footbar { display: none; }
  .hero { flex-direction: row; gap: 20px; padding-block: 10px; }
  .hero-copy { align-items: flex-start; text-align: start; }
  .hero .cta-row { justify-content: flex-start; }
  .hero-art { display: none; }
  .shutter { width: 56px; }
  .controls { padding-block: 8px; }
  .panel { gap: 9px; padding-block: 9px; }
  .opt-grid { grid-template-columns: repeat(3, 1fr); }
  .opt-wide { grid-column: auto; }
}

/* ── desktop pointer refinements ─────────────────────── */
@media (hover: hover) and (min-width: 900px) {
  .app { box-shadow: 0 0 0 1px var(--line); }
  .seg:hover:not(.is-on) { background: rgba(255, 255, 255, 0.05); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
