/* Share Studio.
 *
 * Follows the JUZZ design rules:
 *   - No `transition: all`. Every transition names its properties.
 *   - No `ease-in`. Entrances use a strong ease-out; on-screen movement uses
 *     a strong ease-in-out. Both are custom curves, not the CSS keywords.
 *   - UI transitions stay under 300ms.
 *   - Every press target is at least 44px.
 *   - Sentence case throughout. No tracked all-caps labels.
 *   - Information carrying structure only: rules and depth are used to group,
 *     not to decorate.
 */

.studio-body {
  /* The studio used to carry its own palette: navy ground, mint accent, gold
   * hairlines. None of those three appear anywhere else on the site — the
   * site is warm off-white or charcoal, emerald or violet, with gold used
   * sparingly — so the one page that makes the share image looked like it
   * belonged to a different product. That is what was wrong with it.
   *
   * Every token below now points at the app's own token, so the studio
   * inherits the light and dark themes, the accent, and the borders the rest
   * of the site already paints. Nothing here is a new colour.
   */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-spring: cubic-bezier(0.32, 1.36, 0.5, 1);
  --surface-0: var(--bg);
  --surface-1: var(--surface);
  --surface-2: var(--surface-2);
  --hairline: var(--border);
  --hairline-strong: var(--border-strong, var(--border));
  /* NOT `--text: var(--text)`. A custom property defined in terms of itself is
     invalid at computed-value time and falls back to the initial value, which
     for color is black — so the studio painted black text on the charcoal
     dark theme. The app's :root already defines --text, so the studio just
     inherits it by not redeclaring it. */
  --text-soft: var(--text-2);
  --text-faint: var(--muted);
  --accent: var(--emerald);
  --accent-ink: var(--on-emerald);
  --accent-bright: var(--emerald-bright);
  --gold: var(--amber);
  --radius-card: 20px;
  --radius-control: 12px;
  margin: 0;
  min-height: 100vh;
  background: var(--surface-0);
  color: var(--text);
  font-family: var(--sans, Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The page has to be able to scroll.
 *
 * This stylesheet is loaded after app-v46.css, which is written for the
 * listening app's fixed shell: `html{height:100%}` and
 * `body{height:100vh;height:100dvh;overflow:hidden;display:grid}`. Every other
 * page on the site lives inside that shell's `.scroll` pane, which is what
 * actually scrolls. The studio is a document, not a pane — it sits outside
 * `.scroll` — so it inherited the lock and had nothing to scroll with.
 *
 * Measured on a 390x844 phone before this: the document was 1515px tall inside
 * an 844px window, `body` computed to `overflow:hidden`, and there was no
 * scrollable element anywhere on the page. The bottom 671px — the size picker,
 * the background picker, the translation control and the download button —
 * could not be reached by touch, by wheel, or by keyboard. The page simply
 * died at the fold, which is exactly what "it won't scroll down" was.
 *
 * The mobile layout below was already designed for scrolling: a preview pinned
 * to the top with the controls sliding under it, and a fixed action bar. None
 * of that could ever work while the document refused to move.
 */
html:has(body.studio-body) {
  height: auto;
}
body.studio-body {
  /* block, not the shell's grid: the studio lays itself out. */
  display: block;
  height: auto;
  min-height: 100dvh;
  overflow: visible;
  grid-template-columns: none;
  grid-template-rows: none;
  /* iOS Safari: without this the momentum scroll stutters on long pages. */
  -webkit-overflow-scrolling: touch;
}

.studio-body :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

.studio {
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 20px 96px;
}

/* ------------------------------------------------------------------- top */

.studio-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 40px;
  /* The nav is three links plus a wordmark. On a 390px phone that is wider
     than the viewport, and the last link was being clipped off the right
     edge rather than wrapping. Wrapping keeps every destination reachable. */
  flex-wrap: wrap;
  row-gap: 10px;
}

.studio-brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  min-height: 44px;
}

/* The header carries the real wordmark now. It is a little smaller than the
   sidebar's because the studio's top bar is one line tall. */
.studio-brand .juzz-wordmark { width: 156px; height: auto; display: block; }
.studio-brand .wordmark-dark { display: none; }
html[data-theme="dark"] .studio-brand .wordmark-light { display: none; }
html[data-theme="dark"] .studio-brand .wordmark-dark { display: block; }

.studio-nav {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.studio-nav a {
  color: var(--text-soft);
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  padding: 10px 14px;
  border-radius: 999px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  transition: color 140ms ease, background-color 140ms ease;
}
.studio-nav a:hover { color: var(--text); background: var(--surface-2); }
.studio-nav a:active { transform: scale(0.97); }

/* ----------------------------------------------------------------- intro */

.studio-intro { max-width: 60ch; margin-bottom: 40px; }
.studio-intro h1 {
  font-size: clamp(30px, 5vw, 44px);
  line-height: 1.08;
  letter-spacing: -0.028em;
  font-weight: 700;
  margin: 0 0 14px;
  text-wrap: balance;
}
.studio-intro p {
  margin: 0;
  color: var(--text-soft);
  font-size: 17px;
  line-height: 1.6;
  text-wrap: pretty;
}

/* ------------------------------------------------------------------ grid */

.studio-grid {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(320px, 420px);
  gap: 48px;
  align-items: start;
}

@media (max-width: 860px) {
  .studio-grid { grid-template-columns: 1fr; gap: 22px; }
  /* Two comboboxes side by side on a 390px screen is about 165px each. A
     surah name does not fit in that, so they get a row apiece. */
  .field-row { grid-template-columns: 1fr; gap: 18px; }
  .studio {
    /* Room for the pinned action bar so the last control is never trapped
       underneath it. */
    padding: 20px 16px calc(104px + env(safe-area-inset-bottom));
  }
  /* Chrome above the controls, measured on a 390x844 phone before this pass:
     header 140px + intro 152px + preview 311px = 603px of a 844px screen
     spent before the first field. The person came here to make a card, not to
     read a pitch twice. Tightened, the first three controls clear the fold. */
  .studio-top { margin-bottom: 16px; padding-bottom: 14px; }
  .studio-intro { margin-bottom: 14px; }
  .studio-intro h1 { font-size: 27px; margin-bottom: 6px; }
  .studio-intro p { font-size: 15.5px; line-height: 1.5; }

  /* Measured before this change: on a 390x844 phone the surah picker sat at
     y=976 and the download button at y=1548, both far below an 844px fold,
     because the 9:16 preview consumed 607px of the viewport. You had to
     scroll past a card you had not chosen yet to reach the field that
     chooses it.

     Two changes fix that. The preview shrinks, and it then pins itself to
     the top of the viewport so the controls scroll underneath it and you
     watch the card change as you pick. A live preview you cannot see while
     typing is just a picture.

     The selector carries `.studio-stage` because the base rule is
     `.stage-frame img { max-height: 68vh }` — same specificity, declared
     later, so a bare `.studio-stage img` silently lost. */
  .stage-frame { padding: 12px; border-radius: 16px; }
  /* Hug the card instead of framing empty space.
   *
   * The frame is a full-width grid cell with a 26vh image inside it, so on a
   * 390px phone it was a 358x360 panel holding a 220px-tall card: a third of
   * the panel was nothing, on both axes. Sizing the frame to the card's own
   * 9:16 keeps the panel the same shape as what it contains. */
  .studio-stage .stage-frame {
    width: min(100%, calc(26vh * 0.5625 + 24px));
    margin-inline: auto;
  }
  /* The three-option control holds "Both", "Arabic", "English" on one line.
     At 14.5px "Arabic + English" wrapped inside a 115px track and left the
     other two buttons sitting on a taller row than they needed. */
  .segmented.segmented-lang button { font-size: 13.5px; padding-inline: 4px; }
  .studio-stage {
    position: sticky;
    top: 0;
    z-index: 20;
    /* The pinned preview needs an opaque back, or the form shows through it
       as it scrolls under. */
    background: var(--surface-0);
    padding-bottom: 10px;
  }
  .studio-stage .stage-frame img { max-height: 26vh; }
  .studio-stage { gap: 8px; }
  .studio-stage .stage-note { font-size: 12.5px; }

  /* Primary action stays in the thumb zone, per Apple HIG rule 1.3, instead
     of scrolling away. The bar is translucent and blurs what passes under it,
     which is the iOS toolbar treatment. */
  .actions-primary {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 40;
    margin: 0;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    /* Was rgba(9,22,35,.86) — a navy scrim. On a white page that is a black
       band, and on the app's charcoal it is the wrong black. color-mix on the
       page ground keeps it legible in both themes. */
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: blur(16px) saturate(1.4);
    -webkit-backdrop-filter: blur(16px) saturate(1.4);
    border-top: 1px solid var(--hairline);
  }
  .actions-primary .btn-primary { min-height: 50px; }
}

/* ----------------------------------------------------------------- stage */

.studio-stage {
  position: sticky;
  top: 28px;
  display: grid;
  gap: 14px;
}
@media (max-width: 860px) {
  /* Sticky at top: 0 on mobile, set in the mobile block above. The old rule
     here un-stuck it, which is why the preview scrolled away. */
  .studio-stage { top: 0; }
  /* The frame's desktop min-height would otherwise hold the shrunken mobile
     preview in a 300px box. */
  .stage-frame { min-height: 0; }
}

.stage-frame {
  position: relative;
  border-radius: var(--radius-card);
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--emerald-bright) 6%, transparent), rgba(0, 0, 0, 0) 60%),
    var(--surface-1);
  border: 1px solid var(--hairline);
  padding: 18px;
  display: grid;
  place-items: center;
  min-height: 300px;
  overflow: hidden;
}

.stage-frame img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 68vh;
  object-fit: contain;
  border-radius: 10px;
  background: var(--surface-2);
  /* The card fades in when a new render lands, so the swap reads as a
     change rather than a flicker. */
  opacity: 0;
  transition: opacity 180ms var(--ease-out);
}
.stage-frame img.is-ready { opacity: 1; }

.stage-loading {
  position: absolute;
  inset-inline-end: 26px;
  bottom: 26px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--text-soft);
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  border: 1px solid var(--hairline);
  padding: 7px 13px;
  border-radius: 999px;
  backdrop-filter: blur(8px);
}

.stage-spinner {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--emerald-bright) 28%, transparent);
  border-top-color: var(--accent);
  /* Fast spin reads as a faster render even when the render is the same
     length. Constant motion, so linear is correct here. */
  animation: spin 620ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.stage-note {
  margin: 0;
  min-height: 1.4em;
  font-size: 13.5px;
  color: var(--text-faint);
  text-align: center;
}

/* -------------------------------------------------------------- controls */

.studio-controls { display: grid; gap: 26px; }

.field { display: grid; gap: 9px; }
.field-row { grid-template-columns: 1fr 1fr; gap: 18px; }
.field-half { display: grid; gap: 9px; align-content: start; }

.field-label {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-soft);
  letter-spacing: 0;
}

.field-hint {
  margin: 0;
  font-size: 12.5px;
  color: var(--text-faint);
  line-height: 1.5;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- inputs */

input[type="text"],
input[type="number"],
textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  color: var(--text);
  font: inherit;
  font-size: 15.5px;
  padding: 13px 15px;
  border-radius: var(--radius-control);
  min-height: 46px;
  transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease;
}
input[type="text"]::placeholder,
textarea::placeholder { color: var(--text-faint); }

input[type="text"]:hover,
input[type="number"]:hover,
textarea:hover { border-color: var(--hairline-strong); }

input[type="text"]:focus,
input[type="number"]:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--emerald-bright) 16%, transparent);
}

textarea { resize: vertical; line-height: 1.55; font-size: 14px; }

/* number input: hide spinners, we ship our own stepper */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; text-align: center; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.stepper {
  display: grid;
  grid-template-columns: 46px 1fr 46px;
  gap: 0;
  align-items: stretch;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-control);
  overflow: hidden;
  transition: border-color 150ms ease;
}
.stepper:focus-within { border-color: var(--accent); }
.stepper input {
  border: none;
  border-radius: 0;
  background: transparent;
  min-height: 46px;
}
.stepper input:focus { box-shadow: none; }
.step {
  border: none;
  background: transparent;
  color: var(--text-soft);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  min-height: 46px;
  transition: background-color 130ms ease, color 130ms ease, transform 110ms ease;
}
.step:hover { background: var(--surface-2); color: var(--text); }
.step:active { transform: scale(0.94); }

/* ------------------------------------------------------------- combobox */

.combo { position: relative; }
.combo-list {
  position: absolute;
  /* Above the pinned action bar (z-index 40). The list used to sit at 30, so
     on a phone it opened under the Download button and every tap on a result
     hit the button instead — which is why picking a surah appeared to do
     nothing at all. */
  z-index: 60;
  inset-inline: 0;
  top: calc(100% + 6px);
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--surface-2);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-control);
  max-height: 292px;
  overflow-y: auto;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
  /* Grows from the trigger, not from the middle. */
  transform-origin: top center;
  animation: combo-in 150ms var(--ease-out);
}
@keyframes combo-in {
  from { opacity: 0; transform: scale(0.97) translateY(-5px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
/* When there is no room below, the list flips above the trigger. It has to
   come from somewhere, so it grows from the edge it is anchored to. */
.combo-list.is-up {
  top: auto;
  bottom: calc(100% + 6px);
  transform-origin: bottom center;
  animation-name: combo-in-up;
}
@keyframes combo-in-up {
  from { opacity: 0; transform: scale(0.97) translateY(5px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.combo-list li {
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 15px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  transition: background-color 110ms ease;
}
.combo-list li[aria-selected="true"],
.combo-list li:hover { background: color-mix(in srgb, var(--emerald-bright) 14%, transparent); }
.combo-list li .combo-ar {
  font-family: Amiri, serif;
  font-size: 18px;
  color: var(--gold);
  direction: rtl;
}
.combo-list li .combo-sub { font-size: 12.5px; color: var(--text-faint); }
.combo-empty { padding: 12px; color: var(--text-faint); font-size: 14px; }

/* ----------------------------------------------------------- segmented */

.segmented {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 3px;
  padding: 3px;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-control);
}
.segmented button {
  border: none;
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  padding: 11px 10px;
  min-height: 44px;
  border-radius: 9px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out), transform 110ms ease;
}
.segmented button:hover { color: var(--text); }
.segmented button:active { transform: scale(0.97); }
.segmented button[aria-checked="true"] {
  background: var(--accent);
  color: var(--accent-ink);
}
.segmented button[aria-checked="true"]:hover { color: var(--accent-ink); }

/* A colour chip carries its own edge whatever it is showing: the Night
   swatch is nearly the value of the control behind it. */
.swatch {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.34);
  flex: none;
}
.swatch-cyan { background: linear-gradient(180deg, #0A7D9C 0%, #17A9C6 42%, #FFFFFF 100%); }
.swatch-layl { background: #0A1826; }
.swatch-sahifa { background: #F7F2E6; }

/* --------------------------------------------------------------- toggle */

.toggle {
  display: flex;
  align-items: center;
  gap: 13px;
  cursor: pointer;
  min-height: 44px;
  user-select: none;
}
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track {
  position: relative;
  width: 46px;
  height: 28px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  flex: none;
  transition: background-color 170ms var(--ease-out), border-color 170ms var(--ease-out);
}
.toggle-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--text-soft);
  transition: transform 190ms var(--ease-spring), background-color 170ms ease;
}
.toggle input:checked + .toggle-track { background: var(--accent); border-color: var(--accent); }
.toggle input:checked + .toggle-track .toggle-thumb { transform: translateX(18px); background: var(--accent-ink); }
.toggle input:focus-visible + .toggle-track { outline: 2px solid var(--accent); outline-offset: 3px; }
.toggle-text { font-size: 15px; color: var(--text-soft); }

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

.actions-primary { display: flex; gap: 10px; }

.btn-primary {
  flex: 1;
  border: none;
  cursor: pointer;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  min-height: 52px;
  padding: 14px 22px;
  border-radius: var(--radius-control);
  background: var(--accent);
  color: var(--accent-ink);
  transition: transform 120ms var(--ease-out), filter 150ms ease, box-shadow 150ms ease;
  box-shadow: 0 1px 0 color-mix(in srgb, var(--on-emerald) 18%, transparent) inset, 0 6px 20px var(--glow);
}
.btn-primary:hover { filter: brightness(1.06); }
.btn-primary:active { transform: scale(0.984); box-shadow: 0 1px 0 color-mix(in srgb, var(--on-emerald) 12%, transparent) inset; }
.btn-primary[disabled] { opacity: 0.55; cursor: default; filter: none; transform: none; }

.btn-quiet {
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  min-height: 52px;
  padding: 14px 20px;
  border-radius: var(--radius-control);
  cursor: pointer;
  transition: background-color 150ms ease, transform 120ms var(--ease-out);
}
.btn-quiet:hover { background: color-mix(in srgb, var(--emerald-bright) 12%, transparent); }
.btn-quiet:active { transform: scale(0.984); }

.actions-secondary { display: flex; gap: 10px; }

.btn-ghost {
  flex: 1;
  border: 1px solid var(--hairline);
  background: var(--surface-1);
  color: var(--text-soft);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  min-height: 46px;
  padding: 11px 14px;
  border-radius: var(--radius-control);
  cursor: pointer;
  transition: border-color 150ms ease, color 150ms ease, background-color 150ms ease, transform 120ms var(--ease-out);
}
.btn-ghost:hover { border-color: var(--hairline-strong); color: var(--text); }
.btn-ghost:active { transform: scale(0.984); }
.btn-ghost.is-done { border-color: var(--accent); color: var(--accent); }


@media (prefers-reduced-motion: reduce) {
  .studio-body *, .studio-body *::before, .studio-body *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
