/* ── QR Code Generator — engineering scan bench ──
   A matte slate instrument deck with a real alignment frame around the QR
   "specimen" (corner brackets, not a glow). The accent is a muted, oxidised
   steel-teal — deliberately desaturated so it reads as a measuring tool, not
   a neon "AI" surface. Cool palette sets it apart from the warm amber of
   hash-generator / image-compressor without sharing their hue.
   NO glassmorphism, NO neon glow, NO cyan→indigo gradient (anti-pattern floor). */

.qr-code-generator-page {
  --qr-steel: #6f9aab;          /* muted oxidised steel-teal — primary accent */
  --qr-steel-hi: #8fb6c5;       /* hover / high state */
  --qr-steel-soft: rgba(111, 154, 171, 0.14);
  --qr-steel-line: rgba(127, 156, 170, 0.30);
  --qr-frame-width: 1080px;
  /* Solid matte slate — no gradient, no translucency theatrics. */
  --qr-deck: #141b21;           /* instrument deck surface */
  --qr-deck-raised: #1a232b;    /* raised panels on the deck */
  --qr-input-bg: #0f151a;
  --qr-border: rgba(120, 145, 160, 0.18);
  --qr-ink: #e6edf2;
  --qr-ink-soft: #c3d0d8;
  --qr-ink-muted: #8a9aa4;
  --qr-chip-bg: #10171d;
  --qr-chip-active-bg: var(--qr-steel);
  --qr-chip-active-ink: #0a1014;
  --qr-textarea-border: rgba(120, 145, 160, 0.28);
  /* Specimen stage where the QR sits — near-white so the code reads true. */
  --qr-stage: #f4f6f7;
}

.qr-code-generator-page .tool-frame {
  width: 100%;
  max-width: var(--qr-frame-width);
  margin-inline: auto;
  padding-inline: clamp(0.25rem, 1vw, 0.6rem);
}

.qr-code-generator-page .tool-header-block {
  max-width: 52ch;
  padding-inline: 0.2rem;
}

.qr-code-generator-page .page-title {
  max-width: none;
  font-size: clamp(2.4rem, 3.5vw, 3rem);
  line-height: 0.97;
}

.qr-code-generator-page .page-subtitle {
  max-width: 46ch;
  font-size: clamp(1rem, 1.3vw, 1.1rem);
}

.qr-meta-line {
  margin: 0.4rem 0 0;
  font-size: var(--text-sm);
  color: var(--qr-ink-muted);
  letter-spacing: 0.01em;
}

/* ── Bench layout ── */
.qr-bench {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto);
  gap: 1.25rem;
  align-items: start;
}

.qr-col {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

.qr-col--preview {
  width: clamp(220px, 30vw, 340px);
  flex-shrink: 0;
}

/* ── Input panel ── */
.qr-panel {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--qr-border);
  border-radius: 18px;
  background: var(--qr-deck-raised);
}

.qr-panel__header {
  margin-bottom: 0.65rem;
}

.qr-panel__eyebrow {
  margin: 0 0 0.2rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--qr-steel);
}

.qr-panel__hint {
  margin: 0;
  color: var(--qr-ink-soft);
  font-size: var(--text-sm);
  max-width: 34ch;
}

/* ── Textarea ── */
.qr-textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 9rem;
  padding: 0.75rem 0.9rem;
  background: var(--qr-input-bg);
  border: 1px solid var(--qr-textarea-border);
  border-radius: 12px;
  color: var(--qr-ink);
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1.55;
  resize: vertical;
  outline: none;
  transition: border-color 0.18s;
}

.qr-textarea:focus {
  border-color: var(--qr-steel);
  box-shadow: 0 0 0 2px var(--qr-steel-soft);
}

/* ── Character counter ── */
.qr-char-counter {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--qr-ink-muted);
  text-align: right;
}

.qr-char-counter.qr-char-counter--warn {
  color: #f59e0b;
}

.qr-char-counter.qr-char-counter--over {
  /* #ef4444 is ~4.0:1 on the slate deck — borderline-fail WCAG AA for this
     error-state counter. #f87171 (~5.6:1) matches the feedback-slot error tone. */
  color: #f87171;
}

/* ── Controls ── */
.qr-controls {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--qr-border);
  border-radius: 14px;
  background: var(--qr-deck-raised);
}

.qr-control-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  flex-wrap: wrap;
}

.qr-control-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--qr-ink-soft);
  min-width: 5rem;
  flex-shrink: 0;
}

.qr-chip-group {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.qr-chip {
  padding: 0.28rem 0.65rem;
  min-height: 0;
  font-size: 0.82rem;
  font-weight: 600;
  font-family: var(--font-mono, monospace);
  background: var(--qr-chip-bg);
  border: 1px solid var(--qr-border);
  border-radius: 7px;
  color: var(--qr-ink-soft);
  cursor: pointer;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
  letter-spacing: 0.02em;
}

.qr-chip:hover {
  background: var(--qr-steel-soft);
  border-color: var(--qr-steel);
  color: var(--qr-steel-hi);
}

.qr-chip--active,
.qr-chip[aria-pressed="true"] {
  background: var(--qr-chip-active-bg);
  border-color: var(--qr-steel-hi);
  color: var(--qr-chip-active-ink);
}

.qr-chip:focus-visible {
  outline: 2px solid var(--qr-steel);
  outline-offset: 2px;
}

/* Override shared .button min-height for chips */
.qr-code-generator-page .qr-chip {
  min-height: 0;
}

/* ── Inline hint ── */
.qr-inline-hint {
  margin: 0;
  font-size: 0.8rem;
  color: #f59e0b;
  line-height: 1.4;
}

/* ── Preset buttons ── */
.qr-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.qr-presets .button {
  font-size: 0.85rem;
  padding-block: 0.4rem;
  min-height: 0;
}

/* Override shared .button-secondary min-height for compact preset buttons */
.qr-code-generator-page .qr-presets .button {
  min-height: 0;
}

/* ── QR specimen stage — a real alignment frame, not a glow ──
   Matte slate well that recesses the near-white specimen card. Four corner
   brackets (drawn on ::before) frame the QR like a scanner viewfinder /
   measurement jig. No blur, no neon halo, no gradient edge. */
.qr-preview-panel {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 240px;
  border-radius: 10px;
  padding: 1.6rem;
  background: var(--qr-deck);
  border: 1px solid var(--qr-border);
  /* Recessed instrument well — inner shadow only, downward, no colored glow. */
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

/* Corner brackets: four L-shaped marks via a repeating conic mask is fiddly —
   use a single inset box with steel borders only on the corners by layering
   four small gradients. Simpler + robust: an inset frame whose corners are
   emphasised with steel, edges faded. */
.qr-preview-panel::before {
  content: '';
  position: absolute;
  inset: 14px;
  border-radius: 4px;
  pointer-events: none;
  /* Four corner brackets, each ~22px, painted with linear-gradients so only
     the corners show steel — the middle of each edge stays transparent. */
  background:
    linear-gradient(var(--qr-steel), var(--qr-steel)) top left,
    linear-gradient(var(--qr-steel), var(--qr-steel)) top left,
    linear-gradient(var(--qr-steel), var(--qr-steel)) top right,
    linear-gradient(var(--qr-steel), var(--qr-steel)) top right,
    linear-gradient(var(--qr-steel), var(--qr-steel)) bottom left,
    linear-gradient(var(--qr-steel), var(--qr-steel)) bottom left,
    linear-gradient(var(--qr-steel), var(--qr-steel)) bottom right,
    linear-gradient(var(--qr-steel), var(--qr-steel)) bottom right;
  background-repeat: no-repeat;
  background-size:
    22px 2px, 2px 22px,   /* top-left: horizontal + vertical arm */
    22px 2px, 2px 22px,   /* top-right */
    22px 2px, 2px 22px,   /* bottom-left */
    22px 2px, 2px 22px;   /* bottom-right */
  opacity: 0.65;
}

/* ── Canvas — the mounted specimen ── */
.qr-canvas {
  display: block;
  border-radius: 4px;
  max-width: 100%;
  height: auto;
  /* Thin mount so the near-white QR sits like a card on the slate deck,
     not a raw bitmap bleeding into the well. */
  background: var(--qr-stage);
  padding: 6px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.qr-canvas:not([hidden]) {
  display: block;
}

/* Measured-reveal animation — fires on every new generation */
@keyframes qr-reveal {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

.qr-canvas.qr-reveal {
  animation: qr-reveal 0.20s ease-out both;
}

/* ── Placeholder ── */
.qr-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  width: 200px;
  height: 200px;
}

.qr-placeholder__grid {
  width: 120px;
  height: 120px;
  opacity: 0.28;
  /* Empty module matrix — neutral steel lines, no neon. */
  background-image:
    repeating-linear-gradient(0deg, var(--qr-steel-line) 0px, var(--qr-steel-line) 7px, transparent 7px, transparent 16px),
    repeating-linear-gradient(90deg, var(--qr-steel-line) 0px, var(--qr-steel-line) 7px, transparent 7px, transparent 16px);
  border-radius: 4px;
}

.qr-placeholder__hint {
  margin: 0;
  font-size: 0.82rem;
  color: var(--qr-ink-muted);
  text-align: center;
  max-width: 18ch;
  line-height: 1.45;
}

/* Over-capacity error panel — replaces the placeholder when QR library
   refuses the input (data too long). Persistent (not a 1.5s toast) so
   the user can read the actionable hint. */
.qr-error {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.1rem 1.2rem;
  margin: auto;
  max-width: 32ch;
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 14px;
  background: rgba(248, 113, 113, 0.08);
  color: #fecaca;
  text-align: left;
}
.qr-error[hidden] { display: none; }
.qr-error__title {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: #fecaca;
  letter-spacing: 0.02em;
}
.qr-error__body {
  margin: 0;
  font-size: 0.84rem;
  line-height: 1.5;
  color: rgba(254, 202, 202, 0.85);
}
.qr-error .mono {
  font-family: var(--qr-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
  color: #fecaca;
  font-weight: 600;
}

/* ── Module density chip ── */
.qr-density-chip {
  margin: 0;
  padding: 0.28rem 0.75rem;
  border: 1px solid var(--qr-steel-line);
  border-radius: 6px;
  font-size: 0.78rem;
  font-family: var(--font-mono, monospace);
  color: var(--qr-steel-hi);
  background: var(--qr-steel-soft);
  text-align: center;
  letter-spacing: 0.04em;
  align-self: center;
}

.qr-density-chip:not([hidden]) {
  display: block;
}

/* ── Action buttons ── */
.qr-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.qr-actions .button {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: 0;
}

.qr-btn-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

/* Recolor the primary action to the tool's steel accent — the shared brand
   blue (#38a9ff) is a bright cool blue that fights the muted slate palette and
   reads as a generic CTA. Steel keeps the whole bench cohesive. */
.qr-code-generator-page .button-primary {
  background: var(--qr-steel);
  border-color: var(--qr-steel);
  color: #0a1014;
}
.qr-code-generator-page .button-primary:hover {
  background: var(--qr-steel-hi);
  border-color: var(--qr-steel-hi);
}

/* ── Focus-visible overrides (scoped to .qr-code-generator-page per spec) ── */
.qr-code-generator-page .button-primary:focus-visible {
  outline: 2px solid var(--qr-steel-hi);
  outline-offset: 3px;
}

.qr-code-generator-page .button-secondary:focus-visible {
  outline: 2px solid var(--qr-steel);
  outline-offset: 3px;
}

/* ── Feedback slot ── */
.qr-feedback-slot {
  margin: 0;
  min-height: 1.2em;
  font-size: 0.85rem;
  color: var(--qr-ink-soft);
  text-align: center;
  transition: opacity 0.2s;
}

.qr-feedback-slot[data-tone="success"] { color: #34d399; }
.qr-feedback-slot[data-tone="warn"]    { color: #f59e0b; }
.qr-feedback-slot[data-tone="error"]   { color: #f87171; }

/* ── Trademark / attribution footnote ── */
.qr-code-generator-page .qr-trademark-note {
  font-size: 0.8rem;
  color: var(--qr-ink-muted);
  border-top: 1px solid var(--qr-border);
  padding-top: 0.85rem;
  margin-top: 0.4rem;
}

/* ── Tool discovery — prevent long strings blowing out cards ── */
.qr-code-generator-page .tool-discovery__faq-a,
.qr-code-generator-page .tool-discovery__card .card-text {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* ── Responsive ── */
@media (max-width: 720px) {
  .qr-bench {
    grid-template-columns: 1fr;
  }

  .qr-col--preview {
    width: 100%;
  }

  .qr-preview-panel {
    min-height: 220px;
  }

  .qr-code-generator-page .page-title {
    font-size: 2.1rem;
  }

  .qr-code-generator-page .page-subtitle {
    font-size: 0.97rem;
  }

  .qr-control-label {
    min-width: 4rem;
  }

  /* Match the desktop overrides' specificity (.qr-code-generator-page prefix)
     so the mobile 44px tap target wins over the desktop `min-height: 0`
     compact rule at the same media level — otherwise mobile inherits the
     desktop 28-29px chip / 37px preset height and fails WCAG 2.5.5 AAA. */
  .qr-code-generator-page .qr-chip {
    padding: 0.35rem 0.6rem;
    min-width: 44px;
    min-height: 44px;
  }

  .qr-code-generator-page .qr-presets .button {
    min-height: 44px;
  }
}

@media (max-width: 480px) {
  .qr-control-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
  }

  .qr-control-label {
    min-width: auto;
  }
}
