/* Hand-rolled CSS. Pro blue / neutral palette, generous whitespace, modular
   tool cards. Light + dark themes via `data-theme` on <html>.
   The dark colour ramp keeps the same hue family (cool blue + slate) for
   a coherent "design tool" feel. */

:root, [data-theme="light"] {
  /* Light mode — cool grey aesthetic. Page is intentionally NOT white;
     a slightly muted slate tone makes the brand-blue accents read
     cleaner and gives the dashboard a calmer "design tool" mood. The
     grey is tuned cool (slight blue cast) to match the brand palette. */
  --blue:        #1d4ed8;
  --blue-700:    #1e40af;
  --blue-50:     #e2e8f0;
  --blue-glow:   rgba(29, 78, 216, 0.18);
  --ink:         #1c2230;
  --ink-2:       #475061;
  --muted:       #6a7385;
  --bg:          #e7eaef;
  --bg-2:        #dde1e7;
  --bg-3:        #d0d5dd;
  --line:        #bcc3ce;
  --line-strong: #98a2b2;
  --danger:      #dc2626;
  --ok:          #16a34a;
  --warn:        #d97706;
  --topnav-bg:   rgba(231,234,239,0.85);
}

[data-theme="dark"] {
  --blue:        #60a5fa;
  --blue-700:    #3b82f6;
  --blue-50:     #1e293b;
  --blue-glow:   rgba(96, 165, 250, 0.25);
  --ink:         #e2e8f0;
  --ink-2:       #cbd5e1;
  --muted:       #94a3b8;
  --bg:          #0b1020;
  --bg-2:        #111827;
  --bg-3:        #1e293b;
  --line:        #1f2937;
  --line-strong: #334155;
  --danger:      #f87171;
  --ok:          #4ade80;
  --warn:        #fbbf24;
  --topnav-bg:   rgba(11,16,32,0.78);
}

:root {
  --radius-sm:   8px;
  --radius:      14px;
  --radius-lg:   20px;
}

* { box-sizing: border-box; }
html, body { padding: 0; margin: 0; }
html {
  background: var(--bg);
  /* Don't let iOS bump font sizes after orientation change. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Avoid horizontal scroll from any decoration that bleeds (e.g. .hero::before).
     IMPORTANT: this used to live on `body`. CSS computes
     `overflow-x: hidden; overflow-y: visible` as `overflow: hidden auto`,
     which silently turned <body> into its own scroll container — and that
     in turn meant scroll events fired on <body> instead of <window>, so
     `window.addEventListener('scroll', …)` never fired. The hero parallax
     in app.js stopped working as a result. Hoisting to <html> keeps the
     same visual guard but lets the window be the canonical scroll
     target again. */
  overflow-x: hidden;
}
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  color: var(--ink); background: var(--bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Cuts the 300ms tap delay on older mobile browsers, kills double-tap zoom. */
  touch-action: manipulation;
  transition: background 200ms, color 200ms;
}
button, input, select, textarea { font-family: inherit; }
/* iOS auto-zooms when an input has font-size <16px on focus. Belt-and-suspenders since we already disable zoom. */
input, select, textarea { font-size: 16px; }
img { max-width: 100%; }
h1, h2, h3 { letter-spacing: -0.02em; line-height: 1.15; margin: 0 0 0.4em; }
h1 { font-size: clamp(1.7rem, 4.4vw, 3rem); font-weight: 800; }
h2 { font-size: clamp(1.25rem, 2.6vw, 1.7rem); font-weight: 700; }
h3 { font-size: clamp(1rem, 1.6vw, 1.15rem); font-weight: 700; }
p  { margin: 0 0 1em; color: var(--ink-2); }
.muted       { color: var(--muted); }
.muted.small { font-size: 0.9rem; }
a            { color: var(--blue); text-decoration: none; }
a:hover      { text-decoration: underline; }
code         { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.95em; }

/* ---------- top nav ---------- */
.topnav {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 16px;
  padding: 14px 32px calc(14px) 32px;
  /* Honor the iOS notch — nudge content out from under the status bar. */
  padding-top: calc(14px + env(safe-area-inset-top));
  padding-left:  calc(32px + env(safe-area-inset-left));
  padding-right: calc(32px + env(safe-area-inset-right));
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--topnav-bg); backdrop-filter: blur(12px);
  z-index: 10;
}
/* Brand mark + wordmark — Steam-dashboard style: thin sans-serif wordmark,
   small geometric SVG mark in brand-blue. The mark rotates 45° on hover
   so the diamond shape reads as a quiet interactive cue. No bold weight,
   no italic serifs — just a clean lowercase wordmark with a subtle
   .space accent. */
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-weight: 300;
  font-size: 1.18rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-transform: lowercase;
  transition: color 160ms ease;
}
.brand:hover { text-decoration: none; color: var(--blue); }
.brand-mark {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px;
  color: var(--blue);
  transition: transform 240ms ease, color 200ms ease;
}
.brand-mark svg { display: block; width: 100%; height: 100%; }
.brand:hover .brand-mark { transform: rotate(45deg); }
.brand-text { display: inline-flex; align-items: baseline; }
.brand-tld {
  color: var(--blue);
  font-weight: 400;
  font-style: normal;
  font-family: inherit;
  letter-spacing: 0.02em;
}

.topnav-links {
  display: flex; gap: 28px; justify-content: center;
}
.topnav-links a { color: var(--ink-2); font-weight: 500; }
.topnav-links a.active { color: var(--blue); }
.topnav-links a:hover  { color: var(--ink); text-decoration: none; }

.topnav-utils { display: flex; align-items: center; gap: 12px; }

.lang-switcher { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; padding: 2px; gap: 0; background: var(--bg-2); }
.lang-btn {
  background: none; border: none; color: var(--muted); font-weight: 600;
  font-size: 0.78rem; padding: 4px 9px; border-radius: 999px; cursor: pointer; letter-spacing: 0.04em;
}
.lang-btn.active { background: var(--bg); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,0.04); }

.icon-btn {
  background: none; border: 1px solid var(--line); color: var(--ink-2);
  width: 32px; height: 32px; border-radius: 999px; cursor: pointer;
  display: inline-grid; place-items: center; font-size: 14px;
}
.icon-btn:hover { border-color: var(--ink-2); color: var(--ink); }
.theme-icon-light { display: inline; }
.theme-icon-dark  { display: none; }
[data-theme="dark"] .theme-icon-light { display: none; }
[data-theme="dark"] .theme-icon-dark  { display: inline; }

/* Balance pill — small token icon + number, vertically centred. Also
   a link to /pricing so the user can top up directly from the topnav.
   Replaces the old `{n} ⊙` text glyph which rendered at wildly
   different sizes across system fonts (some fonts mapped ⊙ to a
   comically-large circle). inline-flex + line-height:1 + tabular-nums
   keeps the pill tight and the number perfectly centred regardless of
   how many digits. */
.balance {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px 4px 7px;
  background: var(--blue-50);
  color: var(--blue);
  border-radius: 999px;
  font-size: 0.84rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}
.balance:hover, .balance:focus-visible {
  background: color-mix(in srgb, var(--blue) 16%, var(--blue-50));
  border-color: color-mix(in srgb, var(--blue) 40%, transparent);
  color: var(--blue);
  text-decoration: none;
}
.balance-coin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px; height: 14px;
  flex-shrink: 0;
}
.balance-coin svg { display: block; width: 100%; height: 100%; }
.balance-num { line-height: 1; font-variant-numeric: tabular-nums; }
.btn-link {
  background: none; border: none; color: var(--ink-2); cursor: pointer;
  font-size: 0.95rem; padding: 0; font-weight: 500;
}
.btn-link:hover { color: var(--ink); text-decoration: none; }
.inline-form { display: inline; }

/* ---------- main / footer ---------- */
main {
  max-width: 1180px; margin: 0 auto;
  padding: 40px 32px 64px;
  padding-left:  calc(32px + env(safe-area-inset-left));
  padding-right: calc(32px + env(safe-area-inset-right));
}
footer {
  border-top: 1px solid var(--line); padding: 20px 32px; color: var(--muted); font-size: 0.85rem; text-align: center;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
}

/* ---------- buttons ---------- */
.btn-primary {
  display: inline-block; background: var(--blue); color: #fff; border: none; border-radius: 999px;
  padding: 9px 18px; font-weight: 600; cursor: pointer; font-size: 0.95rem; text-decoration: none;
  transition: background 120ms, transform 120ms, box-shadow 120ms;
}
.btn-primary:hover { background: var(--blue-700); text-decoration: none; transform: translateY(-1px); box-shadow: 0 8px 20px var(--blue-glow); }
.btn-primary:disabled { background: var(--line); color: var(--muted); cursor: not-allowed; box-shadow: none; transform: none; }
.btn-primary.big { padding: 14px 26px; font-size: 1rem; border-radius: 12px; }

/* CTA pill in the topnav — managed arrow + hover nudge so the button looks
   the same on every viewport. The inline "→" in the JSX is hidden because
   the ::after handles it. */
.btn-cta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; font-weight: 700; font-size: 0.92rem;
  letter-spacing: 0.005em;
  white-space: nowrap;
  box-shadow: 0 4px 14px var(--blue-glow);
}
.btn-cta::after {
  content: '→';
  font-size: 1em; line-height: 1;
  transition: transform 140ms ease;
}
.btn-cta:hover::after { transform: translateX(3px); }
.btn-cta .cta-arrow { display: none; }       /* hide the inline arrow in the markup, ::after wins */
.btn-secondary {
  display: inline-block; background: var(--bg); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 8px 14px; font-weight: 500; cursor: pointer; text-decoration: none;
}
.btn-secondary:hover { border-color: var(--line-strong); text-decoration: none; }

/* ---------- hero ---------- */
.hero {
  display: grid; grid-template-columns: 1fr;
  gap: 36px;
  text-align: center;
  padding-top: 8px;
  position: relative;
}
.hero::before {
  content: ''; position: absolute; inset: -40px 0 0 0; z-index: -1;
  background:
    radial-gradient(60% 60% at 50% 0%, var(--blue-glow), transparent 70%),
    repeating-linear-gradient(0deg, transparent, transparent 80px, var(--line) 80px, var(--line) 81px),
    repeating-linear-gradient(90deg, transparent, transparent 80px, var(--line) 80px, var(--line) 81px);
  opacity: 0.45; pointer-events: none;
  /* Backdrop grid moves DOWN as the page scrolls UP — opposite-direction
     parallax that reads as "behind" the foreground layers. Fastest
     drift of any layer so it really feels deep. */
  transform: translate3d(0, calc(var(--scroll-y, 0) * 0.5px), 0);
  will-change: transform;
}
/* Suno-style multi-axis parallax — three things happen as the user
   scrolls down through the hero:
     1. Text TRANSLATES UP faster than the page does (negative drift),
        which makes it feel like the camera is pulling away from the
        title.
     2. Text SCALES DOWN slightly (zooms out) — gives the depth-fade
        feel where the hero "recedes" instead of just sliding offscreen.
     3. Text FADES OUT smoothly so by the time you've scrolled past it
        the title is fully gone and the next section reads cleanly.
   The hero figure rides along at half-rates so the two layers separate
   visually as you scroll. Origin is `center top` so the scale-down
   pulls the title up + in, not towards the centre of its box. */
.hero-text {
  transform-origin: center top;
  transform:
    translate3d(0, calc(var(--scroll-y, 0) * -0.35px), 0)
    scale(calc(1 - var(--scroll-y, 0) * 0.00028));
  opacity: calc(1 - var(--scroll-y, 0) * 0.0018);
  will-change: transform, opacity;
}
.hero-figure {
  transform-origin: center top;
  transform:
    translate3d(0, calc(var(--scroll-y, 0) * -0.15px), 0)
    scale(calc(1 - var(--scroll-y, 0) * 0.00015));
  opacity: calc(1 - var(--scroll-y, 0) * 0.0012);
  will-change: transform, opacity;
}
/* Honour reduced-motion: no parallax for users who asked the OS to
   tone things down. */
@media (prefers-reduced-motion: reduce) {
  .hero::before, .hero-text, .hero-figure { transform: none; opacity: 1; }
}

/* ---------- section reveal parallax ----------
   Each major section below the hero (tutorial demos, create gallery,
   tools strip) gets a Suno-style "lift-in" reveal when it crosses
   into the viewport: starts 36px below its final position, mostly
   invisible, slightly blurred — settles to identity smoothly. Driven
   by an IntersectionObserver in public/app.js which adds .is-visible
   the first time at least 5% of the section is on screen.
   Inside .tools-strip, individual .tool-card children stagger in
   with cascading 60ms delays so the grid "deals" itself onto the
   page rather than popping all-at-once. */
.parallax-section {
  opacity: 0;
  transform: translate3d(0, 36px, 0);
  filter: blur(4px);
  /* `cubic-bezier(0.22, 1, 0.36, 1)` = ease-out-quint — fast start,
     slow settle. Same easing curve the hero uses on hover. */
  transition:
    opacity   780ms ease,
    transform 780ms cubic-bezier(0.22, 1, 0.36, 1),
    filter    520ms ease;
  will-change: opacity, transform, filter;
}
.parallax-section.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  filter: blur(0);
}

/* Tool-card stagger inside a parallax section. Each card lifts in
   slightly AFTER its parent section, with a 60ms cascade — feels
   like the cards "deal" onto the page rather than popping. */
.parallax-section .tool-card {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity   520ms ease,
    transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
.parallax-section.is-visible .tool-card {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
/* Cascade — nth-of-type works regardless of subgroup-head splits.
   Capped at 8 to avoid runaway delays on very long grids. */
.parallax-section.is-visible .tool-card:nth-of-type(1) { transition-delay:   0ms; }
.parallax-section.is-visible .tool-card:nth-of-type(2) { transition-delay:  60ms; }
.parallax-section.is-visible .tool-card:nth-of-type(3) { transition-delay: 120ms; }
.parallax-section.is-visible .tool-card:nth-of-type(4) { transition-delay: 180ms; }
.parallax-section.is-visible .tool-card:nth-of-type(5) { transition-delay: 240ms; }
.parallax-section.is-visible .tool-card:nth-of-type(6) { transition-delay: 300ms; }
.parallax-section.is-visible .tool-card:nth-of-type(7) { transition-delay: 340ms; }
.parallax-section.is-visible .tool-card:nth-of-type(8) { transition-delay: 380ms; }

/* Same reduced-motion bail-out. No transitions, all elements visible
   on first paint. */
@media (prefers-reduced-motion: reduce) {
  .parallax-section,
  .parallax-section .tool-card {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
}
.hero-eyebrow { color: var(--muted); font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase; }
/* h1 is the focal element on the landing page — sized to dominate
   the first viewport. Rotator phrases now wrap to 2 lines when they
   need to (see .hero-rotator-line below), so the longest phrase no
   longer caps the font-size; we're free to push the type as large as
   the layout can absorb.
   `line-height: 1.15` matches the rotator's line height so the visual
   gap between the rotator and "AI rendered." is purely controlled by
   the explicit `.hero-h1-b` margin, not by inherited line-height slack. */
.hero h1 {
  font-size: clamp(1.4rem, 6vw, 5rem);
  margin: 0.18em auto 0;
  padding: 0 12px;
  line-height: 1.15;
  letter-spacing: -0.025em;
}
.hero-h1-a { color: var(--blue); font-style: italic; font-family: 'Georgia', 'Times New Roman', serif; font-weight: 700; }
.hero-h1-b {
  color: var(--ink);
  display: block;        /* stack as a sibling block below the rotator */
  margin-top: 0.28em;    /* MATCHES h1.margin-top so all three gaps look even */
}

/* Hero rotator — vertical slide through 4 phrases, looping seamlessly via a
   duplicated first line at the end of the track. Translate is in `em` so the
   keyframe math scales with the h1's font-size.
   - block-level so the rotator inherits the h1's full inline width
     (otherwise inline-block shrinks to content and long phrases overflow).
   - vertical clip on the rotator (`overflow: hidden` + height: 2.3em).
   - phrases ARE allowed to wrap to 2 lines (e.g. "Architecture & Interior,"
     at a hero-sized font on a phone). Each phrase block is a fixed 2.3em
     tall regardless of how many lines its content takes, so the animation
     translates by 2.3em per step and short phrases sit centred in their
     block instead of jumping. Without this, the longest phrase capped the
     whole h1 size — which made the hero look small on portrait. */
.hero-rotator {
  display: block;
  overflow: hidden;
  height: 2.3em;              /* two lines tall — biggest phrase wraps cleanly */
  max-width: 100%;
}
.hero-rotator-track {
  display: block;
  animation: hero-rotate 16s cubic-bezier(0.45, 0.05, 0.25, 1) infinite;
  will-change: transform;
}
.hero-rotator-line {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 2.3em;
  line-height: 1.15;
  /* Wrap allowed — phrases auto-break at word boundaries when they
     don't fit on one line. Single-line phrases sit visually centred
     (flex align-items: center). */
  white-space: normal;
  overflow: hidden;
  word-spacing: 0.02em;
}
@keyframes hero-rotate {
  /* hold first phrase */     0%,   18.75% { transform: translateY(0); }
  /* hold second */          25%,  43.75% { transform: translateY(-2.30em); }
  /* hold third */           50%,  68.75% { transform: translateY(-4.60em); }
  /* hold fourth */          75%,  93.75% { transform: translateY(-6.90em); }
  /* slide → duplicate first (seamless loop point) */
                              100%         { transform: translateY(-9.20em); }
}

/* Respect a user's reduced-motion preference — show just the first phrase. */
@media (prefers-reduced-motion: reduce) {
  .hero-rotator-track { animation: none; transform: translateY(0); }
}

/* Mobile portrait (≤ 600 px). The Suno-style first impression demands
   a hero that dominates the visible viewport. With the rotator now
   allowed to wrap to 2 lines, we can push the font-size much higher
   than before — the longest phrase ("Architecture & Interior,")
   simply wraps cleanly across 2 lines instead of forcing the whole
   h1 down to a font-size that fits it on 1 line.
   ~11vw on a 390 px iPhone = 43 px = 2.7 rem; rotator-block (2.3em)
   = ~99 px; "AI rendered." (single line) ≈ 50 px. Total h1 occupies
   ~150 px which, combined with the eyebrow + subhead + CTA, fills
   the visible portrait viewport without scrolling. */
@media (max-width: 600px) {
  main {
    padding: 24px 16px 56px;
    padding-left:  calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
  .hero { padding-top: 4px; gap: 18px; }
  .hero-eyebrow { font-size: 0.92rem; letter-spacing: 0.08em; }
  .hero h1 { font-size: clamp(2.4rem, 11vw, 4.4rem); padding: 0 4px; }
  .hero-rotator { max-width: 100%; }
  .hero-subhead { font-size: 1rem; max-width: 38ch; margin: 14px auto 16px; }
}
/* Ultra-narrow (≤ 360 px, e.g. iPhone SE / older Android compact). */
@media (max-width: 360px) {
  main {
    padding: 22px 12px 56px;
    padding-left:  calc(12px + env(safe-area-inset-left));
    padding-right: calc(12px + env(safe-area-inset-right));
  }
  .hero h1 { font-size: clamp(2rem, 10.5vw, 3.2rem); padding: 0 4px; }
}
/* Tablet portrait (601–900 px). Default desktop clamp peaks at ~2.5 rem
   for an iPad portrait (768 px viewport), which left the rotator
   looking small relative to the available vertical real estate. Bump
   the ceiling so the rotator + "AI rendered." dominate the hero on
   that aspect ratio. (Landscape tablets already use the default 6vw
   rule, which renders fine — no override needed.) */
@media (min-width: 601px) and (max-width: 900px) {
  .hero { padding-top: 12px; gap: 28px; }
  .hero-eyebrow { font-size: 1.05rem; letter-spacing: 0.1em; }
  .hero h1 { font-size: clamp(3.4rem, 8.5vw, 5.4rem); padding: 0 10px; }
  .hero-subhead { font-size: 1.12rem; max-width: 50ch; margin: 20px auto 24px; }
}
.hero-subhead { font-size: clamp(0.95rem, 1.6vw, 1.05rem); color: var(--ink-2); max-width: 60ch; margin: 14px auto 20px; }
/* Multi-language chip — small pill under the subhead. Pulls the user's
   eye with a globe glyph + brand-blue accent border so a non-English
   speaker knows they don't have to write prompts in English. */
.hero-multilang {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 auto 18px;
  padding: 8px 16px;
  font-size: 0.88rem;
  color: var(--ink-2);
  background: color-mix(in srgb, var(--blue) 10%, var(--bg-2));
  border: 1px solid color-mix(in srgb, var(--blue) 32%, transparent);
  border-radius: 999px;
  max-width: 56ch;
  line-height: 1.5;
  text-align: left;
}
.hero-multilang-globe {
  font-size: 1.05rem;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 2px color-mix(in srgb, var(--blue) 40%, transparent));
}
@media (max-width: 600px) {
  .hero-multilang { font-size: 0.84rem; padding: 7px 13px; gap: 6px; }
}
.hero-cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.trust { color: var(--muted); font-size: 0.82rem; margin-top: 14px; }
.trust::before { color: #f59e0b; }

.hero-figure { margin: 28px auto 0; max-width: 980px; }
.hero-figure figcaption { text-align: center; margin-top: 10px; }

/* ---------- before/after slider ---------- */
.ba-slider {
  --ba-pos: 50%;
  position: relative;
  width: 100%; aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg-2);
  user-select: none; touch-action: none;
}
.ba-slider img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.ba-after  { position: absolute; inset: 0; }
.ba-clip   { position: absolute; inset: 0; overflow: hidden; clip-path: inset(0 calc(100% - var(--ba-pos)) 0 0); }
.ba-handle {
  position: absolute; top: 0; bottom: 0; left: var(--ba-pos);
  width: 2px; background: rgba(255,255,255,0.95);
  transform: translateX(-50%);
  cursor: ew-resize; z-index: 2;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.15), 0 8px 16px rgba(0,0,0,0.15);
}
.ba-knob {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 40px; height: 40px; border-radius: 50%;
  background: #fff; color: var(--blue); display: grid; place-items: center;
  font-size: 14px; font-weight: 700;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.05);
}
.ba-handle:focus-visible { outline: none; }
.ba-handle:focus-visible .ba-knob { outline: 3px solid var(--blue); }
.ba-label {
  position: absolute; top: 12px; padding: 4px 10px;
  background: rgba(0,0,0,0.65); color: #fff; font-size: 0.75rem; font-weight: 600;
  border-radius: 999px; letter-spacing: 0.04em;
}
.ba-label-before { left: 12px; }
.ba-label-after  { right: 12px; }
.drag-hint { text-align: center; margin-top: 8px; }

/* ---------- tutorial (before/after gallery from real renders) ---------- */
.tutorial { margin-top: clamp(56px, 9vw, 96px); }
.tutorial-head { text-align: center; max-width: 56ch; margin: 0 auto clamp(20px, 3vw, 36px); }
.tutorial-head h2 { margin-bottom: 6px; }
.tutorial-grid {
  display: grid; gap: clamp(14px, 2vw, 22px);
  grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 720px) { .tutorial-grid { grid-template-columns: 1fr; } }

.tutorial-card {
  display: flex; flex-direction: column; gap: 12px;
  margin: 0;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg);
  padding: 14px;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.1s;
}
.tutorial-card:hover { border-color: var(--blue); box-shadow: 0 10px 28px var(--blue-glow); }
.tutorial-card .ba-slider {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
}
.tutorial-cap { display: flex; flex-direction: column; gap: 8px; padding: 2px 4px 4px; }
.tutorial-cap p { margin: 0; color: var(--ink); font-style: italic; font-size: 0.95rem; line-height: 1.45; }
.tutorial-tag {
  align-self: flex-start;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px;
}
.tag-object_render { background: color-mix(in srgb, var(--blue) 12%, transparent); color: var(--blue); }
.tag-full_render   { background: color-mix(in srgb, var(--ok,   #16a34a) 14%, transparent); color: var(--ok, #16a34a); }

/* ---------- Create-Concept gallery (interactive carousel) ----------
   Horizontal strip of cards. User scrolls manually with: mouse wheel
   (sideways), trackpad swipe, prev/next buttons, click-and-drag, or
   keyboard arrows. Clicking a card "focuses" it — the card scales up
   to ~1.12× with a spring transition and centers itself.                */
.create-gallery { margin-top: clamp(56px, 9vw, 96px); }
.create-gallery-head { text-align: center; max-width: 56ch; margin: 0 auto clamp(20px, 3vw, 36px); }
.create-gallery-head h2 { margin-bottom: 6px; }

/* The viewport is the positioning context for the prev/next nav buttons
   and holds the soft mask that fades the cards toward the edges. The
   track inside scrolls horizontally; the viewport itself does not. */
.create-gallery-viewport {
  position: relative;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent);
}

/* The track is the actual scrollable strip. scroll-snap-type proximity
   gives a gentle "land on a card" feel without trapping the user mid-scroll.
   `padding` reserves room above/below so the focused-card scale-up doesn't
   clip against the section boundary. */
.create-gallery-track {
  display: flex; gap: 16px;
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  padding: 28px 8px 44px;
  cursor: grab;
  user-select: none;
}
.create-gallery-track::-webkit-scrollbar { display: none; }
/* While the user is dragging the track, disable smooth-scroll so the cards
   track the cursor 1:1 instead of trailing behind. */
.create-gallery-track.is-dragging { cursor: grabbing; scroll-behavior: auto; }
.create-gallery-track:focus { outline: none; }

.create-gallery-card {
  flex: 0 0 280px;
  scroll-snap-align: center;
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-1);
  cursor: pointer;
  position: relative;
  /* Spring-y transition with a tiny overshoot — the cubic-bezier(.2,.7,.3,1.2)
     `>1` final ordinate produces a subtle pop on focus. */
  transition: transform 280ms cubic-bezier(.2,.7,.3,1.2),
              box-shadow 200ms ease,
              border-color 200ms ease,
              opacity 200ms ease;
}
.create-gallery-card:hover { border-color: var(--blue); box-shadow: 0 8px 22px var(--blue-glow); }

/* Focused card — pops above its siblings, slightly lifted, blue glow. We
   raise z-index so the scaled card paints over its neighbours, and dim the
   unfocused cards slightly so the focus reads at a glance. */
.create-gallery-card.is-focused {
  transform: translateY(-6px) scale(1.12);
  z-index: 10;
  border-color: var(--blue);
  box-shadow: 0 18px 44px var(--blue-glow);
}
.create-gallery-track:has(.is-focused) .create-gallery-card:not(.is-focused) {
  opacity: 0.55;
}
.create-gallery-card:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

.create-gallery-card img {
  display: block; width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--bg-2);
  pointer-events: none;             /* clicks pass through to the figure */
}
.create-gallery-card figcaption {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px;
}
.create-gallery-card figcaption p {
  margin: 0; color: var(--ink); font-style: italic;
  font-size: 0.82rem; line-height: 1.4;
  /* Clamp to 3 lines so cards stay equal height even on long prompts. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* Prev/next nav buttons — circular pills floating over the viewport edges.
   They sit ABOVE the mask fade so they don't disappear into the fadeout. */
.create-gallery-nav {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 1.4rem; line-height: 1;
  display: grid; place-items: center;
  cursor: pointer;
  z-index: 20;
  user-select: none;
  transition: transform 140ms ease, background 140ms ease, color 140ms ease, opacity 200ms ease;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
}
.create-gallery-nav:hover {
  transform: translateY(-50%) scale(1.08);
  background: var(--blue);
  color: #fff;
  border-color: var(--blue);
}
.create-gallery-nav:active { transform: translateY(-50%) scale(0.96); }
.create-gallery-nav[disabled] { opacity: 0; pointer-events: none; }
.create-gallery-nav-prev { left: 10px; }
.create-gallery-nav-next { right: 10px; }

/* Category-coloured chips (kept harmonic with the existing tutorial-tag pair) */
.tag-create-photo { background: color-mix(in srgb, var(--blue) 12%, transparent);          color: var(--blue); }
.tag-create-arch  { background: color-mix(in srgb, var(--ok, #16a34a) 14%, transparent);   color: var(--ok, #16a34a); }
.tag-create-anime { background: color-mix(in srgb, #c026d3 14%, transparent);              color: #c026d3; }
.tag-create-3d    { background: color-mix(in srgb, #ea580c 14%, transparent);              color: #ea580c; }
.tag-create-game  { background: color-mix(in srgb, #0891b2 14%, transparent);              color: #0891b2; }

/* Respect reduced-motion preference — kill the spring overshoot. */
@media (prefers-reduced-motion: reduce) {
  .create-gallery-card { transition: border-color 120ms, box-shadow 120ms, opacity 120ms; }
  .create-gallery-card.is-focused { transform: none; }
  .create-gallery-track { scroll-behavior: auto; }
}

@media (max-width: 720px) {
  .create-gallery-card { flex-basis: 230px; }
  .create-gallery-card.is-focused { transform: translateY(-4px) scale(1.08); }
  .create-gallery-nav { width: 36px; height: 36px; font-size: 1.2rem; }
}

/* ---------- tool cards ---------- */
.tools-strip { margin-top: clamp(48px, 8vw, 88px); text-align: center; }
.tools-strip h2 { margin-bottom: clamp(8px, 1vw, 16px); }

/* Sub-group header for the two-tier layout
   (Architecture & Interior Rendering vs Content Creation & Marketplace). */
.tools-group-head {
  text-align: center;
  margin: clamp(28px, 4vw, 48px) auto clamp(12px, 1.5vw, 20px);
  max-width: 60ch;
}
.tools-group-title {
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 4px;
  position: relative;
  padding-bottom: 10px;
}
/* Small accent rule under the group title — keeps the tiers visually distinct. */
.tools-group-title::after {
  content: '';
  display: block;
  width: 36px; height: 2px;
  background: var(--blue);
  border-radius: 2px;
  margin: 8px auto 0;
}
.tools-group-lede { margin: 0; }

.tool-cards, .tool-grid {
  display: grid; gap: 18px; grid-template-columns: repeat(3, 1fr); margin-top: 8px;
  text-align: left;
}
.tool-grid { grid-template-columns: repeat(2, 1fr); }
/* ----------------------------------------------------------------------
   Studio tool cards — Steam-library style
   ----------------------------------------------------------------------
   Layout: the example image fills the entire card as a low-opacity
   background (~35%); title, lede, and cost overlay on top with full
   contrast. On hover the image brightens to ~55% (the card "comes
   alive"), the card lifts, and a brand-blue glow takes over the border.
   Text stays anchored — no movement, no scale on the copy — only the
   visual layer reacts. Same shape as Steam's library cards.
   Image is intentionally NOT alpha-cut; we want a full atmospheric
   thumbnail to set the visual tone for each tool.
   ---------------------------------------------------------------------- */
.tool-card {
  position: relative;
  display: block;
  min-height: 220px;
  padding: 20px 22px 22px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: inherit;
  overflow: hidden;
  transition: transform 180ms ease, box-shadow 220ms ease, border-color 220ms ease;
  isolation: isolate;
}
.tool-card.link:hover,
.tool-card.link:focus-visible {
  border-color: var(--blue);
  text-decoration: none;
  transform: translateY(-3px) scale(1.01);
  box-shadow: 0 18px 38px var(--blue-glow);
}

/* Background image — fills the whole card and sits BEHIND the text. We
   render it as a real <img> so the browser can lazy-load it; the
   absolute positioning + z-index:0 puts it under the text but above
   the card background colour. opacity:0.35 is the "dimmed" state the
   user asked for — image visible but not competing with the copy. */
.tool-card-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Default crop anchor — `center top` instead of `center center` so
     portrait subjects (people / anime characters / object renders
     where the focal point sits in the upper half of the frame) keep
     their faces / subjects visible after object-fit: cover crops the
     edges. Centre-cropping a 720×1280 portrait into a wider card
     hides the top third — the face — and shows the torso instead. */
  object-position: center top;
  opacity: 0.35;
  transition: opacity 280ms ease, transform 600ms ease, filter 280ms ease;
  z-index: 0;
  pointer-events: none;
  /* No filter at rest — soft natural look; hover bumps brightness. */
}
/* Per-feature crop overrides. For the anime card specifically the
   character's face sits a touch lower than `center top` would
   reveal, so we pull the viewing window down to ~15% to centre on
   the face + bangs. Same idea for the human-portrait cards if their
   default centering ever cuts the face. */
.tool-card[data-feature="background_swap_anime"] .tool-card-thumb { object-position: center 15%; }
.tool-card[data-feature="hair_edit"]             .tool-card-thumb { object-position: center 20%; }
.tool-card[data-feature="try_on"]                .tool-card-thumb { object-position: center 20%; }
.tool-card[data-feature="refine_subject"]        .tool-card-thumb { object-position: center 18%; }
.tool-card[data-feature="background_swap"]       .tool-card-thumb { object-position: center 22%; }
.tool-card.link:hover .tool-card-thumb,
.tool-card.link:focus-visible .tool-card-thumb {
  opacity: 0.55;
  transform: scale(1.04);
  filter: brightness(1.05) saturate(1.05);
}

/* Soft gradient veil sitting between the image and the text — keeps
   copy legible regardless of what's in the image. Slightly darker at
   the bottom so the lede line reads cleanly. The veil is a pseudo-
   element so it doesn't add another node to the DOM. */
.tool-card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--bg-2) 35%, transparent) 0%,
    color-mix(in srgb, var(--bg-2) 55%, transparent) 60%,
    color-mix(in srgb, var(--bg-2) 80%, transparent) 100%);
  transition: opacity 280ms ease;
}
.tool-card.link:hover::before,
.tool-card.link:focus-visible::before {
  opacity: 0.7;
}

/* Body text panel — overlays the image. Sits flush with the card
   padding and ALL its children rest on z-index:2 so they read on top
   of the gradient veil and the dimmed image. */
.tool-card-body {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Push the body towards the bottom so the image's focal area
     stays uncovered above. Auto-margin-top fills any remaining
     space when min-height is taller than the body's natural size. */
  margin-top: auto;
  padding-top: 80px;          /* reserves visual breathing room above text */
}
.tool-card h3 {
  display: flex; align-items: baseline; gap: 6px;
  margin: 0;
  font-size: 1.04rem;
  font-weight: 700;
  color: var(--ink);
  /* Subtle shadow so the title reads even when the underlying image
     happens to be a similar tone. Two layers = a soft halo, not a
     hard text-shadow look. */
  text-shadow:
    0 1px 2px color-mix(in srgb, var(--bg) 85%, transparent),
    0 2px 6px color-mix(in srgb, var(--bg) 60%, transparent);
}
.tool-card h3 span { color: var(--blue); font-weight: 800; font-size: 0.78rem; }
.tool-card p {
  margin: 0;
  color: var(--ink-2);
  font-size: 0.9rem;
  line-height: 1.4;
  /* Clamp to 2 lines so cards line up evenly in the grid. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Halo for the lede line too — softer than the title's. */
  text-shadow: 0 1px 2px color-mix(in srgb, var(--bg) 80%, transparent);
}

/* Make .tool-card behave as a flex column so the auto-margin-top on
   the body actually pushes it down (block elements wouldn't honour the
   auto). Image + ::before are absolutely positioned, so they don't
   participate in the flex layout. */
.tool-card { display: flex; flex-direction: column; }

/* Floating chips in the top-right (cost + optional BETA badge). Backdrop
   blur so they stay legible over the image. */
.tool-card-chips {
  position: absolute;
  top: 12px;
  right: 12px;
  display: inline-flex;
  gap: 6px;
  z-index: 3;
  pointer-events: none;
}
.tool-card-chips .cost {
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.8rem;
  font-weight: 700;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  letter-spacing: 0.01em;
}
.tool-card.link:hover .tool-card-chips .cost,
.tool-card.link:focus-visible .tool-card-chips .cost {
  border-color: color-mix(in srgb, var(--blue) 60%, transparent);
  color: var(--blue);
}
.tool-card-chips .beta-badge {
  background: color-mix(in srgb, var(--blue) 85%, transparent);
  color: white;
  border-radius: 999px;
  padding: 4px 9px;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* Disabled state — used for:
     - the studio "locked" card while a render is in-flight
     - the landing-page "more tools coming soon" placeholder
   Both want a simple block layout (no image area, no margin-auto-push,
   no gradient veil) so the text reads cleanly on the flat card. */
.tool-card.disabled,
.tool-card.disabled-locked {
  display: block;
  padding: 22px;
  min-height: 160px;
  opacity: 0.55;
  pointer-events: none;
  cursor: not-allowed;
}
.tool-card.disabled-locked { opacity: 1; }   /* locked card stays full-opacity — it's a state, not a disabled link */
.tool-card.disabled-locked h3 { font-size: 1.05rem; }
.tool-card.disabled-locked p  { -webkit-line-clamp: unset; }
.tool-card.disabled .tool-card-body,
.tool-card.disabled-locked .tool-card-body { padding-top: 0; margin-top: 0; }
/* Drop the dimming gradient + text-shadow halo on disabled cards
   (no image underneath = the visual aids only get in the way). */
.tool-card.disabled::before,
.tool-card.disabled-locked::before { display: none; }
.tool-card.disabled h3, .tool-card.disabled p,
.tool-card.disabled-locked h3, .tool-card.disabled-locked p { text-shadow: none; }
/* Disabled "coming soon" cards in landing keep the cost chip in the
   corner — but without backdrop blur (no image to blur over). */
.tool-card.disabled .tool-card-chips .cost {
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* Create Concept lives in its own group and is the only card in that grid.
   On wide screens, capping its width keeps the layout balanced instead of
   stretching one card across 3 columns. */
.tool-card-create { max-width: 480px; }

/* Sub-sub-group header — used inside .tools-group (Content Creation &
   Marketplace) to split the cards into Outfit and Product subgroups.
   Smaller than .tools-group-head; left-aligned; a subtle accent line on
   the left edge separates it visually from the surrounding tool grids. */
.tools-subgroup-head {
  margin: clamp(20px, 3vw, 32px) 0 clamp(8px, 1.2vw, 14px);
  padding-left: 14px;
  border-left: 3px solid var(--blue);
  text-align: left;
  max-width: none;
}
.tools-subgroup-title {
  font-size: clamp(0.95rem, 1.4vw, 1.05rem);
  font-weight: 700;
  letter-spacing: 0.03em;
  margin: 0 0 2px;
  color: var(--ink);
}
.tools-subgroup-head p { margin: 0; }
/* Inside the collapsible studio group, the subgroup head sits inside the
   group's padding container — drop the outer margin so it aligns. */
.studio-group .tools-subgroup-head:first-child { margin-top: 0; }
.studio-group .tools-subgroup-head { margin-left: clamp(18px, 2.5vw, 26px); }

/* ---------- Studio collapsible groups ----------
   Each <details class="studio-group"> on /studio renders as a stack of
   collapsible sections. The summary is the existing .tools-group-head with
   a chevron added; clicking it toggles the inner .tool-grid. */
.studio-groups { display: flex; flex-direction: column; gap: 14px; }

.studio-group {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg);
  overflow: hidden;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.studio-group[open] { border-color: var(--blue); box-shadow: 0 8px 22px var(--blue-glow); }

.studio-group > summary.tools-group-head {
  /* Override the centered text variant used on the landing page — for the
     collapsible studio we want a clickable row with the chevron on the right. */
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  text-align: left;
  max-width: none;
  margin: 0;
  padding: clamp(16px, 2.5vw, 22px) clamp(18px, 2.5vw, 26px);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.studio-group > summary::-webkit-details-marker { display: none; }   /* hide default triangle in WebKit */
.studio-group > summary::marker { content: ''; }                      /* hide default marker in Firefox */
.studio-group > summary:hover .tools-group-title { color: var(--blue); }
.studio-group[open] > summary { border-bottom: 1px solid var(--line); }

/* Inside the collapsible the title's accent rule looks redundant; drop it. */
.studio-group .tools-group-title::after { display: none; }
.studio-group .tools-group-title { padding-bottom: 0; }

/* Chevron — points down when closed, up when open. */
.studio-group-chevron {
  flex-shrink: 0;
  font-size: 1.1rem;
  color: var(--ink-2);
  transition: transform 200ms ease;
  display: inline-block;
  transform: rotate(180deg);   /* default = points down ⌄ when collapsed */
}
.studio-group[open] > summary .studio-group-chevron {
  transform: rotate(0deg);     /* points up ⌃ when expanded */
  color: var(--blue);
}

/* Inner grid gets a comfortable padding instead of the page-level margin. */
.studio-group > .tool-grid {
  padding: 18px clamp(18px, 2.5vw, 26px) clamp(18px, 2.5vw, 26px);
  margin-top: 0;
}

/* ---------- Maintenance one-pager ----------
   Self-contained layout — no nav, no chrome. Centered card with a subtle
   gear icon, calm copy. Returned with HTTP 503. */
.maintenance-body {
  margin: 0;
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 24px;
  background: radial-gradient(120% 80% at 50% 0%, var(--blue-glow), transparent 70%), var(--bg);
}
.maintenance {
  width: 100%; max-width: 560px;
}
.maintenance-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 5vw, 48px);
  text-align: center;
  box-shadow: 0 18px 48px rgba(0,0,0,0.08);
}
.maintenance-icon {
  font-size: 3rem;
  line-height: 1;
  color: var(--blue);
  margin-bottom: 18px;
  display: inline-block;
  animation: maintenance-spin 9s linear infinite;
  transform-origin: 50% 50%;
}
@keyframes maintenance-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .maintenance-icon { animation: none; }
}
.maintenance-card h1 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 12px;
  color: var(--ink);
}
.maintenance-lede {
  color: var(--ink-2);
  margin: 0 0 16px;
  line-height: 1.55;
}
.maintenance-reason {
  text-align: left;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin: 16px 0 8px;
}
.maintenance-reason strong { display: block; margin-bottom: 4px; color: var(--ink); }
.maintenance-reason p      { margin: 0; }
.maintenance-foot {
  margin: 20px 0 4px;
}

/* ---------- auth ---------- */
.auth { display: grid; place-items: center; padding: 60px 0; }
.auth-card {
  width: 100%; max-width: 460px; padding: 36px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg);
  box-shadow: 0 12px 36px rgba(0,0,0,0.04);
}
.auth-card h1 { font-size: 1.8rem; }
.auth-form { display: grid; gap: 18px; margin-top: 16px; }
.auth-form label { display: grid; gap: 6px; font-size: 0.9rem; color: var(--ink-2); }
.auth-form input {
  font-size: 1rem; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  outline: none; background: var(--bg); color: var(--ink);
}
.auth-form input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-glow); }
.form-error { background: color-mix(in srgb, var(--danger) 10%, transparent); color: var(--danger); border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent); padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.9rem; }
.dev-banner { background: color-mix(in srgb, var(--warn) 10%, transparent); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 25%, transparent); padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.9rem; margin-bottom: 8px; }

/* OTP method picker (segmented control) */
.method-picker { border: 0; padding: 0; margin: 0; display: grid; gap: 6px; }
.method-picker legend { padding: 0; }
.method-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.method-chip {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 12px; font-size: 0.92rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  color: var(--ink-2); background: var(--bg);
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.method-chip:hover { border-color: var(--blue); color: var(--ink); }
.method-chip.is-active { border-color: var(--blue); color: var(--blue); background: color-mix(in srgb, var(--blue) 6%, transparent); }
.method-chip input { position: absolute; opacity: 0; pointer-events: none; }
.method-ico { font-size: 1rem; opacity: 0.85; }

/* "Continue with Google" button */
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 12px 14px; margin: 4px 0 0;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.1s;
}
.btn-google:hover { border-color: var(--blue); box-shadow: 0 6px 18px rgba(0,0,0,0.06); text-decoration: none; transform: translateY(-1px); }
.btn-google svg { display: block; }
.auth-or { display: flex; align-items: center; gap: 10px; margin: 14px 0 6px; color: var(--muted); font-size: 0.85rem; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Pricing CTA forms inherit btn-primary styling on the button child. */
.pricing-form { margin: 0; }

/* form notice (vs. error) */
.form-notice {
  background: color-mix(in srgb, var(--blue) 8%, transparent);
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--blue) 25%, transparent);
  padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.9rem;
}
.auth-foot { text-align: center; margin-top: 14px; }

/* topnav user chip */
.user-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 0.88rem; color: var(--ink); text-decoration: none; font-weight: 600;
  background: var(--bg); transition: border-color 0.15s, color 0.15s;
}
.user-chip:hover { border-color: var(--blue); color: var(--blue); text-decoration: none; }
.user-chip-name { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- profile ---------- */
.profile { max-width: 760px; margin: 40px auto; padding: 0 16px; }
.profile-head h1 { font-size: 1.7rem; margin-bottom: 4px; }
.profile-tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  border-bottom: 1px solid var(--line); margin: 24px 0 24px;
}
.profile-tabs a {
  padding: 10px 14px; font-weight: 600; font-size: 0.92rem; color: var(--ink-2);
  border-bottom: 2px solid transparent; text-decoration: none;
  transition: color 0.15s, border-color 0.15s;
}
.profile-tabs a:hover { color: var(--ink); }
.profile-tabs a.active { color: var(--blue); border-color: var(--blue); }
.profile-card {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg); padding: 28px; margin-bottom: 18px;
}
.profile-card h2 { font-size: 1.25rem; margin-bottom: 6px; }
.profile-card h3 { font-size: 1.05rem; margin-bottom: 8px; }

.profile-card select {
  font-size: 1rem; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); width: 100%;
}

.balance-pill {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 10px 16px; border: 1px solid var(--line); border-radius: 999px;
  background: color-mix(in srgb, var(--blue) 6%, transparent); margin: 6px 0 8px;
}
.balance-num { font-size: 1.6rem; font-weight: 700; color: var(--blue); }

.badge-verified, .badge-unverified {
  display: inline-block; margin-left: 10px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 0.78rem; font-weight: 600;
  vertical-align: middle;
}
.badge-verified {
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  color: var(--ok);
  border: 1px solid color-mix(in srgb, var(--ok) 32%, transparent);
}
.badge-unverified {
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent);
}

.ledger-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 0.92rem; }
.ledger-table th, .ledger-table td { padding: 10px 8px; text-align: left; border-bottom: 1px solid var(--line); }
.ledger-table th { font-weight: 600; color: var(--ink-2); font-size: 0.84rem; text-transform: uppercase; letter-spacing: 0.04em; }
.delta-pos { color: var(--good, #1f9d55); font-weight: 600; }
.delta-neg { color: var(--danger); font-weight: 600; }
.status-succeeded { color: var(--good, #1f9d55); }
.status-failed    { color: var(--danger); }
.status-running   { color: var(--warn); }
.status-queued    { color: var(--muted); }

/* ---------- render history (Steam-library style cards) ----------
   Grid of thumbnail-first cards. The thumb sits on top (16:10 aspect), the
   metadata + prompt + actions stack below. Failed / running jobs swap the
   thumbnail for a placeholder so the user still sees what they tried.        */
.profile-history-head { margin-bottom: 16px; }
.profile-history-head h2 { margin-bottom: 4px; }

.history-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px;
}

.history-card {
  display: flex; flex-direction: column;
  background: var(--bg-2, var(--bg));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.history-card:hover {
  transform: translateY(-2px);
  border-color: var(--blue);
  box-shadow: 0 12px 28px var(--blue-glow, rgba(0,0,0,0.18));
}
.history-card-failed:hover { border-color: var(--danger); box-shadow: 0 12px 28px rgba(220, 38, 38, 0.18); }
.history-card-running:hover { border-color: var(--warn); }

/* Thumbnail — 16:10 frame; the image cover-fills, placeholder centers icon. */
.history-thumb {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--bg-3, #f0f1f3);
  overflow: hidden;
}
.history-thumb-link { display: block; width: 100%; height: 100%; }
.history-thumb img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
  transition: transform 200ms ease;
}
.history-card:hover .history-thumb img { transform: scale(1.03); }
.history-thumb-placeholder {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  background: linear-gradient(135deg, var(--bg-3, #eef0f3), var(--bg-2, var(--bg)));
  gap: 6px;
}
.history-thumb-icon { font-size: 2rem; color: var(--muted); opacity: 0.6; }

/* Status pill — top-right corner of the thumbnail, like Steam's "Installed". */
.history-status-pill {
  position: absolute; top: 10px; right: 10px;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 0.72rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  letter-spacing: 0.04em; text-transform: uppercase;
  backdrop-filter: blur(4px);
}
.history-status-pill.status-succeeded { background: rgba(31, 157, 85, 0.85); color: #fff; }
.history-status-pill.status-failed    { background: rgba(220, 38, 38, 0.85); color: #fff; }
.history-status-pill.status-running   { background: rgba(217, 119, 6, 0.85); color: #fff; }
.history-status-pill.status-queued    { background: rgba(100, 116, 139, 0.85); color: #fff; }

/* Body — title row, prompt, meta, actions. */
.history-card-body {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px 16px 16px;
  flex: 1;                                    /* push actions to the bottom */
}
.history-card-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.history-card-head h3 {
  font-size: 1.05rem; font-weight: 700; margin: 0; line-height: 1.25;
  color: var(--ink);
}
.history-card-head time { white-space: nowrap; }

.history-prompt {
  font-size: 0.92rem;
  color: var(--ink-2);
  line-height: 1.45;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  font-style: italic;
}

.history-meta { display: flex; gap: 12px; }

.history-actions {
  display: flex; gap: 8px; align-items: center;
  margin-top: auto;                           /* keep buttons at card bottom */
  padding-top: 6px;
}
.history-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  font-size: 0.92rem; font-weight: 600;
  border-radius: var(--radius);
  text-decoration: none;
}
.history-btn-ghost {
  display: inline-flex; align-items: center;
  padding: 8px 12px;
  font-size: 0.88rem;
  color: var(--ink-2);
  text-decoration: none;
  border-radius: var(--radius);
  transition: color 120ms ease, background 120ms ease;
}
.history-btn-ghost:hover { color: var(--blue); background: var(--bg-3, transparent); }

@media (max-width: 600px) {
  .profile-tabs { gap: 0; overflow-x: auto; flex-wrap: nowrap; }
  .profile-tabs a { padding: 10px 10px; flex: 0 0 auto; }
  .profile-card { padding: 20px; }
  .ledger-table { font-size: 0.84rem; }
  .ledger-table th, .ledger-table td { padding: 8px 6px; }
  /* Narrow cards: single column at phone width, slightly smaller padding. */
  .history-grid { grid-template-columns: 1fr; gap: 14px; }
  .history-card-body { padding: 12px 14px 14px; }
  .history-card-head h3 { font-size: 1rem; }
}

/* ---------- studio ---------- */
.studio-greet { margin-bottom: 32px; }
.studio-greet h1 { font-size: 2rem; }

.running-banner {
  display: flex; align-items: center; gap: 12px;
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  color: var(--warn);
  padding: 12px 16px; border-radius: var(--radius); margin-bottom: 24px;
}
.rb-text { flex: 1; }
.rb-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex-shrink: 0;
  animation: rb-pulse 1.4s ease-in-out infinite; }
@keyframes rb-pulse { 0%,100% { opacity: 0.45; transform: scale(0.95); } 50% { opacity: 1; transform: scale(1.15); } }
.rb-spinner { width: 16px; height: 16px; border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor; border-radius: 50%; animation: rb-spin 0.8s linear infinite; flex-shrink: 0; }
@keyframes rb-spin { to { transform: rotate(360deg); } }

.tool-grid.is-locked { grid-template-columns: 1fr; }
.tool-card.disabled-locked {
  background: color-mix(in srgb, var(--warn) 8%, transparent);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
  color: var(--warn);
}
.tool-card.disabled-locked h3, .tool-card.disabled-locked p { color: var(--warn); opacity: 0.95; }

.recent-jobs { margin-top: 56px; }
.jobs { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 0.92rem; }
.jobs th, .jobs td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.jobs th { font-weight: 600; color: var(--muted); }
.pill { padding: 2px 10px; border-radius: 999px; font-size: 0.8rem; font-weight: 600; }
.pill-queued    { background: var(--bg-3); color: var(--ink-2); }
.pill-running   { background: var(--blue-50); color: var(--blue); }
.pill-succeeded { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok); }
.pill-failed    { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }

/* ---------- tool runner page ---------- */
.tool-runner { max-width: 760px; margin: 0 auto; }
.tool-runner header h1 { font-size: 2rem; }
.tool-runner form { display: grid; gap: 18px; margin-top: 24px; }
.tool-tips {
  margin-top: 18px; padding: 14px 16px;
  background: color-mix(in srgb, var(--blue) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue) 22%, transparent);
  border-radius: var(--radius-sm);
}
.tool-tips strong { display: block; color: var(--blue); font-size: 0.85rem; letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 4px; }
.tool-tips p { margin: 0; }

/* BETA badge — appears next to titles on the new tool */
.beta-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 0.6em; letter-spacing: 0.08em; font-weight: 700;
  background: color-mix(in srgb, var(--warn) 18%, transparent);
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
  border-radius: 999px;
  vertical-align: middle;
  text-transform: uppercase;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  font-style: normal;
}
.tool-card.is-beta {
  border-color: color-mix(in srgb, var(--warn) 28%, var(--line));
}
.tool-card.is-beta:hover {
  border-color: var(--warn);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--warn) 16%, transparent);
}

/* Full Render+ stepper layout (3-step flow: analyze → review → render) */
.frp-step-heading { font-size: 1.15rem; margin: 18px 0 4px; }

/* Beta + slow-generation notice — warning-tinted card at the top of the tool
   page so users know what to expect before they upload anything. */
.frp-beta-notice {
  display: block;
  margin: 14px 0 18px;
  padding: 12px 16px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  color: var(--warn);
  font-size: 0.92rem;
}
.frp-beta-notice strong {
  display: block;
  font-weight: 700;
  margin-bottom: 4px;
}
.frp-beta-notice span {
  color: color-mix(in srgb, var(--warn) 80%, var(--ink-2));
  line-height: 1.45;
}

/* Prominent progress card shown during /analyze and /render htmx requests.
   Uses the same .rb-spinner + .rb-pulse animations as the studio running banner.
   htmx puts `.htmx-request` directly on the element referenced by
   `hx-indicator="#..."`, so we match BOTH that case and the ancestor case. */
.frp-progress {
  display: none;
  align-items: center;
  gap: 14px;
  margin: 18px 0;
  padding: 14px 18px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--blue) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue) 25%, transparent);
  color: var(--blue);
}
.frp-progress.htmx-request,
.htmx-request .frp-progress { display: flex; }
.frp-progress .rb-spinner { width: 22px; height: 22px; border-width: 3px; }
.frp-progress-text { flex: 1; }
.frp-progress-text strong { display: block; }
.frp-progress-text span { display: block; font-size: 0.88rem; opacity: 0.8; margin-top: 2px; }

.frp-source-preview { margin: 12px 0 16px; }
.frp-source-preview img {
  display: block; max-width: 100%; max-height: 360px;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
}
.frp-reanalyze { margin: 0 0 16px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ink-2) 4%, transparent); }
.frp-reanalyze summary { cursor: pointer; padding: 2px 0; }
.frp-reanalyze textarea { margin-top: 8px; }
.frp-reanalyze button { margin-top: 8px; }

/* Accordion of per-region segment cards */
.frp-accordion { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 18px; }
.frp-segment-card {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg-1); overflow: hidden;
  transition: border-color 0.15s ease;
}
.frp-segment-card[open] { border-color: color-mix(in srgb, var(--blue) 40%, var(--line)); }
.frp-segment-card.is-filled { border-color: color-mix(in srgb, var(--green, #22c55e) 50%, var(--line)); }

.frp-segment-card > summary {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  cursor: pointer;
  list-style: none;
}
.frp-segment-card > summary::-webkit-details-marker { display: none; }
.frp-segment-card > summary::after {
  content: "▾"; opacity: 0.5; transition: transform 0.15s ease;
}
.frp-segment-card[open] > summary::after { transform: rotate(180deg); }

.frp-segment-thumb {
  width: 56px; height: 56px; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--bg-2);
}
.frp-segment-title { font-weight: 600; }
.frp-segment-status { margin-left: auto; padding-right: 14px;
  font-size: 1rem; color: color-mix(in srgb, var(--green, #22c55e) 80%, var(--ink-2)); }

.frp-segment-body { padding: 0 14px 14px; display: grid; gap: 10px; }
.frp-segment-full {
  width: 100%; max-height: 420px; object-fit: contain;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--bg-2);
}

.frp-result-actions { display: flex; gap: 10px; margin-top: 18px; }
.frp-error { margin: 20px 0; }

/* Reset (start-over) inline form below the Render button.
   Smaller, ghost-style, danger-tinted so users won't trip it by accident. */
.frp-reset { margin-top: 10px; display: flex; justify-content: flex-end; }
.frp-reset button {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 6px 12px;
  font-size: 0.85rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.frp-reset button:hover {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, var(--line));
}

/* Legacy: kept for the static 4-textarea layout in case anything still uses it. */
.frp-segments { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; margin: 0; }
.frp-segments legend { padding: 0 6px; font-size: 0.92rem; color: var(--ink-2); font-weight: 600; }
.frp-segments > p { margin: 0 0 10px; }
.frp-segment-row { display: grid; grid-template-columns: 32px 1fr; gap: 10px; align-items: start; margin-top: 8px; }
.frp-segment-row:first-of-type { margin-top: 0; }
.frp-segment-tag {
  display: grid; place-items: center;
  height: 28px; width: 28px; margin-top: 12px;
  font-size: 0.78rem; font-weight: 700;
  background: color-mix(in srgb, var(--blue) 8%, transparent);
  color: var(--blue);
  border-radius: 999px;
}

.tool-disclaimer {
  display: block; margin: 14px 0 0;
  padding: 8px 12px;
  border-left: 3px solid color-mix(in srgb, var(--blue) 50%, transparent);
  background: color-mix(in srgb, var(--blue) 4%, transparent);
  font-style: italic;
  color: var(--muted);
}

/* Unified prompt textarea — shared across every tool (Object/Full/Refine/Revise/Create) */
textarea.prompt-textarea {
  font-size: 1rem; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); width: 100%; min-height: 88px;
  font-family: inherit; line-height: 1.5; resize: vertical;
}
textarea.prompt-textarea:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-glow); }
.create-resolution { border: 0; padding: 0; margin: 0; display: grid; gap: 6px; }
.create-resolution legend { padding: 0; }

/* ---------- Create Concept — 3-step progressive form ---------- */
.create-step { border: 0; padding: 0; margin: 18px 0 0; display: grid; gap: 10px; }
.create-step[hidden] { display: none; }
.create-step-heading {
  font-size: 1.02rem; font-weight: 600; padding: 0;
  display: block; margin: 0;
}

/* Category grid: auto-fit wraps cleanly across 5 chips on any width.
   Each chip needs ~180px min to fit the name + description line. */
.create-cat-grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) !important;
}

/* Category chips are taller than the basic method-chip — they need to fit
   a name + a short description line. */
.method-chip.create-cat-chip {
  flex-direction: column;
  align-items: flex-start;
  padding: 14px 14px 12px;
  gap: 6px;
  text-align: left;
}
.method-chip.create-cat-chip .method-ico { font-size: 1.4rem; line-height: 1; }
.method-chip.create-cat-chip .create-cat-name { font-weight: 600; font-size: 0.95rem; }
.method-chip.create-cat-chip .create-cat-desc { font-size: 0.82rem; line-height: 1.35; }

/* Inline prompt-format tutorial */
.create-tutorial {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--blue) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--blue) 22%, transparent);
}
.create-tutorial strong { display: block; color: var(--blue); margin-bottom: 4px; }
.create-tutorial p { margin: 0; line-height: 1.55; }

/* Supplementary-LoRA toggles (collapsible accordion) */
.create-supplementaries {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
}
.create-supplementaries summary {
  cursor: pointer; padding: 2px 0;
  list-style: none;
}
.create-supplementaries summary::-webkit-details-marker { display: none; }
.create-supplementaries summary::after { content: '▾'; opacity: 0.5; float: right; }
.create-supplementaries[open] summary::after { content: '▴'; }
.create-supp-group { display: grid; gap: 6px; margin-top: 10px; }
.create-supp-group[hidden] { display: none; }
.create-supp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; border-radius: var(--radius-sm);
  cursor: pointer; transition: background 0.15s ease;
}
.create-supp-row:hover { background: color-mix(in srgb, var(--blue) 5%, transparent); }
.create-supp-row input[type="checkbox"] { accent-color: var(--blue); }

.dropzone {
  position: relative;
  border: 2px dashed var(--line); border-radius: var(--radius); padding: 20px;
  display: grid; place-items: center; cursor: pointer; transition: 120ms;
  text-align: center; min-height: 120px; background: var(--bg);
}
.dropzone:hover, .dropzone.dz-hover { border-color: var(--blue); background: var(--blue-50); }
.dropzone.dz-hover { border-style: solid; }
.dropzone > input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; z-index: 0; }
.dz-empty  { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.dz-empty strong { color: var(--ink); }
.dz-empty .dz-hint { font-size: 0.85rem; }
.dz-filled { display: flex; gap: 14px; align-items: center; width: 100%; z-index: 1; position: relative; }
.dz-filled[hidden] { display: none; }
.dz-preview { width: 64px; height: 64px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); flex-shrink: 0; background: var(--bg); }
@media (min-width: 600px) { .dz-preview { width: 80px; height: 80px; } }
@media (min-width: 900px) { .dz-preview { width: 88px; height: 88px; } }
.dz-meta { flex: 1; text-align: left; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dz-name { word-break: break-all; font-size: 0.95rem; line-height: 1.3; }
.dz-clear { white-space: nowrap; flex-shrink: 0; }
.dz-warn  { color: var(--warn); font-size: 0.85rem; margin-top: 8px; text-align: center; }
.dz-info  { color: var(--ink-2); font-size: 0.85rem; margin-top: 8px; text-align: center; }
.dz-info[hidden], .dz-warn[hidden] { display: none; }

/* Try-On dual dropzone — two side-by-side slots that stack on narrow screens. */
.tryon-dropzones {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}
.tryon-dropzones .dropzone { min-height: 160px; }
@media (max-width: 720px) {
  .tryon-dropzones { grid-template-columns: 1fr; }
}

/* Output-aspect radio group (portrait / square / landscape). Visual rectangles
   above each label give a one-glance preview of the chosen ratio. */
.aspect-picker {
  border: 0;
  padding: 0;
  margin: 4px 0 0;
}
.aspect-picker > legend {
  padding: 0 0 6px;
  margin: 0;
}
.aspect-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.aspect-chip {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 12px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, transform 120ms;
  position: relative;
}
.aspect-chip:hover { border-color: var(--blue); }
.aspect-chip > input[type="radio"] {
  position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0;
}
.aspect-chip:has(input:checked),
.aspect-chip > input:checked ~ * {
  /* Fallback for browsers without :has() — fine since the chip itself doesn't
     style without :has, but the glyph + name still highlight via direct
     adjacency below. */
}
.aspect-chip:has(input:checked) {
  border-color: var(--blue);
  background: color-mix(in srgb, var(--blue) 8%, var(--bg));
  box-shadow: 0 4px 14px var(--blue-glow);
}
.aspect-glyph {
  display: inline-block;
  border: 2px solid var(--ink-2);
  border-radius: 3px;
  background: transparent;
  transition: border-color 120ms;
}
.aspect-chip:has(input:checked) .aspect-glyph { border-color: var(--blue); }
/* 28px high baseline. Portrait = 9:16-ish (16w × 28h),
   square 20×20, landscape 28×16. */
.aspect-glyph-portrait  { width: 16px; height: 28px; }
.aspect-glyph-square    { width: 22px; height: 22px; }
.aspect-glyph-landscape { width: 28px; height: 16px; }
.aspect-name {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-2);
}
.aspect-chip:has(input:checked) .aspect-name { color: var(--blue); }

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: inline; }

.render-result { margin-top: 32px; }
.result-card {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 16px;
  background: var(--bg-2);
}
.result-card.error { border-color: color-mix(in srgb, var(--danger) 30%, transparent); background: color-mix(in srgb, var(--danger) 8%, transparent); }
.render-error-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.render-error-head strong { color: var(--danger); font-size: 1.05rem; }
.render-error-code {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  cursor: help;
}
.render-error p { margin: 0; line-height: 1.45; }
/* Small info banner above the result image — used when a job got migrated
   between ComfyUI instances during processing. Soft amber to read as info
   not error. */
.result-notice {
  padding: 8px 12px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 25%, transparent);
  margin-bottom: 10px;
}

/* Queued / running banner — inline progress UI shown in #render-result
   when the user submitted but their job is still in the server-side queue
   or in flight on a ComfyUI worker. Replaced by the RenderResult card
   when the job completes (via htmx polling of /api/jobs/status/<id>). */
.queued-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-2);
}
.queued-banner.is-running {
  background: color-mix(in srgb, var(--blue) 6%, transparent);
  border-color: color-mix(in srgb, var(--blue) 25%, transparent);
}
.qb-spinner {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--blue) 30%, transparent);
  border-top-color: var(--blue);
  animation: qb-spin 0.9s linear infinite;
  flex: 0 0 auto;
}
@keyframes qb-spin { to { transform: rotate(360deg); } }
.qb-body { display: flex; flex-direction: column; gap: 2px; }
.qb-body strong { color: var(--ink); }
.qb-body p { margin: 0; }

/* Pool-down banner — appears at the top of /studio and every tool page
   when the render service is fully unhealthy. htmx polls /api/pool/banner
   every 10s; banner auto-clears the moment the pool reports a healthy
   instance again. The empty wrapper (when pool is healthy) is invisible
   so the page reflow is zero on first paint. */
.pool-status-banner {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius);
  margin: 0 0 16px;
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
}
.pool-status-banner.is-down { display: flex; }
/* Overload variant — same warn palette as is-down (single yellow strip
   is the right urgency level for "fully loaded, try later"). Kept as a
   distinct class so the operator can theme them differently later (e.g.
   blue/info for overload, yellow/warn for down) without touching JSX. */
.pool-status-banner.is-overloaded { display: flex; }
.psb-icon { font-size: 1.25rem; color: var(--warn); flex: 0 0 auto; }
.psb-text { flex: 1 1 auto; line-height: 1.4; }
.psb-text strong { color: var(--warn); }

/* "Last render" wrapper — shown below the submit button on every tool
   page so the user's most recent successful render persists across
   reloads / navigation. htmx replaces the contents of #render-result on
   each fresh submit, so this label only appears when the slot is
   pre-filled from the server. */
.last-render {
  margin-top: 8px;
}
.last-render-label {
  display: flex; align-items: center; gap: 6px;
  margin: 0 0 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
  font-weight: 600;
}
.last-render-label span {
  color: var(--line);
}

/* Studio recent jobs — same Steam-library cards as /profile/history,
   capped at 5. Layout uses the existing .history-grid so the cards
   match exactly. The header row has the section title + a "view all"
   link to the full library. */
.recent-jobs { margin-top: clamp(24px, 4vw, 40px); }
.recent-jobs-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: clamp(10px, 1.5vw, 18px);
}
.recent-jobs-head h2 { margin: 0; }
.recent-jobs-all { text-decoration: none; }
.recent-jobs-all:hover { color: var(--blue); }
/* The grid inherits .history-grid but the 5-card cap means we don't need
   it to wrap aggressively — slightly larger minmax so cards aren't tiny. */
.recent-jobs-grid {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.result-card > img {
  max-width: 100%; max-height: 50vh; width: auto; height: auto; object-fit: contain;
  border-radius: var(--radius-sm); display: block; margin: 0 auto 14px; background: #fff;
}
@media (min-width: 600px) { .result-card > img { max-height: 55vh; } }
@media (min-width: 900px) { .result-card > img { max-height: 60vh; } }
/* In a result-card, the slider should size to the image's natural aspect
   (not the default 16:9 used on the marketing page). We do that by letting
   the AFTER image flow as a normal block — it defines the slider's height
   — and overlaying the BEFORE clip + handle on top of it via the existing
   absolute positioning. Without this, `aspect-ratio: auto` left the slider
   at height 0 (its absolute children contributed nothing), so only the
   handle's intrinsic 40px knob was visible — no images. */
.result-card .ba-slider { aspect-ratio: auto; max-height: 60vh; }
.result-card .ba-after {
  position: static;
  display: block;
  width: 100%;
  height: auto;
  max-height: 60vh;
  object-fit: contain;
  background: #fff;
}
.result-card .ba-slider .ba-before { object-fit: contain; background: #fff; }
.result-meta { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 10px; }

/* ---------- pricing ---------- */
.pricing-head { text-align: center; margin-bottom: 32px; }
.pricing-head h1 { font-size: 2.4rem; }
.pricing-head p { max-width: 56ch; margin: 8px auto 0; }

.pricing-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: 1180px; margin: 0 auto;
}
.pricing-card {
  position: relative; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 28px; display: flex; flex-direction: column; gap: 14px;
}
.pricing-card.is-popular {
  border-color: var(--blue);
  box-shadow: 0 12px 32px var(--blue-glow);
}
/* Max plan — accent in amber/gold so it visually distinguishes itself from the
   blue "popular" Pro card. The expiry trade-off is communicated separately
   via .pricing-expiry. */
.pricing-card.is-max {
  border-color: #d97706;             /* amber-600 */
  box-shadow: 0 12px 32px rgba(217, 119, 6, 0.18);
}
.pricing-card.is-max .pricing-num { color: #d97706; }
.pricing-badge {
  position: absolute; top: -12px; right: 22px;
  background: var(--blue); color: #fff; font-size: 0.75rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px; letter-spacing: 0.04em;
}
.pricing-badge.pricing-badge-max { background: #d97706; }
.pricing-card-head h3 { font-size: 1.4rem; margin-bottom: 4px; }
.pricing-amount { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.pricing-tokens { font-size: 2.2rem; font-weight: 800; color: var(--ink); }
.pricing-price  { display: flex; align-items: baseline; gap: 4px; }
.pricing-currency { color: var(--muted); font-size: 1.1rem; font-weight: 600; }
.pricing-num    { font-size: 2.2rem; font-weight: 800; color: var(--blue); letter-spacing: -0.02em; }
.pricing-pertoken { margin-top: -4px; }
.pricing-feats  { list-style: none; padding: 0; margin: 8px 0; display: grid; gap: 6px; font-size: 0.95rem; color: var(--ink-2); }
.pricing-feats li:first-child { color: var(--ink); margin-bottom: 2px; }
/* Expiry notice — amber tint with a soft background, slots above the CTA so
   it reads as a clear trade-off rather than fine print. */
.pricing-expiry {
  color: #b45309;                    /* amber-700 */
  background: rgba(217, 119, 6, 0.08);
  border: 1px solid rgba(217, 119, 6, 0.25);
  border-radius: var(--radius);
  padding: 8px 10px; margin: 0;
  display: flex; align-items: center; gap: 6px;
}
.pricing-btn { margin-top: auto; }
.pricing-btn:disabled { background: var(--bg-3); color: var(--muted); border: 1px solid var(--line); }
.is-popular .pricing-btn:disabled { background: var(--blue); color: #fff; border: none; opacity: 0.85; }
.pricing-soon { text-align: center; max-width: 56ch; margin: 28px auto 0; }

/* ---------- tutorials page ---------- */
/* Steam-library aesthetic for the tutorial guide: chunky cards, soft
   gradients, native <details> accordions, lightweight search filter.
   The page is one long scroll — no sidebar or JS-heavy nav. Visitors
   without an account can read the whole thing. */

/* Hero: smaller than the landing hero (different page priority) but
   keeps the same eyebrow + script-italic accent so the brand reads. */
.tt-hero {
  text-align: center;
  padding: clamp(24px, 5vw, 56px) clamp(12px, 3vw, 24px) clamp(20px, 3vw, 32px);
  max-width: 980px;
  margin: 0 auto;
}
.tt-hero h1 {
  font-size: clamp(1.8rem, 6vw, 3.4rem);
  margin: 6px auto 14px;
  letter-spacing: -0.025em;
}
.tt-hero-sub {
  max-width: 60ch;
  margin: 0 auto 26px;
  color: var(--ink-2);
  font-size: clamp(0.96rem, 1.6vw, 1.05rem);
  line-height: 1.55;
}
.tt-hero-sub strong { color: var(--ink); }
.tt-hero-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  max-width: 780px;
  margin: 28px auto;
  text-align: left;
}
.tt-step {
  display: grid; gap: 4px;
  padding: 16px 18px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  position: relative;
}
.tt-step strong { font-size: 1.02rem; color: var(--ink); }
.tt-step span { color: var(--ink-2); font-size: 0.9rem; line-height: 1.4; }
.tt-step-n {
  position: absolute; top: 12px; right: 14px;
  font-family: 'Georgia', 'Times New Roman', serif;
  font-style: italic; font-weight: 700;
  font-size: 1.4rem;
  color: var(--blue); opacity: 0.4;
}
.tt-hero-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

/* Multi-language callout — sits between the hero and the toolbar.
   Made visually distinct (subtle blue-tinted gradient + globe icon)
   so users notice the "you don't need to write in English" message
   before they start reading any prompt advice. The card has a soft
   blue-glow border and a wider max-width than .tt-section to draw
   the eye. */
.tt-multilang { max-width: 1080px; margin: clamp(20px, 4vw, 36px) auto; }
.tt-multilang-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(14px, 2vw, 22px);
  padding: clamp(20px, 3vw, 28px) clamp(22px, 4vw, 36px);
  background:
    radial-gradient(80% 100% at 0% 0%, color-mix(in srgb, var(--blue) 14%, transparent), transparent 60%),
    var(--bg-2);
  border: 1px solid color-mix(in srgb, var(--blue) 35%, var(--line));
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px color-mix(in srgb, var(--blue) 10%, transparent);
}
.tt-multilang-icon {
  font-size: clamp(2rem, 5vw, 3rem);
  align-self: start;
  filter: drop-shadow(0 2px 6px color-mix(in srgb, var(--blue) 35%, transparent));
}
.tt-multilang-text h2 {
  margin: 0 0 8px;
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
}
.tt-multilang-text p { margin: 0 0 12px; color: var(--ink-2); line-height: 1.55; }
.tt-multilang-text p:last-child { margin-bottom: 0; }
.tt-multilang-examples {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px 14px;
  margin: 14px 0;
  font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, monospace;
  font-size: 0.84rem;
  color: var(--ink);
}
.tt-multilang-examples span {
  padding: 6px 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.tt-multilang-examples strong {
  color: var(--blue);
  font-weight: 700;
  margin-right: 6px;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}
@media (max-width: 760px) {
  .tt-multilang-card { grid-template-columns: 1fr; text-align: left; }
  .tt-multilang-examples { grid-template-columns: 1fr; }
}

/* Toolbar: sticky-ish search + jump nav. Lightweight — no offscreen
   sidebar, no shadow blur, no JS for the smooth scroll (native CSS). */
html { scroll-behavior: smooth; }
.tt-toolbar {
  position: sticky; top: 56px;            /* sits just under the topnav */
  z-index: 5;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  padding: 10px clamp(12px, 3vw, 24px);
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  max-width: 1180px;
  margin: 0 auto;
}
.tt-search-wrap {
  position: relative; flex: 1 1 280px; min-width: 260px;
  display: flex; align-items: center;
}
.tt-search-wrap::before {
  content: '🔍';
  position: absolute; left: 12px; font-size: 0.92rem; opacity: 0.55;
  pointer-events: none;
}
#tt-search {
  width: 100%; padding: 9px 38px 9px 36px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.94rem;
  color: var(--ink);
  font-family: inherit;
}
#tt-search:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-glow); }
.tt-search-clear {
  position: absolute; right: 10px;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--bg-3); color: var(--ink-2);
  font-size: 0.7rem;
  cursor: pointer;
}
.tt-search-clear:hover { color: var(--ink); }
.tt-jump {
  display: flex; gap: 4px; flex-wrap: wrap;
}
.tt-jump a {
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: 0.85rem;
  font-weight: 500;
}
.tt-jump a:hover { background: var(--bg-2); color: var(--ink); border-color: var(--line-strong); text-decoration: none; }

/* Sections — wide max-width, comfortable rhythm. */
.tt-section {
  max-width: 1180px;
  margin: clamp(32px, 6vw, 64px) auto;
  padding: 0 clamp(12px, 3vw, 24px);
}
.tt-section-head {
  text-align: center;
  max-width: 56ch;
  margin: 0 auto clamp(20px, 3vw, 32px);
}
.tt-section-head h2 { font-size: clamp(1.4rem, 3.4vw, 2rem); margin-bottom: 8px; }
.tt-section-head p { color: var(--ink-2); margin: 0; }

/* "How to prompt" — two side-by-side cards. */
.tt-prompt-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
}
.tt-prompt-card {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 24px;
  display: grid; gap: 12px;
}
.tt-prompt-card h3 { margin: 0; font-size: 1.15rem; }
.tt-prompt-card p { margin: 0; color: var(--ink-2); line-height: 1.5; }
.tt-prompt-card code {
  display: block;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, monospace;
  font-size: 0.88rem;
  color: var(--ink);
  line-height: 1.5;
}
.tt-example-label { font-size: 0.82rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.tt-formula {
  display: inline-flex; flex-wrap: wrap; gap: 6px 8px; align-items: center;
  font-family: ui-monospace, 'Cascadia Code', monospace;
  font-size: 0.88rem;
}
.tt-formula > span {
  padding: 3px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--blue) 12%, transparent);
  color: var(--blue);
  border: 1px solid color-mix(in srgb, var(--blue) 32%, transparent);
}
.tt-formula-plus {
  background: transparent !important; border: none !important;
  color: var(--muted) !important; padding: 0 2px !important;
}
.tt-prompt-tip {
  margin: 22px auto 0;
  max-width: 60ch;
  text-align: center;
  font-size: 0.92rem;
}

/* Prompt-style chip — colour-codes INSTRUCT / ALTER / NO_PROMPT. */
.tt-style {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.tt-style-instruct { background: color-mix(in srgb, var(--blue) 16%, transparent); color: var(--blue); border: 1px solid color-mix(in srgb, var(--blue) 35%, transparent); }
.tt-style-alter    { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent); }
.tt-style-noprompt { background: color-mix(in srgb, var(--ok) 16%, transparent);   color: var(--ok);   border: 1px solid color-mix(in srgb, var(--ok) 35%, transparent); }

/* Tier wrapper — each of the 4 groups (AIRA / outfit / product / create) */
.tt-tier {
  margin: 0 0 clamp(18px, 3vw, 28px);
}
.tt-tier-head {
  margin: 0 0 12px;
  padding-left: 14px;
  border-left: 3px solid var(--blue);
}
.tt-tier-head h3 { margin: 0; font-size: 1.1rem; }
.tt-tier-head p  { margin: 2px 0 0; }
.tt-tier-grid { display: grid; gap: 12px; }

/* Tool accordion — native <details>. Collapsed state shows thumbnail
   + name + one-liner + chips. Open state reveals use case + sample
   prompt + before/after + CTA. */
.tt-tool {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 180ms ease, box-shadow 220ms ease;
}
.tt-tool:hover { border-color: color-mix(in srgb, var(--blue) 40%, var(--line)); }
.tt-tool[open] { border-color: var(--blue); box-shadow: 0 8px 22px var(--blue-glow); }
.tt-tool-head {
  display: grid;
  grid-template-columns: 88px 1fr auto 22px;
  gap: 14px;
  align-items: center;
  padding: 14px 18px;
  cursor: pointer;
  list-style: none;
}
.tt-tool-head::-webkit-details-marker { display: none; }
.tt-tool-head::marker                  { content: ''; }
.tt-tool-thumb {
  width: 88px; height: 64px;
  object-fit: cover; object-position: center 18%;
  border-radius: var(--radius-sm);
  background: var(--bg);
  border: 1px solid var(--line);
}
.tt-tool-headtext h3 {
  display: flex; align-items: baseline; gap: 8px;
  margin: 0 0 4px;
  font-size: 1.02rem;
}
.tt-tool-headtext p { margin: 0; color: var(--ink-2); font-size: 0.9rem; line-height: 1.35; }
.tt-tool-chips { display: flex; flex-direction: column; gap: 5px; align-items: flex-end; }
.tt-tool-cost {
  font-size: 0.78rem; font-weight: 700;
  padding: 3px 8px; border-radius: 999px;
  background: var(--bg);
  color: var(--ink-2);
  border: 1px solid var(--line);
}
.tt-tool-caret {
  font-size: 1.05rem; color: var(--ink-2);
  transition: transform 220ms ease, color 220ms ease;
  display: inline-block;
}
.tt-tool[open] .tt-tool-caret { transform: rotate(180deg); color: var(--blue); }
.tt-tool-body {
  padding: 4px 18px 20px;
  display: grid; gap: 14px;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.tt-tool-when strong, .tt-tool-prompt strong {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.tt-tool-when p { margin: 0; color: var(--ink); line-height: 1.5; }
.tt-tool-prompt code {
  display: block;
  padding: 11px 13px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, 'Cascadia Code', monospace;
  font-size: 0.88rem;
  color: var(--ink);
  line-height: 1.45;
}
.tt-tool-meta { margin: 0; }
.tt-tool-ba {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.tt-tool-ba figure { margin: 0; }
.tt-tool-ba img {
  width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; border-radius: var(--radius-sm);
  background: var(--bg-2);
  border: 1px solid var(--line);
}
.tt-tool-ba figcaption {
  margin-top: 6px;
  font-size: 0.78rem;
  color: var(--muted);
  text-align: center;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tt-tool-cta { justify-self: start; }

/* Search-filter state — `tt-filtered-out` hides cards / glossary rows /
   empty tier wrappers without changing layout shift. */
.tt-filtered-out { display: none !important; }
.tt-search-status {
  text-align: center;
  color: var(--muted);
  font-size: 0.88rem;
  margin: 0 0 14px;
}

/* Glossary — definition list with chip-style terms. */
.tt-glossary {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  max-width: 760px;
  margin: 0 auto;
}
.tt-glossary-row {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 14px;
  align-items: start;
}
.tt-glossary-row dt {
  font-weight: 700;
  color: var(--blue);
}
.tt-glossary-row dd { margin: 0; color: var(--ink-2); line-height: 1.5; }

/* CTA strip at the bottom — final nudge to sign up. */
.tt-cta-strip {
  text-align: center;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 5vw, 48px) clamp(16px, 4vw, 32px);
}
.tt-cta-row {
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
  margin-top: 16px;
}

/* Responsive tweaks — single column on phone for tools + prompt grid. */
@media (max-width: 760px) {
  .tt-hero-steps    { grid-template-columns: 1fr; max-width: 460px; }
  .tt-prompt-grid   { grid-template-columns: 1fr; }
  .tt-tool-head     { grid-template-columns: 60px 1fr 18px; gap: 10px; padding: 12px 14px; }
  .tt-tool-thumb    { width: 60px; height: 48px; }
  .tt-tool-headtext h3 { font-size: 0.95rem; }
  .tt-tool-headtext p  { font-size: 0.85rem; }
  .tt-tool-chips    { display: none; }       /* save space on phone — chips are inside the body when open */
  .tt-tool-body     { padding: 8px 14px 18px; }
  .tt-glossary-row  { grid-template-columns: 1fr; gap: 4px; }
  .tt-toolbar       { padding: 10px 14px; gap: 10px; }
  .tt-jump a        { padding: 6px 10px; font-size: 0.8rem; }
}

/* ---------- responsive ---------- */
/* Tablet / narrow desktop. */
@media (max-width: 880px) {
  .topnav {
    padding: 10px 16px;
    padding-top:    calc(10px + env(safe-area-inset-top));
    padding-left:   calc(16px + env(safe-area-inset-left));
    padding-right:  calc(16px + env(safe-area-inset-right));
    grid-template-columns: auto 1fr auto;
    gap: 10px;
  }
  .topnav-links { gap: 14px; }
  .topnav-links a { font-size: 0.92rem; }
  main {
    padding: 28px 16px 48px;
    padding-left:  calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
  .tool-cards, .tool-grid { grid-template-columns: 1fr; gap: 12px; }
  .auth { padding: 28px 0; }
  .auth-card { margin: 0; padding: 24px 20px; max-width: 100%; }
  .ba-slider { aspect-ratio: 4 / 5; }
  .pricing-grid { grid-template-columns: 1fr; gap: 14px; max-width: 560px; }
  .pricing-card { padding: 22px; }
  .profile { margin: 24px auto; padding: 0 12px; }
}

/* Mid-width: between mobile and 3-card desktop, fall back to a single column
   stacked layout so cards keep breathing room rather than squashing into 3
   skinny columns. The 3-up only kicks in above 1100px. */
@media (max-width: 1100px) and (min-width: 881px) {
  .pricing-grid { grid-template-columns: 1fr; max-width: 560px; gap: 14px; }
}

/* Phone — most iPhones / Androids land here (≤480px logical width).
   Tightening pass: the topnav has five+ chips crammed alongside the
   brand on phone, so every element gets squeezed slightly. The brand
   mark in particular used to render LARGER on phone than desktop
   (24px vs 20px) — left over from the chunky-glyph era; now matched
   to a slightly-smaller-than-desktop 16px to keep the wordmark + mark
   visually balanced on a narrow header. */
@media (max-width: 480px) {
  .topnav { padding: 8px 10px; gap: 6px; }
  .topnav-links { display: none; }                         /* yield space; nav reachable via the user-chip / brand */
  .brand { font-size: 0.92rem; gap: 7px; letter-spacing: 0.03em; }
  .brand-mark { width: 16px; height: 16px; }
  .topnav-utils { gap: 5px; }
  .lang-switcher { padding: 1px; }
  .lang-btn { font-size: 0.7rem; padding: 3px 6px; }
  .icon-btn { width: 26px; height: 26px; font-size: 13px; }
  /* Balance pill on phone — smaller icon, smaller pad, same coin/number
     vertical alignment as desktop. */
  .balance { padding: 3px 9px 3px 6px; font-size: 0.76rem; gap: 4px; }
  .balance-coin { width: 11px; height: 11px; }
  .user-chip { padding: 4px 8px; font-size: 0.8rem; }
  .user-chip-name { max-width: 8ch; }
  /* "Sign in" text link is redundant on phones — /signup links to /signin and back. */
  .topnav-utils .btn-link { display: none; }
  .btn-primary { padding: 8px 14px; font-size: 0.9rem; }
  .btn-primary.big { padding: 11px 18px; font-size: 0.95rem; }
  .btn-cta {
    padding: 7px 12px; font-size: 0.82rem; gap: 4px;
    box-shadow: 0 3px 10px var(--blue-glow);
  }

  main { padding: 20px 14px 40px; }
  footer { padding: 16px; font-size: 0.8rem; padding-bottom: calc(16px + env(safe-area-inset-bottom)); }

  /* Tool cards on phone — same image-as-bg layout, just shorter and
     with smaller text/chip footprints so a 1-col stack reads compactly
     instead of as a wall of tall thumbnails. */
  .tool-card { min-height: 170px; padding: 16px 18px 18px; }
  .tool-card-body { padding-top: 56px; }
  .tool-card h3 { font-size: 0.98rem; }
  .tool-card p  { font-size: 0.86rem; line-height: 1.35; }
  .tool-card-chips { top: 10px; right: 10px; gap: 4px; }
  .tool-card-chips .cost { padding: 3px 8px; font-size: 0.72rem; }
  .tool-card-chips .beta-badge { padding: 3px 7px; font-size: 0.62rem; }

  .hero { gap: 18px; }
  /* Font-size + line-height for .hero h1 come from the global clamp + the
     `@media (max-width: 600px)` rule earlier — DON'T re-fix it here; the old
     `font-size: 1.85rem; max-width: 16ch` capped the rotator at 16 char
     widths and clipped phrases like "Architecture & Interior,". */
  .hero-subhead { font-size: 0.95rem; margin: 10px auto 14px; }
  .hero-eyebrow { font-size: 0.78rem; }
  .trust { font-size: 0.78rem; margin-top: 10px; }
  .hero-figure { margin-top: 18px; }
  .ba-slider { aspect-ratio: 1 / 1; border-radius: var(--radius); }
  .ba-knob { width: 32px; height: 32px; font-size: 12px; }
  .ba-label { font-size: 0.68rem; padding: 3px 8px; top: 8px; }
  .ba-label-before { left: 8px; }
  .ba-label-after  { right: 8px; }

  .tools-strip { margin-top: 36px; }

  .auth-card { padding: 20px 16px; border-radius: var(--radius); }
  .auth-card h1 { font-size: 1.45rem; }
  .auth-form { gap: 14px; margin-top: 12px; }
  .auth-form input { padding: 11px 12px; }
  .method-row { grid-template-columns: 1fr; gap: 6px; }    /* stack the OTP method picker */
  .method-chip { padding: 9px 10px; font-size: 0.88rem; }
  .btn-google { padding: 11px 12px; }

  .studio-greet { margin-bottom: 20px; }
  .studio-greet h1 { font-size: 1.55rem; }
  .recent-jobs { margin-top: 32px; }
  .jobs { font-size: 0.85rem; }
  .jobs th, .jobs td { padding: 8px 6px; }

  .pricing-head h1 { font-size: 1.7rem; }
  .pricing-tokens, .pricing-num { font-size: 1.8rem; }
  .pricing-card { padding: 18px; gap: 10px; }

  .profile-head h1 { font-size: 1.35rem; }
  .profile-card { padding: 16px; border-radius: var(--radius); }
  .balance-num { font-size: 1.3rem; }

  .tool-runner header h1 { font-size: 1.5rem; }
  .dropzone { padding: 14px; min-height: 96px; }
}

/* Very narrow phones (iPhone SE, older Androids). */
@media (max-width: 360px) {
  .balance { display: none; }                              /* user-chip already shows username; balance is on /profile */
  /* `.hero h1` font-size handled by the global @media (max-width: 360px) rule
     earlier — leaving an explicit fixed-size override here clobbers it and
     re-introduces overflow. */
  .btn-cta { padding: 6px 10px; font-size: 0.78rem; }
  .btn-cta::after { font-size: 0.95em; }
}
