/* =========================================================================
   main.css — Single-file design system for the Converter UI.

   Authored by hand — no preprocessor, no build step, no imports. The only
   way styles reach the page is via <link rel="stylesheet"> in base.html.

   Table of contents:
     1. Design tokens (:root custom properties)
     2. Reset and base element styles
     3. Alpine [x-cloak] helper
     4. Layout containers
     5. Site header + navigation
     6. Hamburger mobile nav (.site-nav__toggle)
     7. Buttons (.btn, .btn--primary, .btn--secondary)
     8. Upload drop zone (.upload-drop)
     9. Status line states (.status-line, --error, queued/processing/done)
    10. Error banners (.error-banner + modifiers)
    11. DJVU warning alert (.djvu-warning)
    12. Converter page blocks (.converter, .instructions, .faq, .download-area)
    13. Homepage blocks (.home, .universal-upload)
    14. Format groups + format grid (.format-group, .format-grid, .format-card)
    15. Related converters (.related-converters)
    16. Three-step how-it-works (.three-steps)
    17. Stats counter (.stats-counter)
    18. Site footer
    19. Responsive breakpoints (@media max-width: 768px, 480px)
   ========================================================================= */


/* ------------------------------------------------------------------------
   1. Design tokens
   Named custom properties are the hard contract with Tasks 2 and 3.
   Exact hex/px values are advisory and can be tuned during QA.
   ------------------------------------------------------------------------ */
:root {
  /* Colors */
  --color-bg:           #ffffff;
  --color-bg-alt:       #f8f9fa;
  --color-primary:      #3b82f6;
  --color-primary-dark: #2563eb;
  --color-accent:       #3b82f6;
  --color-text:         #1f2937;
  --color-text-muted:   #6b7280;
  --color-border:       #e5e7eb;
  --color-error:        #ef4444;
  --color-error-bg:     #fef2f2;
  --color-warning:      #f59e0b;
  --color-warning-bg:   #fffbeb;
  --color-success:      #10b981;
  --color-success-bg:   #ecfdf5;

  /* Spacing scale (4 / 8 / 12 / 16 / 24 / 32 / 48 / 64) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* Typography */
  --fs-body: 16px;
  --fs-small: 14px;
  --fs-h1: 32px;
  --fs-h2: 24px;
  --fs-h3: 20px;
  --font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                "Helvetica Neue", Arial, sans-serif;

  /* Radii */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;

  /* Transitions */
  --transition-fast: 120ms ease-out;
  --transition-base: 200ms ease-out;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
}


/* ------------------------------------------------------------------------
   2. Reset and base element styles
   ------------------------------------------------------------------------ */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-stack);
  color: var(--color-text);
  background: var(--color-bg);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Prevent horizontal scroll from unexpectedly-long words / URLs. */
  overflow-wrap: break-word;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--space-4);
  line-height: 1.2;
  color: var(--color-text);
}

h1 { font-size: var(--fs-h1); font-weight: 700; }
h2 { font-size: var(--fs-h2); font-weight: 600; }
h3 { font-size: var(--fs-h3); font-weight: 600; }

p {
  margin: 0 0 var(--space-4);
}

a {
  color: var(--color-primary);
  text-decoration: none;
  transition: color var(--transition-fast);
}
a:hover,
a:focus-visible {
  color: var(--color-primary-dark);
  text-decoration: underline;
}

button {
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

legend {
  padding: 0;
  font-weight: 600;
}


/* ------------------------------------------------------------------------
   3. Alpine [x-cloak] helper
   Keeps x-show'd blocks invisible until Alpine initialises on first paint.
   The !important is the canonical Alpine pattern — the only one in the file.
   ------------------------------------------------------------------------ */
[x-cloak] {
  display: none !important;
}


/* ------------------------------------------------------------------------
   4. Layout containers
   ------------------------------------------------------------------------ */
.site-main {
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5);
}


/* ------------------------------------------------------------------------
   5. Site header + navigation
   ------------------------------------------------------------------------ */
.site-header {
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}

.site-header__inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-4) var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.site-logo {
  color: var(--color-primary);
  font-weight: 700;
  font-size: var(--fs-h3);
  text-decoration: none;
  flex-shrink: 0;
}
.site-logo:hover,
.site-logo:focus-visible {
  color: var(--color-primary-dark);
  text-decoration: none;
}

.site-nav {
  display: flex;
  flex-direction: row;
  gap: var(--space-5);
  align-items: center;
  flex-grow: 1;
}

.site-nav a {
  color: var(--color-text);
  text-decoration: none;
  font-weight: 500;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.site-nav a:hover,
.site-nav a:focus-visible {
  color: var(--color-primary);
  background: var(--color-bg-alt);
  text-decoration: none;
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.telegram-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--color-bg-alt);
  color: var(--color-text);
  border-radius: var(--radius-md);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.telegram-link:hover,
.telegram-link:focus-visible {
  background: var(--color-primary);
  color: #ffffff;
  text-decoration: none;
}

.lang-switcher {
  display: inline-flex;
  gap: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.lang-switcher__btn {
  background: var(--color-bg);
  color: var(--color-text);
  border: 0;
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
  font-size: var(--fs-small);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.lang-switcher__btn + .lang-switcher__btn {
  border-left: 1px solid var(--color-border);
}
.lang-switcher__btn:hover,
.lang-switcher__btn:focus-visible {
  background: var(--color-bg-alt);
}
.lang-switcher__btn.is-active {
  background: var(--color-primary);
  color: #ffffff;
}


/* ------------------------------------------------------------------------
   6. Hamburger mobile nav toggle
   Hidden by default; the 768px media query reveals it on narrow screens.
   The open-state modifier (.site-nav--open) is applied by Alpine when
   menuOpen === true (see base.html).
   ------------------------------------------------------------------------ */
.site-nav__toggle {
  display: none; /* revealed at <=768px */
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  width: 40px;
  height: 40px;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  flex-shrink: 0;
}
.site-nav__toggle:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.site-nav__toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--color-text);
  border-radius: 1px;
  transition: background var(--transition-fast);
}


/* ------------------------------------------------------------------------
   7. Buttons
   ------------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.2;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transition-base),
              color var(--transition-base),
              border-color var(--transition-base),
              transform var(--transition-fast);
  user-select: none;
}
.btn:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.btn--primary {
  background: var(--color-primary);
  color: #ffffff;
  border-color: var(--color-primary);
}
.btn--primary:hover:not(:disabled) {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
  color: #ffffff;
  text-decoration: none;
}
.btn--primary:active:not(:disabled) {
  transform: translateY(1px);
}

.btn--secondary {
  background: var(--color-bg-alt);
  color: var(--color-text);
  border-color: var(--color-border);
}
.btn--secondary:hover:not(:disabled) {
  background: var(--color-border);
  color: var(--color-text);
  text-decoration: none;
}
.btn--secondary:active:not(:disabled) {
  transform: translateY(1px);
}


/* ------------------------------------------------------------------------
   8. Upload drop zone
   <label class="upload-drop"> wraps a visually-hidden file input.
   .is-dragover toggled by Alpine handlers (Task 3).
   ------------------------------------------------------------------------ */
.upload-drop {
  display: block;
  position: relative;
  padding: var(--space-7) var(--space-5);
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  text-align: center;
  cursor: pointer;
  transition: background var(--transition-base),
              border-color var(--transition-base);
  width: 100%;
}
.upload-drop:hover {
  background: var(--color-bg-alt);
  border-color: var(--color-text-muted);
}
.upload-drop:focus-within {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.upload-drop.is-dragover {
  background: var(--color-bg-alt);
  border-color: var(--color-primary);
  border-style: solid;
}
/* Visually hide the native file input but keep it focusable. */
.upload-drop input[type="file"] {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.upload-drop__hint {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--fs-body);
}
/* Long filenames shouldn't blow out the drop zone (Task 3 will add markup). */
.upload-drop__filename {
  display: inline-block;
  max-width: 40ch;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  vertical-align: bottom;
}


/* ------------------------------------------------------------------------
   9. Status line states
   Three visually distinct states: queued (neutral), processing (animated
   stripe), done (green accent). --error is the red variant.
   ------------------------------------------------------------------------ */
.status-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-text-muted);
  border-radius: var(--radius-md);
  color: var(--color-text);
  margin: var(--space-4) 0;
}

/* Queued = neutral, matches base rule. */

/* Processing = animated diagonal stripe on the left border.
   Explicit class added by markup in Task 3 where needed. */
.status-line--processing {
  border-left-color: var(--color-primary);
  background: var(--color-bg-alt);
  position: relative;
  overflow: hidden;
}
.status-line--processing::before {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: linear-gradient(
    90deg,
    var(--color-primary) 0%,
    var(--color-primary) 40%,
    transparent 40%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: status-progress 1.2s linear infinite;
}
@keyframes status-progress {
  from { background-position: 100% 0; }
  to   { background-position: -100% 0; }
}

/* Respect users who asked the OS for reduced motion — kill the
   infinite stripe animation and freeze it at the start position. */
@media (prefers-reduced-motion: reduce) {
  .status-line--processing::before {
    animation: none;
    background-position: 0 0;
  }
}

.status-line--done {
  border-left-color: var(--color-success);
  background: var(--color-success-bg);
  color: var(--color-text);
}

.status-line--error {
  border-left-color: var(--color-error);
  background: var(--color-error-bg);
  color: var(--color-error);
  font-weight: 500;
}


/* ------------------------------------------------------------------------
   10. Error banners
   Generic container for prominent errors (rate limit, file too large, …).
   Task 2/3 markup injects these — Task 1 only supplies the CSS.
   ------------------------------------------------------------------------ */
.error-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-error);
  background: var(--color-error-bg);
  color: var(--color-error);
  margin: var(--space-4) 0;
  font-weight: 500;
}
.error-banner::before {
  content: "!";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  background: var(--color-error);
  color: #ffffff;
  border-radius: 50%;
  font-weight: 700;
}
.error-banner--rate-limit {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: #92400e;
}
.error-banner--rate-limit::before {
  background: var(--color-warning);
  content: "\231B"; /* hourglass */
  font-size: 14px;
}
.error-banner--size {
  background: var(--color-bg-alt);
  border-color: var(--color-text-muted);
  color: var(--color-text);
}
.error-banner--size::before {
  background: var(--color-text-muted);
  content: "\00D7";
  font-size: 18px;
}


/* ------------------------------------------------------------------------
   11. DJVU warning alert
   Base rule IS the warning state — no --alert modifier per task spec.
   ------------------------------------------------------------------------ */
.djvu-warning {
  display: block;
  padding: var(--space-4) var(--space-5);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning);
  border-left: 4px solid var(--color-warning);
  border-radius: var(--radius-md);
  color: #92400e;
  margin: 0 0 var(--space-5);
  font-weight: 500;
}


/* ------------------------------------------------------------------------
   12. Converter page blocks
   ------------------------------------------------------------------------ */
.converter {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.converter__heading {
  margin: 0;
  font-size: var(--fs-h1);
}

.converter__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-bg-alt);
  border-radius: var(--radius-lg);
}

.converter__status {
  min-height: 48px;
}

.converter__description {
  color: var(--color-text-muted);
  font-size: var(--fs-body);
  line-height: 1.6;
}

.instructions {
  background: var(--color-bg);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.instructions h2 {
  margin-top: 0;
  font-size: var(--fs-h2);
}
.instructions ol {
  margin: 0;
  padding-left: var(--space-5);
  line-height: 1.7;
}
.instructions li + li {
  margin-top: var(--space-2);
}

/* FAQ accordion — dt > button is the full-width click target, dd is
   the answer body. Task 3 keeps the existing x-show / x-cloak wiring. */
.faq {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.faq h2 {
  margin-top: 0;
  font-size: var(--fs-h2);
}
.faq dl {
  margin: 0;
}
.faq dt {
  border-top: 1px solid var(--color-border);
}
.faq dt:first-child {
  border-top: 0;
}
.faq dt > button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-4) 0;
  background: transparent;
  border: 0;
  color: var(--color-text);
  font-weight: 600;
  font-size: var(--fs-body);
  text-align: left;
  cursor: pointer;
}
.faq dt > button::after {
  content: "";
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--color-text-muted);
  border-bottom: 2px solid var(--color-text-muted);
  transform: rotate(45deg);
  transition: transform var(--transition-base);
}
.faq dt > button[aria-expanded="true"]::after {
  transform: rotate(-135deg);
}
.faq dt > button:hover,
.faq dt > button:focus-visible {
  color: var(--color-primary);
}
.faq dd {
  margin: 0 0 var(--space-4);
  padding-left: 0;
  color: var(--color-text-muted);
  line-height: 1.6;
}

.download-area {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-success-bg);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-lg);
}
.download-area p {
  margin: 0;
}


/* ------------------------------------------------------------------------
   13. Homepage blocks
   ------------------------------------------------------------------------ */
.home {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.home__title {
  margin: 0;
  font-size: var(--fs-h1);
}

.home__intro {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--fs-h3);
  max-width: 68ch;
}

.home__empty {
  padding: var(--space-5);
  background: var(--color-bg-alt);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  text-align: center;
}

.universal-upload {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--color-bg-alt);
  border-radius: var(--radius-lg);
}
.universal-upload__heading {
  margin: 0;
  font-size: var(--fs-h2);
}
.universal-upload__hint {
  margin: 0;
  color: var(--color-text-muted);
}
.universal-upload__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.universal-upload__targets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0;
}
.universal-upload__targets legend {
  margin-bottom: var(--space-3);
  font-weight: 600;
}
.universal-upload__target {
  display: inline-block;
  position: relative;
  cursor: pointer;
}
/* Visually hide the native radio input but keep it focusable. */
.universal-upload__target input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.universal-upload__target > span {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  border-radius: 999px;
  font-weight: 500;
  font-size: var(--fs-small);
  color: var(--color-text);
  transition: background var(--transition-fast),
              border-color var(--transition-fast),
              color var(--transition-fast);
}
.universal-upload__target input[type="radio"]:checked + span {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #ffffff;
}
.universal-upload__target input[type="radio"]:focus-visible + span {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.universal-upload__target:hover > span {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.universal-upload__target input[type="radio"]:checked + span,
.universal-upload__target:hover input[type="radio"]:checked + span {
  color: #ffffff;
}

.universal-upload__status {
  min-height: 24px;
}


/* ------------------------------------------------------------------------
   14. Format groups + format grid + format cards
   Supports both the existing <li><a>...</a></li> markup and a future
   .format-card subitem so Task 2 can drop in markup without CSS edits.
   ------------------------------------------------------------------------ */
.format-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.format-group__heading {
  margin: 0;
  font-size: var(--fs-h2);
}
.format-group__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.format-group__list > li {
  display: block;
}
.format-group__list a {
  display: block;
  padding: var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-weight: 500;
  text-decoration: none;
  transition: border-color var(--transition-fast),
              background var(--transition-fast),
              transform var(--transition-fast);
}
.format-group__list a:hover,
.format-group__list a:focus-visible {
  border-color: var(--color-primary);
  background: var(--color-bg-alt);
  color: var(--color-primary);
  text-decoration: none;
}

/* Homepage format grid wrapper — Task 2 will wrap cards in this. */
.format-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* Individual format cards — singular class, not __item. */
.format-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
  transition: border-color var(--transition-fast),
              background var(--transition-fast),
              box-shadow var(--transition-fast);
}
.format-card:hover,
.format-card:focus-visible {
  border-color: var(--color-primary);
  background: var(--color-bg-alt);
  box-shadow: var(--shadow-md);
  text-decoration: none;
}

/* Wrapper used on the convert page to show "format info cards". */
.format-cards {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  margin: var(--space-5) 0;
}


/* ------------------------------------------------------------------------
   15. Related converters (convert page)
   ------------------------------------------------------------------------ */
.related-converters {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-bg-alt);
  border-radius: var(--radius-lg);
}
.related-converters h2 {
  margin: 0;
  font-size: var(--fs-h2);
}
.related-converters ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.related-converters a {
  display: block;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
  font-weight: 500;
  transition: border-color var(--transition-fast),
              color var(--transition-fast);
}
.related-converters a:hover,
.related-converters a:focus-visible {
  border-color: var(--color-primary);
  color: var(--color-primary);
  text-decoration: none;
}


/* ------------------------------------------------------------------------
   16. Three-step "How it works" block
   ------------------------------------------------------------------------ */
.three-steps {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin: var(--space-6) 0;
}
.three-steps__item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.three-steps__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--color-primary);
  color: #ffffff;
  border-radius: 50%;
  font-weight: 700;
  font-size: var(--fs-h3);
  flex-shrink: 0;
}
.three-steps__label {
  margin: 0;
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--color-text);
}


/* ------------------------------------------------------------------------
   17. Stats counter
   ------------------------------------------------------------------------ */
.stats-counter {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-alt);
  border-radius: var(--radius-md);
  font-size: var(--fs-body);
  color: var(--color-text-muted);
}
.stats-counter strong {
  color: var(--color-text);
  font-size: var(--fs-h3);
  font-weight: 700;
}


/* ------------------------------------------------------------------------
   17b. Error page (404 and friends)
   Centred single-column layout reusing existing tokens — the template
   currently ships with a few inline styles, these rules let us strip
   those later without a visual regression.
   ------------------------------------------------------------------------ */
.error-page {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--space-7) var(--space-4);
  text-align: center;
  color: var(--color-text);
}
.error-page h1 {
  font-size: var(--fs-h1);
  margin: 0 0 var(--space-3);
  color: var(--color-text);
}
.error-page p {
  font-size: var(--fs-body);
  color: var(--color-text-muted);
  margin: var(--space-3) 0;
}
.error-page a {
  color: var(--color-primary);
}


/* ------------------------------------------------------------------------
   18. Site footer
   ------------------------------------------------------------------------ */
.site-footer {
  background: var(--color-text);
  color: var(--color-bg);
  margin-top: var(--space-8);
  padding: var(--space-6) 0;
}
.site-footer__inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.site-footer__copyright {
  color: var(--color-bg-alt);
  font-size: var(--fs-small);
}
.site-footer .telegram-link {
  background: transparent;
  color: var(--color-bg);
  border: 1px solid rgba(255, 255, 255, 0.2);
}
.site-footer .telegram-link:hover,
.site-footer .telegram-link:focus-visible {
  background: rgba(255, 255, 255, 0.1);
  color: var(--color-bg);
}


/* ------------------------------------------------------------------------
   19. Responsive breakpoints
   Desktop-first (max-width) queries because the hamburger flips at 768px
   and phone-only adjustments live at 480px — easier to read in that order.
   ------------------------------------------------------------------------ */
@media (max-width: 768px) {
  /* Hamburger appears, nav collapses. */
  .site-nav__toggle {
    display: flex;
    order: 3;
  }
  .site-header__inner {
    flex-wrap: wrap;
    gap: var(--space-3);
  }
  .site-nav {
    display: none;
    order: 4;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--color-border);
  }
  .site-nav--open {
    display: flex;
  }
  .site-header__actions {
    order: 2;
    margin-left: auto;
  }

  /* Stack the footer on mobile. */
  .site-footer__inner {
    flex-direction: column;
    align-items: flex-start;
  }

  /* Slightly tighter typography on tablets. */
  :root {
    --fs-h1: 28px;
  }
}

@media (max-width: 480px) {
  :root {
    --fs-h1: 24px;
    --fs-h2: 20px;
  }

  .site-main {
    padding: var(--space-4) var(--space-3);
  }
  .site-header__inner {
    padding: var(--space-3);
  }

  /* Full-width primary actions on phones. */
  .btn {
    width: 100%;
  }
  /* Lang switcher stays inline. */
  .lang-switcher__btn {
    width: auto;
  }
  /* Inline buttons inside pill groups must not stretch. */
  .lang-switcher .lang-switcher__btn {
    width: auto;
  }
  .site-header__actions .telegram-link {
    width: auto;
  }

  /* Single-column format grid on phones. */
  .format-grid,
  .format-cards,
  .format-group__list,
  .related-converters ul {
    grid-template-columns: 1fr;
  }
  .three-steps {
    grid-template-columns: 1fr;
  }

  /* Softer upload drop padding on small screens. */
  .upload-drop {
    padding: var(--space-5) var(--space-3);
  }

  /* Long URLs / filenames must not blow past the viewport. */
  .universal-upload,
  .converter,
  .converter__description,
  .instructions {
    overflow-wrap: anywhere;
  }
}
