/* ═══════════════════════════════════════════════════════════════
   Type Unlimited — specimen.css
   Shared styles for font specimen pages (fonts/<name>/index.html).
   Paired with assets/js/specimen.js — each specimen page supplies
   only its own FONT_CONFIG object and a minimal HTML skeleton.
═══════════════════════════════════════════════════════════════ */

/* ── SPACING SCALE ───────────────────────────────────────────── */

:root {
  --space-xs:   8px;
  --space-s:   16px;
  --space-m:   24px;
  --space-l:   48px;
  --space-xl:  96px;
  --space-2xl: 160px;

  --wght: 400; /* live weight-axis value; set by the weight slider (variable fonts only) */
}

@media (max-width: 640px) {
  :root {
    --space-l:   32px;
    --space-xl:  64px;
    --space-2xl: 96px;
  }
}

/* ── LAYOUT ──────────────────────────────────────────────────── */

.specimen-body {
  /* .cta-block (shared, main.css) always ends the page now and carries its
     own generous bottom padding, sitewide-consistent — no extra gap needed
     here for last section → footer. */
  padding: 0 var(--pad-x);
}

/* ── HERO ────────────────────────────────────────────────────── */

.specimen-hero {
  padding-top: var(--space-l);   /* nav → back link */
}

.specimen-back {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--fg-mid);
  margin-bottom: var(--space-m); /* back link → hero */
  transition: color 0.2s;
}

.specimen-back:hover {
  color: var(--fg);
}

.specimen-hero-name {
  font-size: clamp(72px, 12vw, 180px);
  line-height: 1;
  letter-spacing: 0.01em;
  margin-bottom: var(--space-s); /* hero → description — one step tighter than the scale's default m→s, per hero cluster density request */
  /* font-family set by JS */
}

@media (max-width: 640px) {
  /* Below 600px, 12vw alone would go under the 72px floor above, so a
     longer name (e.g. "NOSTROMO") stops shrinking and overflows its
     container. Drop the floor to 40px here so long names keep scaling
     down with the viewport instead of plateauing. Continuous with the
     base rule at 600px, where 12vw already equals 72px on its own. */
  .specimen-hero-name {
    font-size: clamp(40px, 12vw, 180px);
  }
}

/* Live weight axis — one variable, driven by the weight slider (or its
   breathing animation), consumed by the hero, the tester, the character
   set, and the carousel preview. Variable fonts only; no-op otherwise. */
.specimen-hero-name,
.specimen-textarea,
.glyph-cell,
.carousel-preview-text {
  font-variation-settings: 'wght' var(--wght);
}

.specimen-hero-desc {
  font-family: var(--font-mono);
  font-size: clamp(0.875rem, 1.1vw, 1rem);
  color: var(--fg-mid);
  line-height: 1.6;
  max-width: 560px;
  margin-bottom: var(--space-xs); /* description → tags — one step tighter, same hero cluster density request */
}

/* Purchase button (optional, fonts/js only injects it when FONT_CONFIG.purchase
   is set) — a real .btn-cta-small (buying is this page's actual conversion),
   with a separate price/checkout caption beside it, never inside the filled
   surface — same convention as .cta-block-label sitting beside .btn-cta-big.
   The caption is linked to the button via aria-describedby (set in JS), not
   nested inside the <a>. Row wraps (caption drops under the button) on
   narrow screens via flex-wrap — no separate short-copy variant. */
.specimen-purchase {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: var(--space-s); /* tags → purchase row — one step tighter, same hero cluster density request */
}

.specimen-purchase-meta {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--fg-mid); /* readable — never --fg-faint, which is a hover-tint token, not a text color */
}

/* Screen-reader-only text — same clip technique as main.css's
   .visually-hidden-input, generalised here for non-input content
   (e.g. an "(opens in new tab)" note on an external link). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── CAROUSEL (multi-slide fonts, e.g. NOSTROMO) ────────────── */

.specimen-carousel {
  margin-top: var(--space-xl); /* section → section — one step tighter, per request */
}

.carousel-slide {
  display: none;
  width: 100%;
}

.carousel-slide.active {
  display: flex;
  align-items: center;
  justify-content: center;
}

.carousel-slide-text {
  flex-direction: column;
  min-height: 160px;
}

.carousel-preview-text {
  font-size: clamp(2rem, 5vw, 4.5rem);
  line-height: 1.2;
  text-align: center;
  word-break: break-word;
  padding: 24px 0;
  /* font-family set by JS */
}

.carousel-slide-image img {
  width: 100%;
  height: auto;
  display: block;
}

.carousel-controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 24px;
}

.carousel-chip {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-mid);
  background: none;
  border: 0.5px solid var(--rule);
  padding: 6px 14px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}

.carousel-chip:hover {
  color: var(--fg);
  border-color: var(--fg);
}

.carousel-chip.active {
  color: var(--bg);
  background: var(--fg);
  border-color: var(--fg);
}

/* Weight breathing animation indicator (variable fonts only). Lives in
   .specimen-preview now, next to the weight control it actually describes —
   previously nested in .specimen-carousel, which hides itself entirely for
   any font with no carousel slides (e.g. NOSTROMO today), silently hiding
   this along with it. */
.anim-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: flex-start;
  margin-bottom: var(--space-m); /* indicator → type tester */
  opacity: 0.5;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--fg-mid);
  transition: opacity 0.25s;
}

.anim-indicator.paused {
  opacity: 0;
}

.anim-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--fg);
  animation: pulse 1.8s ease-in-out infinite;
}

.anim-dot:nth-child(2) { animation-delay: 0.3s; }
.anim-dot:nth-child(3) { animation-delay: 0.6s; }

@keyframes pulse {
  0%, 100% { opacity: 0.3; transform: scale(0.8); }
  50%      { opacity: 1;   transform: scale(1.2); }
}

@media (prefers-reduced-motion: reduce) {
  /* Belt-and-suspenders alongside the JS check in specimen.js that skips
     starting the weight-breathing loop at all when this is set — this
     covers the dots' own CSS animation independently of that JS path. */
  .anim-dot { animation: none; }
}

/* ── GALLERY (static image fonts, e.g. Pops) ────────────────── */

.specimen-gallery {
  margin-top: var(--space-xl); /* section → section — one step tighter, per request */
}

.gallery-header {
  font-family: var(--font-mono);
  font-size: var(--caps-size);
  font-weight: var(--caps-weight);
  letter-spacing: var(--caps-tracking);
  text-transform: uppercase;
  color: var(--fg-mid);
  margin-bottom: var(--space-m); /* section label → content */
}

.gallery-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 900px;
}

.gallery-list img {
  width: 100%;
  height: auto;
  display: block;
}

/* ── TYPE TO TEST (controls + live preview, merged) ─────────── */

.specimen-preview {
  margin-top: var(--space-l); /* hero → Type to test; tighter than the standard section → section gap */
}

.preview-header {
  font-family: var(--font-mono);
  font-size: var(--caps-size);
  font-weight: var(--caps-weight);
  letter-spacing: var(--caps-tracking);
  text-transform: uppercase;
  color: var(--fg-mid);
  margin-bottom: var(--space-m); /* section label → content */
}

.controls-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  margin-bottom: 32px;
}

@media (max-width: 640px) {
  .controls-grid {
    grid-template-columns: 1fr;
    gap: 32px;
  }
}

.control-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.control-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--fg-mid);
  letter-spacing: 0.04em;
}

.control-value {
  font-family: var(--font-mono);
  color: var(--fg);
  font-weight: 500;
}

/* Slider */
.specimen-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 1px;
  background: var(--rule);
  outline: none;
}

.specimen-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--fg);
  cursor: pointer;
  transition: transform 0.15s;
}

.specimen-slider::-webkit-slider-thumb:hover {
  transform: scale(1.25);
}

.specimen-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--fg);
  cursor: pointer;
  border: none;
}

.weight-track-labels {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--fg-mid);
  margin-top: 4px;
}

/* Weight buttons (static fonts, e.g. Pops) */
.weight-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.weight-btn {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-mid);
  background: none;
  border: 0.5px solid var(--rule);
  padding: 8px 18px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}

.weight-btn:hover {
  color: var(--fg);
  border-color: var(--fg);
}

.weight-btn.active {
  color: var(--bg);
  background: var(--fg);
  border-color: var(--fg);
}

.specimen-textarea {
  width: 100%;
  min-height: 180px;
  padding: 24px;
  border: 0.5px solid var(--rule);
  background: transparent;
  color: var(--fg);
  font-size: 36px;
  line-height: 1.4;
  outline: none;
  resize: vertical;
  transition: border-color 0.2s;
  /* font-family set by JS */
}

.specimen-textarea:focus {
  border-color: var(--fg);
}

.specimen-textarea[contenteditable]:empty::before {
  content: "Type here to test the font...";
  color: var(--fg-mid);
  opacity: 0.5;
}

/* ── GLYPH GRID (character set) ─────────────────────────────── */

.specimen-glyphs {
  margin-top: var(--space-xl); /* section → section — one step tighter, per request */
}

.glyphs-header {
  font-family: var(--font-mono);
  font-size: var(--caps-size);
  font-weight: var(--caps-weight);
  letter-spacing: var(--caps-tracking);
  text-transform: uppercase;
  color: var(--fg-mid);
  margin-bottom: var(--space-m); /* section label → content */
}

.glyph-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  gap: 1px;
}

.glyph-cell {
  background: var(--bg);
  border: 0.5px solid var(--rule);
  display: grid;
  place-items: center;
  overflow: hidden;
  font-size: clamp(1rem, 2vw, 1.5rem);
  aspect-ratio: 1;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
  user-select: none;
  color: var(--fg);
  /* font-family set by JS */
}

.glyph-cell.glyph-cell-space {
  font-size: 0.875rem;
  color: var(--fg-mid);
}

.glyph-cell:hover {
  background: var(--fg-faint);
  transform: scale(1.08);
  z-index: 1;
}

.glyph-cell:active {
  transform: scale(0.95);
}

@media (max-width: 640px) {
  .glyph-grid {
    grid-template-columns: repeat(auto-fill, minmax(32px, 1fr));
  }
}

/* ── TECHNICAL DETAILS ───────────────────────────────────────── */

.specimen-tech {
  margin-top: var(--space-xl); /* section → section — one step tighter, per request */
}

.tech-header {
  font-family: var(--font-mono);
  font-size: var(--caps-size);
  font-weight: var(--caps-weight);
  letter-spacing: var(--caps-tracking);
  text-transform: uppercase;
  color: var(--fg-mid);
  margin-bottom: var(--space-m); /* section label → content */
}

.tech-list {
  display: grid;
  grid-template-columns: 200px 1fr;
  row-gap: var(--space-s);
  column-gap: var(--space-m);
  max-width: 700px;
  font-family: var(--font-mono);
  font-size: 0.9375rem;
}

.tech-list dt {
  color: var(--fg-mid);
}

.tech-list dd {
  color: var(--fg);
}

@media (max-width: 640px) {
  .tech-list {
    grid-template-columns: 1fr;
    row-gap: var(--space-xs);
  }

  .tech-list dd {
    margin-bottom: var(--space-s);
  }
}

/* Section rhythm on mobile is handled by the --space-* overrides above. */
